43 lines
2.6 KiB
PHP
43 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\StockItem;
|
|
use App\Models\Warehouse;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
class WarehouseAvailability
|
|
{
|
|
/** @return array<string,mixed> */
|
|
public function row(StockItem $item, Warehouse $warehouse, bool $planning): array
|
|
{
|
|
abort_unless($item->tenant_id === $warehouse->tenant_id && auth()->user()?->tenant_id === $item->tenant_id, 404);
|
|
$physical = app(StockWorkflow::class)->balance($item->id, $warehouse->id);
|
|
$lots = app(InventoryLots::class)->context($item->id, $warehouse->id);
|
|
$usable = $lots === null ? $physical['quantity'] : ($lots['reconciled'] ? $lots['usable_milli'] : null);
|
|
$needs = null;
|
|
$minimum = null;
|
|
if ($planning && Schema::hasTable('supply_records')) {
|
|
$needs = 0;
|
|
foreach (app(SupplyPlanning::class)->latest('reservation')->where('stock_item_id', $item->id)->where('warehouse_id', $warehouse->id)->whereIn('state', ['active', 'fulfilled'])->get() as $need) {
|
|
if (($need->snapshot['item']['unit'] ?? null) !== $item->unit) {
|
|
$needs = null;
|
|
break;
|
|
}
|
|
$needs += app(SupplyCoordination::class)->remainingReservation($need);
|
|
}
|
|
$policy = app(SupplyPlanning::class)->latest('policy')->where('stock_item_id', $item->id)->where('warehouse_id', $warehouse->id)->where('state', 'approved')->first();
|
|
if ($policy !== null && $policy->snapshot['item'] === $item->only(['id', 'code', 'name', 'unit'])) {
|
|
$minimum = $policy->data['minimum_stock_milli'] ?? null;
|
|
}
|
|
}
|
|
|
|
return ['id' => $item->id, 'code' => $item->code, 'name' => $item->name, 'unit' => $item->unit,
|
|
'physical_milli' => $physical['quantity'], 'usable_milli' => $usable, 'blocked_milli' => $lots === null || ! $lots['reconciled'] ? null : $lots['blocked_milli'],
|
|
'lot_control' => $lots !== null, 'reconciled' => $lots === null || $lots['reconciled'], 'planned_milli' => $needs,
|
|
'minimum_milli' => $minimum, 'at_minimum' => $usable !== null && $minimum !== null && $usable - app(WarehouseReservations::class)->committed($item->id, $warehouse->id) <= $minimum,
|
|
'physical_commitment_milli' => app(WarehouseReservations::class)->ready() ? app(WarehouseReservations::class)->committed($item->id, $warehouse->id) : null,
|
|
'free_milli' => $usable === null ? null : $usable - app(WarehouseReservations::class)->committed($item->id, $warehouse->id), 'ledger_version' => $physical['version']];
|
|
}
|
|
}
|