DeploymentStatus::class, 'quantity' => 'decimal:2', 'dispatched_at' => 'datetime', 'delivered_at' => 'datetime', 'consumed_at' => 'datetime', ]; } public function project(): BelongsTo { return $this->belongsTo(Project::class); } public function material(): BelongsTo { return $this->belongsTo(Material::class); } public function requisition(): BelongsTo { return $this->belongsTo(MaterialRequisition::class, 'material_requisition_id'); } public function requester(): BelongsTo { return $this->belongsTo(User::class, 'requested_by'); } public function transitionTo(DeploymentStatus $newStatus): void { $allowed = $this->status->allowedTransitions(); if (!in_array($newStatus, $allowed)) { throw new \InvalidArgumentException( "Cannot transition deployment from {$this->status->label()} to {$newStatus->label()}" ); } $updates = ['status' => $newStatus]; match ($newStatus) { DeploymentStatus::InTransit => $updates['dispatched_at'] = now(), DeploymentStatus::Delivered => $updates['delivered_at'] = now(), DeploymentStatus::Consumed => $updates['consumed_at'] = now(), default => null, }; $this->update($updates); } }