| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- <?php
- namespace App\Models;
- use App\Models\Scopes\YearScope;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Database\Eloquent\Relations\BelongsTo;
- use Illuminate\Database\Eloquent\Relations\HasOne;
- /**
- * Резерв запчасти под рекламацию.
- *
- * Резерв уменьшает свободный остаток, но НЕ физический.
- * Физический остаток уменьшается только при списании (issue).
- *
- * Жизненный цикл:
- * 1. active - создан при добавлении запчасти в рекламацию
- * 2. issued - запчасть списана (отгружена)
- * 3. cancelled - резерв отменён (запчасть удалена из рекламации)
- */
- class Reservation extends Model
- {
- const STATUS_ACTIVE = 'active';
- const STATUS_ISSUED = 'issued';
- const STATUS_CANCELLED = 'cancelled';
- const STATUS_NAMES = [
- self::STATUS_ACTIVE => 'Активен',
- self::STATUS_ISSUED => 'Списано',
- self::STATUS_CANCELLED => 'Отменён',
- ];
- protected $fillable = [
- 'spare_part_id',
- 'spare_part_order_id',
- 'reclamation_id',
- 'reserved_qty',
- 'with_documents',
- 'status',
- 'movement_id',
- ];
- protected $casts = [
- 'reserved_qty' => 'integer',
- 'with_documents' => 'boolean',
- ];
- // Отношения
- public function sparePart(): BelongsTo
- {
- return $this->belongsTo(SparePart::class);
- }
- public function sparePartOrder(): BelongsTo
- {
- return $this->belongsTo(SparePartOrder::class)->withoutGlobalScope(YearScope::class);
- }
- public function reclamation(): BelongsTo
- {
- return $this->belongsTo(Reclamation::class);
- }
- public function movement(): BelongsTo
- {
- return $this->belongsTo(InventoryMovement::class, 'movement_id');
- }
- // Аксессоры
- public function getStatusNameAttribute(): string
- {
- return self::STATUS_NAMES[$this->status] ?? $this->status;
- }
- public function isActive(): bool
- {
- return $this->status === self::STATUS_ACTIVE;
- }
- public function isIssued(): bool
- {
- return $this->status === self::STATUS_ISSUED;
- }
- public function isCancelled(): bool
- {
- return $this->status === self::STATUS_CANCELLED;
- }
- // Scopes
- public function scopeActive($query)
- {
- return $query->where('status', self::STATUS_ACTIVE);
- }
- public function scopeForReclamation($query, int $reclamationId)
- {
- return $query->where('reclamation_id', $reclamationId);
- }
- public function scopeForSparePart($query, int $sparePartId)
- {
- return $query->where('spare_part_id', $sparePartId);
- }
- public function scopeWithDocuments($query, bool $withDocs = true)
- {
- return $query->where('with_documents', $withDocs);
- }
- public function scopeFromOrder($query, int $orderId)
- {
- return $query->where('spare_part_order_id', $orderId);
- }
- }
|