*/ use HasFactory; use SoftDeletes; public const DEFAULT_SORT_BY = 'created_at'; public const DEFAULT_ORDER_BY = 'desc'; protected $fillable = [ 'external_id', 'source', 'order_number', 'order_year', 'customer_name', 'object_address', 'invoice_number', 'invoice_date', 'contract_number', 'contract_date', 'payment_date', 'supply_working_days', 'contract_shipment_date', 'application_shipment_date', 'status', 'execution_type', 'manager_id', 'note', 'created_by', 'updated_by', ]; protected function casts(): array { return [ 'source' => ProductionOrderSource::class, 'order_year' => 'integer', 'invoice_date' => 'immutable_date', 'contract_date' => 'immutable_date', 'payment_date' => 'immutable_date', 'supply_working_days' => 'integer', 'contract_shipment_date' => 'immutable_date', 'application_shipment_date' => 'immutable_date', 'status' => ProductionOrderStatus::class, 'execution_type' => ProductionOrderExecutionType::class, 'manager_id' => 'integer', 'created_by' => 'integer', 'updated_by' => 'integer', ]; } public function manager(): BelongsTo { return $this->belongsTo(User::class, 'manager_id'); } public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } public function updater(): BelongsTo { return $this->belongsTo(User::class, 'updated_by'); } public function items(): HasMany { return $this->hasMany(ProductionOrderItem::class)->orderBy('sort')->orderBy('id'); } public function deliveries(): HasMany { return $this->hasMany(ProductionOrderDelivery::class)->orderBy('delivery_date')->orderBy('id'); } public function installations(): HasMany { return $this->hasMany(ProductionOrderInstallation::class)->orderBy('installation_date')->orderBy('id'); } public function activities(): HasMany { return $this->hasMany(ProductionOrderActivity::class)->latest('created_at')->latest('id'); } public function reclamations(): HasMany { return $this->hasMany(Reclamation::class); } public function documents(): BelongsToMany { return $this->belongsToMany(File::class, 'production_order_document')->withTimestamps(); } public function photos(): BelongsToMany { return $this->belongsToMany(File::class, 'production_order_photo')->withTimestamps(); } public function chatMessages(): HasMany { return $this->hasMany(ChatMessage::class)->oldest('created_at')->oldest('id'); } public function statusLabel(): string { return $this->status->label(); } public function executionTypeLabel(): string { return $this->execution_type->label(); } public function getStatusNameAttribute(): string { return $this->statusLabel(); } public function getExecutionTypeNameAttribute(): string { return $this->executionTypeLabel(); } public function getDeliveryDatesAttribute(): string { return $this->deliveries ->pluck('delivery_date') ->filter() ->map(static fn ($date): string => $date->format('d.m.Y')) ->implode('
'); } public function getInstallationDatesAttribute(): string { return $this->installations ->pluck('installation_date') ->filter() ->map(static fn ($date): string => $date->format('d.m.Y')) ->implode('
'); } public function isShipmentOverdue(): bool { return $this->contract_shipment_date?->isPast() && ! in_array($this->status, [ProductionOrderStatus::InStock, ProductionOrderStatus::Closed], true); } }