170 lines
5.6 KiB
PHP
170 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace App\Traits\Restock;
|
|
|
|
use App\Models\Bottle;
|
|
use App\Models\Perfume;
|
|
use App\Models\Product;
|
|
use App\Models\Restock;
|
|
use App\Services\StockActivityLogService;
|
|
|
|
trait WithRestockStock
|
|
{
|
|
public function transferStockFromWarehouseToOutlet($warehouse, $outlet, $item): void
|
|
{
|
|
$quantity = $item->quantity;
|
|
|
|
switch ($item->restockable_type) {
|
|
case Perfume::class:
|
|
$relation = 'perfumes';
|
|
break;
|
|
case Product::class:
|
|
$relation = 'products';
|
|
break;
|
|
case Bottle::class:
|
|
$relation = 'bottles';
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
// Decrease warehouse stock
|
|
$warehouseItem = $warehouse->{$relation}()
|
|
->where("{$relation}.id", $item->restockable_id)
|
|
->lockForUpdate()
|
|
->withPivot('stock')
|
|
->first();
|
|
|
|
$warehousePreviousStock = 0;
|
|
|
|
if ($warehouseItem) {
|
|
$warehousePreviousStock = $warehouseItem->pivot->stock ?? 0;
|
|
}
|
|
|
|
if ($warehousePreviousStock < $quantity) {
|
|
throw new \Exception("Stok {$item->restockable->name} di gudang tidak mencukupi. Tersisa {$warehousePreviousStock}, diminta {$quantity}.");
|
|
}
|
|
|
|
$warehouseNewStock = $warehousePreviousStock - $quantity;
|
|
|
|
$warehouse->{$relation}()->updateExistingPivot($item->restockable_id, [
|
|
'stock' => $warehouseNewStock,
|
|
]);
|
|
|
|
// Increase outlet stock
|
|
$outletItem = $outlet->{$relation}()
|
|
->where("{$relation}.id", $item->restockable_id)
|
|
->lockForUpdate()
|
|
->withPivot('stock')
|
|
->first();
|
|
|
|
if ($outletItem) {
|
|
$outletPreviousStock = $outletItem->pivot->stock ?? 0;
|
|
$outlet->{$relation}()->updateExistingPivot($item->restockable_id, [
|
|
'stock' => $outletPreviousStock + $quantity,
|
|
]);
|
|
} else {
|
|
$outletPreviousStock = 0;
|
|
$outlet->{$relation}()->attach($item->restockable_id, [
|
|
'stock' => $quantity,
|
|
]);
|
|
}
|
|
$outletNewStock = $outletPreviousStock + $quantity;
|
|
|
|
$restock = $item->restock ?? Restock::find($item->restock_id);
|
|
|
|
if ($restock) {
|
|
StockActivityLogService::distribution(
|
|
restock: $restock,
|
|
product: $item->restockable,
|
|
quantity: $quantity,
|
|
warehousePreviousStock: $warehousePreviousStock,
|
|
warehouseNewStock: $warehouseNewStock,
|
|
outletPreviousStock: $outletPreviousStock,
|
|
outletNewStock: $outletNewStock
|
|
);
|
|
}
|
|
}
|
|
|
|
public function reverseStockTransfer($warehouse, $outlet, $item): void
|
|
{
|
|
$quantity = $item->quantity;
|
|
|
|
switch ($item->restockable_type) {
|
|
case Perfume::class:
|
|
$relation = 'perfumes';
|
|
break;
|
|
case Product::class:
|
|
$relation = 'products';
|
|
break;
|
|
case Bottle::class:
|
|
$relation = 'bottles';
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
// Return items to Warehouse
|
|
$warehousePivot = $warehouse->{$relation}()
|
|
->where("{$relation}.id", $item->restockable_id)
|
|
->first();
|
|
|
|
$currentWarehouseStock = $warehousePivot?->pivot?->stock ?? 0;
|
|
$newWarehouseStock = $currentWarehouseStock + $quantity;
|
|
|
|
if ($warehousePivot) {
|
|
$warehouse->{$relation}()->updateExistingPivot($item->restockable_id, [
|
|
'stock' => $newWarehouseStock,
|
|
]);
|
|
} else {
|
|
$warehouse->{$relation}()->attach($item->restockable_id, [
|
|
'stock' => $quantity,
|
|
]);
|
|
}
|
|
|
|
$restock = $item->restock ?? Restock::find($item->restock_id);
|
|
|
|
if ($restock) {
|
|
StockActivityLogService::logWarehouse(
|
|
logName: StockActivityLogService::LOG_DISTRIBUTION,
|
|
event: 'increase',
|
|
description: "Restock #{$restock->hash_id} Deleted: Returned {$quantity} stock to Warehouse.",
|
|
performedOn: $item->restockable,
|
|
warehouse: $warehouse,
|
|
quantityChange: $quantity,
|
|
previousStock: $currentWarehouseStock,
|
|
newStock: $newWarehouseStock,
|
|
extraProperties: ['restock_id' => $restock->id]
|
|
);
|
|
}
|
|
|
|
// Remove items from Outlet
|
|
$outletPivot = $outlet->{$relation}()
|
|
->where("{$relation}.id", $item->restockable_id)
|
|
->first();
|
|
|
|
$currentOutletStock = $outletPivot?->pivot?->stock ?? 0;
|
|
$newOutletStock = max(0, $currentOutletStock - $quantity);
|
|
|
|
if ($outletPivot) {
|
|
$outlet->{$relation}()->updateExistingPivot($item->restockable_id, [
|
|
'stock' => $newOutletStock,
|
|
]);
|
|
}
|
|
|
|
if ($restock) {
|
|
StockActivityLogService::logOutlet(
|
|
logName: StockActivityLogService::LOG_DISTRIBUTION,
|
|
event: 'decrease',
|
|
description: "Restock #{$restock->hash_id} Deleted: Removed {$quantity} stock from Outlet.",
|
|
performedOn: $item->restockable,
|
|
outlet: $outlet,
|
|
quantityChange: -1 * abs($quantity),
|
|
previousStock: $currentOutletStock,
|
|
newStock: $newOutletStock,
|
|
extraProperties: ['restock_id' => $restock->id]
|
|
);
|
|
}
|
|
}
|
|
}
|