| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- <?php
- namespace App\Models;
- use App\Models\Scopes\YearScope;
- use Illuminate\Database\Eloquent\Attributes\ScopedBy;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Database\Eloquent\Relations\BelongsTo;
- use Illuminate\Database\Eloquent\Relations\HasMany;
- use Illuminate\Database\Eloquent\Relations\MorphTo;
- use Illuminate\Database\Eloquent\SoftDeletes;
- #[ScopedBy([YearScope::class])]
- class SparePartOrder extends Model
- {
- use SoftDeletes;
- const STATUS_ORDERED = 'ordered';
- const STATUS_IN_STOCK = 'in_stock';
- const STATUS_SHIPPED = 'shipped';
- const STATUS_NAMES = [
- self::STATUS_ORDERED => 'Заказано',
- self::STATUS_IN_STOCK => 'На складе',
- self::STATUS_SHIPPED => 'Отгружено',
- ];
- const DEFAULT_SORT_BY = 'created_at';
- protected $fillable = [
- 'year',
- 'spare_part_id',
- 'source_text',
- 'sourceable_id',
- 'sourceable_type',
- 'status',
- 'ordered_quantity',
- 'remaining_quantity',
- 'with_documents',
- 'note',
- 'user_id',
- ];
- protected $casts = [
- 'with_documents' => 'boolean',
- 'ordered_quantity' => 'integer',
- 'remaining_quantity' => 'integer',
- 'year' => 'integer',
- ];
- protected static function boot(): void
- {
- parent::boot();
- static::creating(function ($model) {
- if (!isset($model->year)) {
- $model->year = year();
- }
- if (!isset($model->remaining_quantity)) {
- $model->remaining_quantity = $model->ordered_quantity;
- }
- });
- // Автосмена статуса
- static::updating(function ($model) {
- if ($model->remaining_quantity === 0 && $model->status !== self::STATUS_SHIPPED) {
- $model->status = self::STATUS_SHIPPED;
- }
- });
- }
- // Отношения
- public function sparePart(): BelongsTo
- {
- return $this->belongsTo(SparePart::class);
- }
- public function user(): BelongsTo
- {
- return $this->belongsTo(User::class);
- }
- public function sourceable(): MorphTo
- {
- return $this->morphTo();
- }
- public function shipments(): HasMany
- {
- return $this->hasMany(SparePartOrderShipment::class);
- }
- // Scopes
- public function scopeInStock($query)
- {
- return $query->where('status', self::STATUS_IN_STOCK)
- ->where('remaining_quantity', '>', 0);
- }
- public function scopeWithDocuments($query, bool $withDocs = true)
- {
- return $query->where('with_documents', $withDocs);
- }
- // Метод списания
- public function shipQuantity(int $quantity, string $note, ?int $reclamationId = null, ?int $userId = null): bool
- {
- if ($quantity > $this->remaining_quantity) {
- return false;
- }
- // Уменьшаем остаток
- $this->remaining_quantity -= $quantity;
- $this->save();
- // Создаем запись в истории
- SparePartOrderShipment::create([
- 'spare_part_order_id' => $this->id,
- 'quantity' => $quantity,
- 'note' => $note,
- 'reclamation_id' => $reclamationId,
- 'user_id' => $userId ?? auth()->id(),
- 'is_automatic' => $reclamationId !== null,
- ]);
- return true;
- }
- // Получить имя статуса
- public function getStatusNameAttribute(): string
- {
- return self::STATUS_NAMES[$this->status] ?? $this->status;
- }
- }
|