'date', 'expected_date' => 'date', 'received_date' => 'date', 'subtotal' => 'decimal:2', 'tax' => 'decimal:2', 'shipping' => 'decimal:2', 'total' => 'decimal:2', ]; const STATUS_DRAFT = 'draft'; const STATUS_PENDING = 'pending'; const STATUS_ORDERED = 'ordered'; const STATUS_PARTIAL = 'partial'; const STATUS_RECEIVED = 'received'; const STATUS_CANCELLED = 'cancelled'; public function supplier(): BelongsTo { return $this->belongsTo(Supplier::class); } public function items(): HasMany { return $this->hasMany(PurchaseOrderItem::class); } public function stockMovements(): HasMany { return $this->hasMany(StockMovement::class); } public function getStatusBadgeClassAttribute(): string { return match($this->status) { self::STATUS_DRAFT => 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300', self::STATUS_PENDING => 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300', self::STATUS_ORDERED => 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300', self::STATUS_PARTIAL => 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-300', self::STATUS_RECEIVED => 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300', self::STATUS_CANCELLED => 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300', default => 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300', }; } public function isEditable(): bool { return in_array($this->status, [self::STATUS_DRAFT, self::STATUS_PENDING]); } public function canBeReceived(): bool { return in_array($this->status, [self::STATUS_ORDERED, self::STATUS_PARTIAL]); } public function getItemsCountAttribute(): int { return $this->items()->count(); } public function getTotalAmountAttribute(): float { return $this->items()->sum(\DB::raw('quantity_ordered * unit_cost')); } }