Completed
Push — develop ( f7640a...3c81d1 )
by Abdelrahman
01:12
created

Booking::scopeByUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Rinvex\Bookings\Models;
6
7
use Carbon\Carbon;
8
use Illuminate\Database\Eloquent\Model;
9
use Rinvex\Cacheable\CacheableEloquent;
10
use Illuminate\Database\Eloquent\Builder;
11
use Rinvex\Support\Traits\ValidatingTrait;
12
use Rinvex\Bookings\Contracts\BookingContract;
13
use Illuminate\Database\Eloquent\Relations\MorphTo;
14
use Illuminate\Database\Eloquent\Relations\BelongsTo;
15
16
/**
17
 * Rinvex\Bookings\Models\Booking.
18
 *
19
 * @property int                                                $id
20
 * @property int                                                $bookable_id
21
 * @property string                                             $bookable_type
22
 * @property int                                                $user_id
23
 * @property \Carbon\Carbon                                     $starts_at
24
 * @property \Carbon\Carbon                                     $ends_at
25
 * @property float                                              $price
26
 * @property array                                              $price_equation
27
 * @property \Carbon\Carbon                                     $cancelled_at
28
 * @property string                                             $notes
29
 * @property \Carbon\Carbon                                     $created_at
30
 * @property \Carbon\Carbon                                     $updated_at
31
 * @property-read \Illuminate\Database\Eloquent\Model|\Eloquent $user
32
 * @property-read \Illuminate\Database\Eloquent\Model|\Eloquent $bookable
33
 *
34
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking bookingsOf($bookable)
35
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking byUser($user)
36
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking cancelled()
37
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking cancelledAfter($date)
38
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking cancelledBefore($date)
39
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking cancelledBetween($starts, $ends)
40
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking current()
41
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking endsAfter($date)
42
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking endsBefore($date)
43
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking endsBetween($starts, $ends)
44
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking future()
45
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking past()
46
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking startsAfter($date)
47
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking startsBefore($date)
48
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking startsBetween($starts, $ends)
49
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereUserId($value)
50
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereBookableId($value)
51
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereBookableType($value)
52
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereCancelledAt($value)
53
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereCreatedAt($value)
54
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereEndsAt($value)
55
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereId($value)
56
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereNotes($value)
57
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking wherePrice($value)
58
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking wherePriceEquation($value)
59
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereStartsAt($value)
60
 * @method static \Illuminate\Database\Eloquent\Builder|\Rinvex\Bookings\Models\Booking whereUpdatedAt($value)
61
 * @mixin \Eloquent
62
 */
