belongsTo(Registry::class); } public function category(): BelongsTo { return $this->belongsTo(Category::class); } public function asset(): BelongsTo { return $this->belongsTo(Asset::class); } public function operations(): MorphToMany { return $this->objectsByGroup('operations'); } public function scopeByStates($query, $states) { $query->where(function($query) use($states) { collect($states)->each(function($state) use($query) { $query->orWhere(function($query) use($state) { $query->$state(); }); }); }); } public function scopeAwaiting($query) { $query->where('active_since', '>', now()); } public function scopeActive($query) { $query->where('active_since', '<=', now())->where(function($query) { $query->whereNull('active_till')->orWhere('active_till', '>', now()); })->notCancelled()->notSuspended(); } public function scopeExpired($query) { $query->where('active_till', '<=', now()); } public function scopeSuspended($query) { $query->where('suspended_since', '<=', now())->where(function($query) { $query->whereNull('suspended_till')->orWhere('suspended_till', '>', now()); })->notCancelled(); } public function scopeNotSuspended($query) { $query->where(function($query) { $query->whereNull('suspended_since')->orWhere('suspended_since', '>', now()); })->where(function($query) { $query->whereNull('suspended_till')->orWhere('suspended_till', '<', now()); }); } public function scopeCancelled($query) { $query->where('cancelled_at', '<=', now()); } public function scopeNotCancelled($query) { $query->where(function($query) { $query->whereNull('cancelled_at')->orWhere('cancelled_at', '>', now()); }); } public function getPropertiesAttribute(): ?Model { return ($type = $this->registry->parsedType['options']['properties'] ?? null) ? $this->getObject($type, 'properties') : null; } public function getStateAttribute(): ?array { $state = null; if ($this->active_since) { $state = ($this->active_since <= now()) ? EntryState::ACTIVE : EntryState::AWAITING; if ($this->active_till && ($this->active_till <= now())) $state = EntryState::EXPIRED; elseif ($this->cancelled_at && ($this->cancelled_at <= now())) $state = EntryState::CANCELLED; elseif ($this->suspended_since && ($this->suspended_since <= now()) && (!$this->suspended_till || ($this->suspended_till > now()))) $state = EntryState::SUSPENDED; } return $state ? ['name' => $state, 'title' => EntryState::TITLES[$state] ?? null] : null; } public function sortOperations() { $this->operations()->reorder()->applyOrders(['order-date' => 'desc'])->get()->each(function($operation, $ord) { $this->objects()->updateExistingPivot($operation, ['ord' => $ord]); if ($ord === 0) $this->update(['active_since' => $operation->value('active-since'), 'active_till' => $operation->value('active-till')]); }); } }