Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
Shift
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
9 / 9
18
100.00% covered (success)
100.00%
1 / 1
 neededAngelTypes
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 schedule
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 shiftEntries
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 shiftType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 location
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createdBy
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 updatedBy
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isNightShift
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
9
 getNightShiftMultiplier
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Models\Shifts;
6
7use Carbon\Carbon;
8use Engelsystem\Models\BaseModel;
9use Engelsystem\Models\Location;
10use Engelsystem\Models\User\User;
11use Illuminate\Database\Eloquent\Collection;
12use Illuminate\Database\Eloquent\Factories\HasFactory;
13use Illuminate\Database\Eloquent\Relations\BelongsTo;
14use Illuminate\Database\Eloquent\Relations\HasMany;
15use Illuminate\Database\Eloquent\Relations\HasOneThrough;
16use Illuminate\Database\Query\Builder as QueryBuilder;
17
18/**
19 * @property int                               $id
20 * @property string                            $title
21 * @property string                            $description
22 * @property string                            $url
23 * @property Carbon                            $start
24 * @property Carbon                            $end
25 * @property int                               $shift_type_id
26 * @property int                               $location_id
27 * @property string|null                       $transaction_id
28 * @property int                               $created_by
29 * @property int|null                          $updated_by
30 * @property Carbon|null                       $created_at
31 * @property Carbon|null                       $updated_at
32 *
33 * @property-read Collection|NeededAngelType[] $neededAngelTypes
34 * @property-read Schedule                     $schedule
35 * @property-read Collection|ShiftEntry[]      $shiftEntries
36 * @property-read ShiftType                    $shiftType
37 * @property-read Location                     $location
38 * @property-read User                         $createdBy
39 * @property-read User|null                    $updatedBy
40 *
41 * @method static QueryBuilder|Shift[] whereId($value)
42 * @method static QueryBuilder|Shift[] whereTitle($value)
43 * @method static QueryBuilder|Shift[] whereDescription($value)
44 * @method static QueryBuilder|Shift[] whereUrl($value)
45 * @method static QueryBuilder|Shift[] whereStart($value)
46 * @method static QueryBuilder|Shift[] whereEnd($value)
47 * @method static QueryBuilder|Shift[] whereShiftTypeId($value)
48 * @method static QueryBuilder|Shift[] whereLocationId($value)
49 * @method static QueryBuilder|Shift[] whereTransactionId($value)
50 * @method static QueryBuilder|Shift[] whereCreatedBy($value)
51 * @method static QueryBuilder|Shift[] whereUpdatedBy($value)
52 * @method static QueryBuilder|Shift[] whereCreatedAt($value)
53 * @method static QueryBuilder|Shift[] whereUpdatedAt($value)
54 */
55class Shift extends BaseModel
56{
57    use HasFactory;
58
59    /** @var array<string, string|null> default attributes */
60    protected $attributes = [ // phpcs:ignore
61        'description'    => '',
62        'url'            => '',
63        'transaction_id' => null,
64        'updated_by'     => null,
65    ];
66
67    /** @var bool enable timestamps */
68    public $timestamps = true; // phpcs:ignore
69
70    /** @var array<string, string> */
71    protected $casts = [ // phpcs:ignore
72        'shift_type_id' => 'integer',
73        'location_id'   => 'integer',
74        'created_by'    => 'integer',
75        'updated_by'    => 'integer',
76        'start'         => 'datetime',
77        'end'           => 'datetime',
78    ];
79
80    /** @var array<string> Values that are mass assignable */
81    protected $fillable = [ // phpcs:ignore
82        'title',
83        'description',
84        'url',
85        'start',
86        'end',
87        'shift_type_id',
88        'location_id',
89        'transaction_id',
90        'created_by',
91        'updated_by',
92    ];
93
94    public function neededAngelTypes(): HasMany
95    {
96        return $this->hasMany(NeededAngelType::class);
97    }
98
99    public function schedule(): HasOneThrough
100    {
101        return $this->hasOneThrough(Schedule::class, ScheduleShift::class, null, 'id', null, 'schedule_id');
102    }
103
104    public function shiftEntries(): HasMany
105    {
106        return $this->hasMany(ShiftEntry::class);
107    }
108
109    public function shiftType(): BelongsTo
110    {
111        return $this->belongsTo(ShiftType::class);
112    }
113
114    public function location(): BelongsTo
115    {
116        return $this->belongsTo(Location::class);
117    }
118
119    public function createdBy(): BelongsTo
120    {
121        return $this->belongsTo(User::class, 'created_by');
122    }
123
124    public function updatedBy(): BelongsTo
125    {
126        return $this->belongsTo(User::class, 'updated_by');
127    }
128
129    /**
130     * Check if the shift is a night shift
131     */
132    public function isNightShift(): bool
133    {
134        $config = config('night_shifts');
135
136        /** @see User_get_shifts_sum_query to keep it in sync */
137        return $config['enabled'] && (
138                // Starts during night
139                $this->start->hour >= $config['start'] && $this->start->hour < $config['end']
140                // Ends during night
141                || (
142                    $this->end->hour > $config['start']
143                    || $this->end->hour == $config['start'] && $this->end->minute > 0
144                ) && $this->end->hour <= $config['end']
145                // Starts before and ends after night
146                || $this->start->hour <= $config['start'] && $this->end->hour >= $config['end']
147            );
148    }
149
150    /**
151     * Calculate the shifts night multiplier
152     */
153    public function getNightShiftMultiplier(): float
154    {
155        if (!$this->isNightShift()) {
156            return 1;
157        }
158
159        return config('night_shifts')['multiplier'];
160    }
161}