PaymentStatus::class, 'approved_at' => 'datetime', 'paid_at' => 'datetime', ]; } public function isPaid(): bool { return $this->payment_status === PaymentStatus::Paid; } public function isApproved(): bool { return $this->status === 'approved'; } public function hasReceipt(): bool { return !empty($this->receipt_path); } public function targetWarehouse(): BelongsTo { return $this->belongsTo(Warehouse::class, 'target_warehouse_id'); } public function requester(): BelongsTo { return $this->belongsTo(User::class, 'requested_by'); } public function approver(): BelongsTo { return $this->belongsTo(User::class, 'approved_by'); } public function items(): HasMany { return $this->hasMany(PurchaseOrderItem::class); } public function requisitions(): BelongsToMany { return $this->belongsToMany(MaterialRequisition::class, 'purchase_order_requisitions') ->withTimestamps(); } public function getTotalCostAttribute(): float { return $this->items->sum(fn (PurchaseOrderItem $item) => $item->line_total); } public function scopeApproved($query) { return $query->where('status', 'approved'); } public function onApprovalCompleted($chain) { $this->update(['status' => $chain->status->value]); if ($chain->status->value === 'approved') { $lastStep = $chain->steps()->where('status', 'approved')->orderByDesc('acted_at')->first(); $this->update([ 'approved_by' => $lastStep ? $lastStep->approver_id : null, 'approved_at' => $lastStep ? $lastStep->acted_at : now(), ]); } elseif ($chain->status->value === 'rejected') { $this->requisitions()->detach(); } } }