63
class Booking extends Model implements BookingContract
64
{
65
    use ValidatingTrait;
66
    use CacheableEloquent;
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    protected $fillable = [
72
        'bookable_id',
73
        'bookable_type',
74
        'user_id',
75
        'starts_at',
76
        'ends_at',
77
        'price',
78
        'price_equation',
79
        'cancelled_at',
80
        'notes',
81
    ];
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    protected $casts = [
87
        'bookable_id' => 'integer',
88
        'bookable_type' => 'string',
89
        'user_id' => 'integer',
90
        'starts_at' => 'datetime',
91
        'ends_at' => 'datetime',
92
        'price' => 'float',
93
        'price_equation' => 'json',
94
        'cancelled_at' => 'datetime',
95
        'notes' => 'string',
96
    ];
97
98
    /**
99
     * {@inheritdoc}
100
     */
101
    protected $observables = [
102
        'validating',
103
        'validated',
104
    ];
105
106
    /**
107
     * The default rules that the model will validate against.
108
     *
109
     * @var array
110
     */
111
    protected $rules = [];
112
113
    /**
114
     * Whether the model should throw a
115
     * ValidationException if it fails validation.
116
     *
117
     * @var bool
118
     */
119
    protected $throwValidationExceptions = true;
120
121
    /**
122
     * Create a new Eloquent model instance.
123
     *
124
     * @param array $attributes
125
     */
126
    public function __construct(array $attributes = [])
127
    {
128
        parent::__construct($attributes);
129
130
        // Get users model
131
        $userModel = config('auth.providers.'.config('auth.guards.'.config('auth.defaults.guard').'.provider').'.model');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 121 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
132
133
        $this->setTable(config('rinvex.bookings.tables.bookings'));
134
        $this->setRules([
135
            'bookable_id' => 'required|integer',
136
            'bookable_type' => 'required|string',
137
            'user_id' => 'required|integer|exists:'.(new $userModel())->getTable().',id',
138
            'starts_at' => 'nullable|date',
139
            'ends_at' => 'nullable|date',
140
            'price' => 'required|numeric',
141
            'price_equation' => 'json',
142
            'cancelled_at' => 'nullable|date',
143
            'notes' => 'nullable|string|max:10000',
144
        ]);
145
    }
146
147
    /**
148
     * Get the owning model.
149
     *
150
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
151
     */
152
    public function bookable(): MorphTo
153
    {
154
        return $this->morphTo();
155
    }
156
157
    /**
158
     * Get the past bookings.
159
     *
160
     * @param \Illuminate\Database\Eloquent\Builder $builder
161
     *
162
     * @return \Illuminate\Database\Eloquent\Builder
163
     */
164
    public function scopePast(Builder $builder): Builder
165
    {
166
        return $builder->whereNull('cancelled_at')
167
                       ->whereNotNull('ends_at')
168
                       ->where('ends_at', '<', Carbon::now());
169
    }
170
171
    /**
172
     * Get the future bookings.
173
     *
174
     * @param \Illuminate\Database\Eloquent\Builder $builder
175
     *
176
     * @return \Illuminate\Database\Eloquent\Builder
177
     */
178
    public function scopeFuture(Builder $builder): Builder
179
    {
180
        return $builder->whereNull('cancelled_at')
181
                       ->whereNotNull('starts_at')
182
                       ->where('starts_at', '>', Carbon::now());
183
    }
184
185
    /**
186
     * Get the current bookings.
187
     *
188
     * @param \Illuminate\Database\Eloquent\Builder $builder
189
     *
190
     * @return \Illuminate\Database\Eloquent\Builder
191
     */
192
    public function scopeCurrent(Builder $builder): Builder
193
    {
194
        return $builder->whereNull('cancelled_at')
195
                       ->whereNotNull('starts_at')
196
                       ->whereNotNull('ends_at')
197
                       ->where('starts_at', '<', Carbon::now())
198
                       ->where('ends_at', '>', Carbon::now());
199
    }
200
201
    /**
202
     * Get the cancelled bookings.
203
     *
204
     * @param \Illuminate\Database\Eloquent\Builder $builder
205
     *
206
     * @return \Illuminate\Database\Eloquent\Builder
207
     */
208
    public function scopeCancelled(Builder $builder): Builder
209
    {
210
        return $builder->whereNotNull('cancelled_at');
211
    }
212
213
    /**
214
     * Get bookings starts before the given date.
215
     *
216
     * @param \Illuminate\Database\Eloquent\Builder $builder
217
     * @param string                                $date
218
     *
219
     * @return \Illuminate\Database\Eloquent\Builder
220
     */
221
    public function scopeStartsBefore(Builder $builder, string $date): Builder
222
    {
223
        return $builder->whereNull('cancelled_at')
224
                       ->whereNotNull('starts_at')
225
                       ->where('starts_at', '<', new Carbon($date));
226
    }
227
228
    /**
229
     * Get bookings starts after the given date.
230
     *
231
     * @param \Illuminate\Database\Eloquent\Builder $builder
232
     * @param string                                $date
233
     *
234
     * @return \Illuminate\Database\Eloquent\Builder
235
     */
236
    public function scopeStartsAfter(Builder $builder, string $date): Builder
237
    {
238
        return $builder->whereNull('cancelled_at')
239
                       ->whereNotNull('starts_at')
240
                       ->where('starts_at', '>', new Carbon($date));
241
    }
242
243
    /**
244
     * Get bookings starts between the given dates.
245
     *
246
     * @param \Illuminate\Database\Eloquent\Builder $builder
247
     * @param string                                $starts
248
     * @param string                                $ends
249
     *
250
     * @return \Illuminate\Database\Eloquent\Builder
251
     */
252
    public function scopeStartsBetween(Builder $builder, string $starts, string $ends): Builder
253
    {
254
        return $builder->whereNull('cancelled_at')
255
                       ->whereNotNull('starts_at')
256
                       ->where('starts_at', '>', new Carbon($starts))
257
                       ->where('starts_at', '<', new Carbon($ends));
258
    }
259
260
    /**
261
     * Get bookings ends before the given date.
262
     *
263
     * @param \Illuminate\Database\Eloquent\Builder $builder
264
     * @param string                                $date
265
     *
266
     * @return \Illuminate\Database\Eloquent\Builder
267
     */
268
    public function scopeEndsBefore(Builder $builder, string $date): Builder
269
    {
270
        return $builder->whereNull('cancelled_at')
271
                       ->whereNotNull('ends_at')
272
                       ->where('ends_at', '<', new Carbon($date));
273
    }
274
275
    /**
276
     * Get bookings ends after the given date.
277
     *
278
     * @param \Illuminate\Database\Eloquent\Builder $builder
279
     * @param string                                $date
280
     *
281
     * @return \Illuminate\Database\Eloquent\Builder
282
     */
283
    public function scopeEndsAfter(Builder $builder, string $date): Builder
284
    {
285
        return $builder->whereNull('cancelled_at')
286
                       ->whereNotNull('ends_at')
287
                       ->where('ends_at', '>', new Carbon($date));
288
    }
289
290
    /**
291
     * Get bookings ends between the given date.
292
     *
293
     * @param \Illuminate\Database\Eloquent\Builder $builder
294
     * @param string                                $starts
295
     * @param string                                $ends
296
     *
297
     * @return \Illuminate\Database\Eloquent\Builder
298
     */
299
    public function scopeEndsBetween(Builder $builder, string $starts, string $ends): Builder
300
    {
301
        return $builder->whereNull('cancelled_at')
302
                       ->whereNotNull('ends_at')
303
                       ->where('ends_at', '>', new Carbon($starts))
304
                       ->where('ends_at', '<', new Carbon($ends));
305
    }
306
307
    /**
308
     * Get bookings cancelled before the given date.
309
     *
310
     * @param \Illuminate\Database\Eloquent\Builder $builder
311
     * @param string                                $date
312
     *
313
     * @return \Illuminate\Database\Eloquent\Builder
314
     */
315
    public function scopeCancelledBefore(Builder $builder, string $date): Builder
316
    {
317
        return $builder->whereNotNull('cancelled_at')
318
                       ->where('cancelled_at', '<', new Carbon($date));
319
    }
320
321
    /**
322
     * Get bookings cancelled after the given date.
323
     *
324
     * @param \Illuminate\Database\Eloquent\Builder $builder
325
     * @param string                                $date
326
     *
327
     * @return \Illuminate\Database\Eloquent\Builder
328
     */
329
    public function scopeCancelledAfter(Builder $builder, string $date): Builder
330
    {
331
        return $builder->whereNotNull('cancelled_at')
332
                       ->where('cancelled_at', '>', new Carbon($date));
333
    }
334
335
    /**
336
     * Get bookings cancelled between the given dates.
337
     *
338
     * @param \Illuminate\Database\Eloquent\Builder $builder
339
     * @param string                                $starts
340
     * @param string                                $ends
341
     *
342
     * @return \Illuminate\Database\Eloquent\Builder
343
     */
344
    public function scopeCancelledBetween(Builder $builder, string $starts, string $ends): Builder
345
    {
346
        return $builder->whereNotNull('cancelled_at')
347
                       ->where('cancelled_at', '>', new Carbon($starts))
348
                       ->where('cancelled_at', '<', new Carbon($ends));
349
    }
350
351
    /**
352
     * Get bookings by the given user.
353
     *
354
     * @param \Illuminate\Database\Eloquent\Builder $builder
355
     * @param \Illuminate\Database\Eloquent\Model   $user
356
     *
357
     * @return \Illuminate\Database\Eloquent\Builder
358
     */
359
    public function scopeByUser(Builder $builder, Model $user): Builder
360
    {
361
        return $builder->where('user_id', $user->getKey());
362
    }
363
364
    /**
365
     * Get bookings of the given model.
366
     *
367
     * @param \Illuminate\Database\Eloquent\Builder $builder
368
     * @param string                                $bookable
369
     *
370
     * @return \Illuminate\Database\Eloquent\Builder
371
     */
372
    public function scopeBookingsOf(Builder $builder, string $bookable): Builder
373
    {
374
        return $builder->where('bookable_type', $bookable);
375
    }
376
377
    /**
378
     * Get the booking user.
379
     *
380
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
381
     */
382
    public function user(): belongsTo
383
    {
384
        $userModel = config('auth.providers.'.config('auth.guards.'.config('auth.defaults.guard').'.provider').'.model');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 121 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
385
386
        return $this->belongsTo($userModel, 'user_id', 'id');
387
    }
388
389
    /**
390
     * Check if the booking is cancelled.
391
     *
392
     * @return bool
393
     */
394
    public function isCancelled(): bool
395
    {
396
        return (bool) $this->cancelled_at;
397
    }
398
399
    /**
400
     * Check if the booking is past.
401
     *
402
     * @return bool
403
     */
404
    public function isPast(): bool
405
    {
406
        return ! $this->isCancelled() && $this->ends_at->isPast();
407
    }
408
409
    /**
410
     * Check if the booking is future.
411
     *
412
     * @return bool
413
     */
414
    public function isFuture(): bool
415
    {
416
        return ! $this->isCancelled() && $this->starts_at->isFuture();
417
    }
418
419
    /**
420
     * Check if the booking is current.
421
     *
422
     * @return bool
423
     */
424
    public function isCurrent(): bool
425
    {
426
        return ! $this->isCancelled() && Carbon::now()->between($this->starts_at, $this->ends_at);
427
    }
428
}
429