|null $comparison_policy * @property Collection $steps * @property Collection $items */ class Requisition extends Model { use BelongsToTenant; use HasWorkContext; protected $guarded = ['id']; protected function casts(): array { return ['approval_snapshot' => 'array', 'comparison_policy' => 'array', 'submitted_at' => 'datetime', 'needed_by' => 'date:Y-m-d']; } /** @return HasMany */ public function items(): HasMany { return $this->hasMany(RequisitionItem::class); } /** @return HasMany */ public function steps(): HasMany { return $this->hasMany(ApprovalStep::class)->orderBy('position'); } /** @return BelongsTo */ public function requester(): BelongsTo { return $this->belongsTo(User::class, 'requester_id'); } /** @return BelongsTo */ public function department(): BelongsTo { return $this->belongsTo(Department::class); } /** @return BelongsTo */ public function costCenter(): BelongsTo { return $this->belongsTo(CostCenter::class); } /** @param Builder $query */ public function scopeVisibleTo(Builder $query, User $user): void { if ($user->departmentScoped()) { $query->where('department_id', $user->department_id); } elseif (! $user->hasFunctions([PurchasingRole::Admin, PurchasingRole::Procurement, PurchasingRole::Finance])) { $query->where('requester_id', $user->id); } } public function canDecide(User $user): bool { if ($this->tenant_id !== $user->tenant_id) { return false; } $next = InternalRequisitions::nextStep(['status' => $this->status, 'requester_id' => $this->requester_id, 'steps' => $this->steps->toArray()], $user->id); return $next !== null && $user->hasFunctions([$next['role']]) && ($next['role'] !== 'department_head' || $this->department_id === $user->department_id) && ! app(ConflictGuard::class)->participationBlocked($user, $this); } }