*/
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);
}
}