170 lines
5.9 KiB
PHP
170 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace App\Traits\StockTransfer;
|
|
|
|
use App\Models\Bottle;
|
|
use App\Models\Perfume;
|
|
use App\Models\Product;
|
|
use App\Models\StockTransfer;
|
|
use App\Services\StockActivityLogService;
|
|
|
|
trait WithStockTransferStock
|
|
{
|
|
public function transferStockBetweenOutlets($sourceOutlet, $destinationOutlet, $item): void
|
|
{
|
|
$quantity = $item->quantity;
|
|
|
|
switch ($item->transferable_type) {
|
|
case Perfume::class:
|
|
$relation = 'perfumes';
|
|
break;
|
|
case Product::class:
|
|
$relation = 'products';
|
|
break;
|
|
case Bottle::class:
|
|
$relation = 'bottles';
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
// Decrease source outlet stock
|
|
$sourceItem = $sourceOutlet->{$relation}()
|
|
->where("{$relation}.id", $item->transferable_id)
|
|
->lockForUpdate()
|
|
->withPivot('stock')
|
|
->first();
|
|
|
|
$sourcePreviousStock = 0;
|
|
|
|
if ($sourceItem) {
|
|
$sourcePreviousStock = $sourceItem->pivot->stock ?? 0;
|
|
}
|
|
|
|
if ($sourcePreviousStock < $quantity) {
|
|
throw new \Exception("Stok {$item->transferable->name} di outlet asal tidak mencukupi. Tersisa {$sourcePreviousStock}, diminta {$quantity}.");
|
|
}
|
|
|
|
$sourceNewStock = $sourcePreviousStock - $quantity;
|
|
|
|
$sourceOutlet->{$relation}()->updateExistingPivot($item->transferable_id, [
|
|
'stock' => $sourceNewStock,
|
|
]);
|
|
|
|
// Increase destination outlet stock
|
|
$destinationItem = $destinationOutlet->{$relation}()
|
|
->where("{$relation}.id", $item->transferable_id)
|
|
->lockForUpdate()
|
|
->withPivot('stock')
|
|
->first();
|
|
|
|
if ($destinationItem) {
|
|
$destinationPreviousStock = $destinationItem->pivot->stock ?? 0;
|
|
$destinationOutlet->{$relation}()->updateExistingPivot($item->transferable_id, [
|
|
'stock' => $destinationPreviousStock + $quantity,
|
|
]);
|
|
} else {
|
|
$destinationPreviousStock = 0;
|
|
$destinationOutlet->{$relation}()->attach($item->transferable_id, [
|
|
'stock' => $quantity,
|
|
]);
|
|
}
|
|
$destinationNewStock = $destinationPreviousStock + $quantity;
|
|
|
|
$stockTransfer = $item->stockTransfer ?? StockTransfer::find($item->stock_transfer_id);
|
|
|
|
if ($stockTransfer) {
|
|
StockActivityLogService::transfer(
|
|
stockTransfer: $stockTransfer,
|
|
product: $item->transferable,
|
|
quantity: $quantity,
|
|
sourcePreviousStock: $sourcePreviousStock,
|
|
sourceNewStock: $sourceNewStock,
|
|
destinationPreviousStock: $destinationPreviousStock,
|
|
destinationNewStock: $destinationNewStock
|
|
);
|
|
}
|
|
}
|
|
|
|
public function reverseStockTransferBetweenOutlets($sourceOutlet, $destinationOutlet, $item): void
|
|
{
|
|
$quantity = $item->quantity;
|
|
|
|
switch ($item->transferable_type) {
|
|
case Perfume::class:
|
|
$relation = 'perfumes';
|
|
break;
|
|
case Product::class:
|
|
$relation = 'products';
|
|
break;
|
|
case Bottle::class:
|
|
$relation = 'bottles';
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
// Return items to source outlet
|
|
$sourcePivot = $sourceOutlet->{$relation}()
|
|
->where("{$relation}.id", $item->transferable_id)
|
|
->first();
|
|
|
|
$currentSourceStock = $sourcePivot?->pivot?->stock ?? 0;
|
|
$newSourceStock = $currentSourceStock + $quantity;
|
|
|
|
if ($sourcePivot) {
|
|
$sourceOutlet->{$relation}()->updateExistingPivot($item->transferable_id, [
|
|
'stock' => $newSourceStock,
|
|
]);
|
|
} else {
|
|
$sourceOutlet->{$relation}()->attach($item->transferable_id, [
|
|
'stock' => $quantity,
|
|
]);
|
|
}
|
|
|
|
$stockTransfer = $item->stockTransfer ?? StockTransfer::find($item->stock_transfer_id);
|
|
|
|
if ($stockTransfer) {
|
|
StockActivityLogService::logOutlet(
|
|
logName: StockActivityLogService::LOG_TRANSFER,
|
|
event: 'increase',
|
|
description: "Transfer Stok #{$stockTransfer->hash_id} Dihapus: Mengembalikan {$quantity} stok ke outlet asal.",
|
|
performedOn: $item->transferable,
|
|
outlet: $sourceOutlet,
|
|
quantityChange: $quantity,
|
|
previousStock: $currentSourceStock,
|
|
newStock: $newSourceStock,
|
|
extraProperties: ['stock_transfer_id' => $stockTransfer->id]
|
|
);
|
|
}
|
|
|
|
// Remove items from destination outlet
|
|
$destinationPivot = $destinationOutlet->{$relation}()
|
|
->where("{$relation}.id", $item->transferable_id)
|
|
->first();
|
|
|
|
$currentDestinationStock = $destinationPivot?->pivot?->stock ?? 0;
|
|
$newDestinationStock = max(0, $currentDestinationStock - $quantity);
|
|
|
|
if ($destinationPivot) {
|
|
$destinationOutlet->{$relation}()->updateExistingPivot($item->transferable_id, [
|
|
'stock' => $newDestinationStock,
|
|
]);
|
|
}
|
|
|
|
if ($stockTransfer) {
|
|
StockActivityLogService::logOutlet(
|
|
logName: StockActivityLogService::LOG_TRANSFER,
|
|
event: 'decrease',
|
|
description: "Transfer Stok #{$stockTransfer->hash_id} Dihapus: Menghapus {$quantity} stok dari outlet tujuan.",
|
|
performedOn: $item->transferable,
|
|
outlet: $destinationOutlet,
|
|
quantityChange: -1 * abs($quantity),
|
|
previousStock: $currentDestinationStock,
|
|
newStock: $newDestinationStock,
|
|
extraProperties: ['stock_transfer_id' => $stockTransfer->id]
|
|
);
|
|
}
|
|
}
|
|
}
|