'Trimis', 'in_progress' => 'În lucru', 'done' => 'Gata', 'returned' => 'Returnat', 'cancelled' => 'Anulat', ]; protected $fillable = [ 'company_id', 'work_order_id', 'subcontractor_id', 'number', 'category', 'description', 'cost', 'markup_pct', 'client_price', 'status', 'sent_at', 'eta', 'returned_at', 'paid_to_sub', 'notes', ]; protected $casts = [ 'cost' => 'decimal:2', 'markup_pct' => 'decimal:2', 'client_price' => 'decimal:2', 'sent_at' => 'date', 'eta' => 'date', 'returned_at' => 'date', 'paid_to_sub' => 'boolean', ]; public function workOrder(): BelongsTo { return $this->belongsTo(WorkOrder::class); } public function subcontractor(): BelongsTo { return $this->belongsTo(Subcontractor::class); } /** Our margin = what we bill the client − what the sub charges us. */ public function margin(): float { return round((float) $this->client_price - (float) $this->cost, 2); } public static function generateNumber(int $companyId): string { $year = date('y'); $count = static::withoutGlobalScopes() ->where('company_id', $companyId) ->whereYear('created_at', date('Y')) ->count(); return sprintf('SC-%s-%04d', $year, $count + 1); } protected static function booted(): void { static::creating(function (self $job) { if (empty($job->number)) { $job->number = static::generateNumber( $job->company_id ?: app(\App\Tenancy\TenantManager::class)->currentId() ); } }); static::saving(function (self $job) { // markup drives client_price unless markup is zero (then keep manual price). if ((float) $job->markup_pct > 0) { $job->client_price = round((float) $job->cost * (1 + (float) $job->markup_pct / 100), 2); } }); static::saved(fn (self $job) => $job->workOrder?->recalcTotal()); static::deleted(fn (self $job) => $job->workOrder?->recalcTotal()); } }