ultimatepos/Modules/InventoryManagement/Services/WmsWaveService.php

66 lines
2.2 KiB
PHP

<?php
namespace Modules\InventoryManagement\Services;
use App\TransactionSellLine;
use Illuminate\Support\Facades\DB;
use Modules\InventoryManagement\Models\WmsWave;
use Modules\InventoryManagement\Models\WmsWaveLine;
class WmsWaveService
{
public function createWave(int $businessId, int $locationId, array $sellLineIds = []): WmsWave
{
return DB::transaction(function () use ($businessId, $locationId, $sellLineIds) {
$count = WmsWave::forBusiness($businessId)->count() + 1;
$wave = WmsWave::create([
'business_id' => $businessId,
'location_id' => $locationId,
'wave_no' => 'WAVE-'.str_pad((string) $count, 5, '0', STR_PAD_LEFT),
'status' => 'planned',
'pick_strategy' => 'wave',
]);
$lines = TransactionSellLine::query()
->whereIn('id', $sellLineIds)
->get();
foreach ($lines as $line) {
WmsWaveLine::create([
'wave_id' => $wave->id,
'variation_id' => $line->variation_id,
'product_id' => $line->product_id,
'quantity' => $line->quantity,
'sell_line_id' => $line->id,
'status' => 'pending',
]);
}
return $wave->load('lines');
});
}
public function releaseWave(WmsWave $wave): WmsWave
{
$wave->update(['status' => 'released', 'released_at' => now()]);
return $wave;
}
public function recordPick(WmsWaveLine $line, float $qty): WmsWaveLine
{
$line->picked_quantity = min($line->quantity, $line->picked_quantity + $qty);
$line->status = $line->picked_quantity >= $line->quantity ? 'picked' : 'pending';
$line->save();
$pending = WmsWaveLine::where('wave_id', $line->wave_id)->where('status', '!=', 'picked')->count();
if ($pending === 0) {
$line->wave->update(['status' => 'completed', 'completed_at' => now()]);
} elseif ($line->wave->status === 'released') {
$line->wave->update(['status' => 'picking']);
}
return $line;
}
}