'Nou', 'diagnosis' => 'Diagnosticare', 'agreement' => 'Aprobare client', 'approved' => 'Aprobat', 'in_work' => 'În lucru', 'awaiting_parts' => 'Așteaptă piese', 'ready' => 'Gata de ridicare', 'done' => 'Predat', 'cancelled' => 'Anulat', ]; public const PAY_STATUSES = [ 'unpaid' => 'Neplătit', 'partial' => 'Parțial', 'paid' => 'Plătit', ]; protected $fillable = [ 'company_id', 'number', 'client_id', 'vehicle_id', 'master_id', 'deal_id', 'appointment_id', 'opened_at', 'closed_at', 'mileage_in', 'mileage_out', 'complaint', 'diagnosis', 'recommendations', 'status', 'pay_status', 'approved', 'approved_at', 'discount_pct', 'total', ]; protected $casts = [ 'opened_at' => 'date', 'closed_at' => 'date', 'approved_at' => 'datetime', 'approved' => 'boolean', 'discount_pct' => 'decimal:2', 'total' => 'decimal:2', ]; public function client(): BelongsTo { return $this->belongsTo(Client::class); } public function vehicle(): BelongsTo { return $this->belongsTo(Vehicle::class); } public function master(): BelongsTo { return $this->belongsTo(User::class, 'master_id'); } public function works(): HasMany { return $this->hasMany(WorkOrderWork::class); } public function parts(): HasMany { return $this->hasMany(WorkOrderPart::class); } public function payments(): HasMany { return $this->hasMany(Payment::class); } public function paidAmount(): float { return (float) $this->payments()->sum('amount'); } public function balanceDue(): float { return max(0.0, (float) $this->total - $this->paidAmount()); } public function recalcTotal(): void { $worksTotal = $this->works()->sum('total'); $partsTotal = $this->parts()->sum('total'); $sub = (float) $worksTotal + (float) $partsTotal; $disc = (float) $this->discount_pct; $this->total = round($sub * (1 - $disc / 100), 2); $this->save(); } 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('WO-%s-%04d', $year, $count + 1); } }