MovementType::class, 'quantity' => 'decimal:2', 'balance_after' => 'decimal:2', ]; } // --- Relationships --- public function material(): BelongsTo { return $this->belongsTo(Material::class); } public function inventoryBatch(): BelongsTo { return $this->belongsTo(InventoryBatch::class); } public function warehouse(): BelongsTo { return $this->belongsTo(Warehouse::class); } public function project(): BelongsTo { return $this->belongsTo(Project::class); } public function task(): BelongsTo { return $this->belongsTo(Task::class); } public function performer(): BelongsTo { return $this->belongsTo(User::class, 'performed_by'); } public function dispatcher(): BelongsTo { return $this->belongsTo(User::class, 'dispatched_by'); } public function receiver(): BelongsTo { return $this->belongsTo(User::class, 'received_by'); } public function returner(): BelongsTo { return $this->belongsTo(User::class, 'returned_by'); } public function adjuster(): BelongsTo { return $this->belongsTo(User::class, 'adjusted_by'); } public function reference(): MorphTo { return $this->morphTo(); } // --- Scopes --- public function scopeOfType($query, MovementType $type) { return $query->where('movement_type', $type); } public function scopeForMaterial($query, int $materialId) { return $query->where('material_id', $materialId); } public function scopeForWarehouse($query, int $warehouseId) { return $query->where('warehouse_id', $warehouseId); } public function scopeForProject($query, int $projectId) { return $query->where('project_id', $projectId); } public function scopeInDateRange($query, ?string $from, ?string $to) { if ($from) { $query->where('created_at', '>=', $from); } if ($to) { $query->where('created_at', '<=', $to . ' 23:59:59'); } return $query; } // --- Helpers --- public function getFromLabelAttribute(): string { return match ($this->from_location_type) { 'warehouse' => Warehouse::find($this->from_location_id)?->name ?? 'Warehouse', 'project' => Project::find($this->from_location_id)?->name ?? 'Project', 'task' => Task::find($this->from_location_id)?->name ?? 'Task', 'external' => 'External (Supplier)', default => '-', }; } public function getToLabelAttribute(): string { return match ($this->to_location_type) { 'warehouse' => Warehouse::find($this->to_location_id)?->name ?? 'Warehouse', 'project' => Project::find($this->to_location_id)?->name ?? 'Project', 'task' => Task::find($this->to_location_id)?->name ?? 'Task', 'external' => 'External', default => '-', }; } }