137 lines
4.4 KiB
PHP
137 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Traits\Order;
|
|
|
|
use App\Models\Bottle;
|
|
use App\Models\Perfume;
|
|
use App\Models\Product;
|
|
use App\Services\StockActivityLogService;
|
|
|
|
trait WithUpdateStock
|
|
{
|
|
public function increaseOutletStock($outlet, $item): void
|
|
{
|
|
$quantity = $item->quantity;
|
|
|
|
switch ($item->orderable_type) {
|
|
case Perfume::class:
|
|
$relation = 'perfumes';
|
|
break;
|
|
case Product::class:
|
|
$relation = 'products';
|
|
break;
|
|
case Bottle::class:
|
|
$relation = 'bottles';
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
$existing = $outlet->{$relation}()
|
|
->withPivot('stock')
|
|
->where("{$relation}.id", $item->orderable_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
if ($existing) {
|
|
$currentStock = $existing->pivot->stock ?? 0;
|
|
$outlet->{$relation}()->updateExistingPivot($item->orderable_id, [
|
|
'stock' => $currentStock + $quantity,
|
|
]);
|
|
} else {
|
|
$currentStock = 0;
|
|
$outlet->{$relation}()->attach($item->orderable_id, [
|
|
'stock' => $quantity,
|
|
]);
|
|
}
|
|
$newStock = $currentStock + $quantity;
|
|
|
|
StockActivityLogService::logOutlet(
|
|
logName: StockActivityLogService::LOG_SALE,
|
|
event: 'increase',
|
|
description: 'Stok '.$item->orderable->name.' di '.$outlet->name.' bertambah '.formatCurrencyNumber($quantity).' (Pembatalan/Edit Order)',
|
|
performedOn: $item->orderable,
|
|
outlet: $outlet,
|
|
quantityChange: abs($quantity),
|
|
previousStock: $currentStock,
|
|
newStock: $newStock,
|
|
extraProperties: [
|
|
'orderable_id' => $item->orderable_id,
|
|
'orderable_type' => $item->orderable_type,
|
|
'order_id' => $item->order_id ?? null,
|
|
]
|
|
);
|
|
}
|
|
|
|
public function decreaseOutletStock($outlet, $item)
|
|
{
|
|
$quantity = $item->quantity;
|
|
|
|
switch ($item->orderable_type) {
|
|
case Perfume::class:
|
|
$relation = 'perfumes';
|
|
break;
|
|
case Product::class:
|
|
$relation = 'products';
|
|
break;
|
|
case Bottle::class:
|
|
$relation = 'bottles';
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
$existing = $outlet->{$relation}()
|
|
->withPivot('stock')
|
|
->where("{$relation}.id", $item->orderable_id)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
if (! $existing) {
|
|
return ['status' => false, 'message' => "Produk {$item->orderable->name} tidak ditemukan di {$outlet->name}."];
|
|
}
|
|
|
|
$currentStock = $existing->pivot->stock ?? 0;
|
|
|
|
if ($currentStock < $quantity) {
|
|
return ['status' => false, 'message' => "Stok produk {$item->orderable->name} tidak mencukupi. Tersisa {$currentStock}, diminta {$quantity}. Silakan hubungi Administrator."];
|
|
}
|
|
|
|
$newStock = $currentStock - $quantity;
|
|
|
|
$outlet->{$relation}()->updateExistingPivot($item->orderable_id, [
|
|
'stock' => $newStock,
|
|
]);
|
|
|
|
$order = $item->order ?? \App\Models\Order::find($item->order_id);
|
|
|
|
if ($order) {
|
|
StockActivityLogService::sale(
|
|
order: $order,
|
|
product: $item->orderable,
|
|
quantity: $quantity,
|
|
previousStock: $currentStock,
|
|
newStock: $newStock
|
|
);
|
|
} else {
|
|
StockActivityLogService::logOutlet(
|
|
logName: StockActivityLogService::LOG_SALE,
|
|
event: 'decrease',
|
|
description: 'Stok '.$item->orderable->name.' di '.$outlet->name.' berkurang '.formatCurrencyNumber($quantity),
|
|
performedOn: $item->orderable,
|
|
outlet: $outlet,
|
|
quantityChange: -1 * abs($quantity),
|
|
previousStock: $currentStock,
|
|
newStock: $newStock,
|
|
extraProperties: [
|
|
'orderable_id' => $item->orderable_id,
|
|
'orderable_type' => $item->orderable_type,
|
|
'order_id' => $item->order_id ?? null,
|
|
]
|
|
);
|
|
}
|
|
|
|
return ['status' => true];
|
|
}
|
|
}
|