154 lines
4.1 KiB
PHP
154 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace Modules\MaterialLogistics\Models;
|
|
use Modules\MasterData\Models\Material;
|
|
use Modules\MasterData\Models\MaterialGroup;
|
|
|
|
use App\Models\User;
|
|
use App\Traits\HasPublicIdentifier;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
|
use Modules\MaterialLogistics\Enums\MovementType;
|
|
use Modules\ProjectManagement\Models\Project;
|
|
use Modules\ProjectManagement\Models\Task;
|
|
|
|
class InventoryMovement extends Model
|
|
{
|
|
use HasPublicIdentifier;
|
|
|
|
protected $fillable = [
|
|
'material_id', 'warehouse_id', 'project_id', 'task_id', 'inventory_batch_id',
|
|
'movement_type', 'direction', 'quantity', 'balance_after',
|
|
'from_location_type', 'from_location_id',
|
|
'to_location_type', 'to_location_id',
|
|
'reference_type', 'reference_id',
|
|
'performed_by', 'notes',
|
|
'dispatched_by', 'received_by', 'returned_by', 'adjusted_by',
|
|
];
|
|
|
|
protected function casts(): array
|
|
{
|
|
return [
|
|
'movement_type' => 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 => '-',
|
|
};
|
|
}
|
|
}
|
|
|