- Implemented stock transfer creation and management with Livewire components. - Created StockTransfer and StockTransferItem models with necessary relationships. - Added migration files for stock_transfers and stock_transfer_items tables. - Developed traits for handling stock transfer items (add, delete, update). - Integrated stock transfer logging in StockActivityLogService. - Updated ViewServiceProvider to include stock transfer permissions and routes. - Created frontend views for stock transfer form and index with appropriate UI components. - Added role permissions for stock transfer actions in RolePermissionSeeder.
113 lines
3.6 KiB
PHP
113 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Traits\StockTransfer;
|
|
|
|
use App\Models\Bottle;
|
|
use App\Models\Outlet;
|
|
use App\Models\Perfume;
|
|
use App\Models\Product;
|
|
use App\Models\StockTransferItem;
|
|
|
|
trait WithStockTransferAddItem
|
|
{
|
|
public function addItem(string $type): void
|
|
{
|
|
$this->canOrAbort('create stock transfer');
|
|
|
|
if (! $this->form->source_outlet_id) {
|
|
$this->toast('Silakan pilih outlet asal terlebih dahulu.', 'Gagal', 'warning');
|
|
|
|
return;
|
|
}
|
|
|
|
$sourceOutlet = Outlet::find($this->form->source_outlet_id);
|
|
|
|
if (! $sourceOutlet) {
|
|
$this->toast('Outlet asal tidak ditemukan.', 'Gagal', 'danger');
|
|
|
|
return;
|
|
}
|
|
|
|
$data = match ($type) {
|
|
'parfum' => [
|
|
'transferable_type' => Perfume::class,
|
|
'transferable_id' => $this->form->perfume_id,
|
|
'quantity' => parseRupiahToInt($this->form->quantity_perfume),
|
|
],
|
|
'produk' => [
|
|
'transferable_type' => Product::class,
|
|
'transferable_id' => $this->form->product_id,
|
|
'quantity' => parseRupiahToInt($this->form->quantity_product),
|
|
],
|
|
'botol' => [
|
|
'transferable_type' => Bottle::class,
|
|
'transferable_id' => $this->form->bottle_id,
|
|
'quantity' => parseRupiahToInt($this->form->quantity_bottle),
|
|
],
|
|
default => null,
|
|
};
|
|
|
|
if (! $data || ! $data['transferable_id'] || $data['quantity'] <= 0) {
|
|
$this->toast('Data item tidak valid.', 'Gagal', 'danger');
|
|
|
|
return;
|
|
}
|
|
|
|
// Validate stock availability
|
|
$relationName = match ($type) {
|
|
'parfum' => 'perfumes',
|
|
'produk' => 'products',
|
|
'botol' => 'bottles',
|
|
default => null,
|
|
};
|
|
|
|
if ($relationName) {
|
|
$sourceStock = $sourceOutlet->{$relationName}()
|
|
->where($data['transferable_type']::make()->getTable().'.id', $data['transferable_id'])
|
|
->first()
|
|
?->pivot
|
|
?->stock ?? 0;
|
|
|
|
// Is item already in cart?
|
|
$existing = StockTransferItem::where([
|
|
'user_id' => auth()->id(),
|
|
'transferable_id' => $data['transferable_id'],
|
|
'transferable_type' => $data['transferable_type'],
|
|
])->whereNull('stock_transfer_id')->first();
|
|
|
|
$currentCartQty = $existing ? $existing->quantity : 0;
|
|
$requestedQty = $data['quantity'];
|
|
|
|
if (($currentCartQty + $requestedQty) > $sourceStock) {
|
|
$this->toast("Stok tidak mencukupi. Stok di outlet asal: {$sourceStock}. Sudah di keranjang: {$currentCartQty}.", 'Gagal', 'danger');
|
|
|
|
return;
|
|
}
|
|
|
|
if ($existing) {
|
|
$existing->increment('quantity', $requestedQty);
|
|
} else {
|
|
StockTransferItem::create(array_merge($data, ['user_id' => auth()->id()]));
|
|
}
|
|
}
|
|
|
|
$this->resetFormItem($type);
|
|
$this->stockTransferItems = $this->loadStockTransferItems();
|
|
$this->toast('Item berhasil ditambahkan ke keranjang.');
|
|
}
|
|
|
|
private function resetFormItem(string $type): void
|
|
{
|
|
if ($type === 'parfum') {
|
|
$this->form->perfume_id = '';
|
|
$this->form->quantity_perfume = '';
|
|
} elseif ($type === 'produk') {
|
|
$this->form->product_id = '';
|
|
$this->form->quantity_product = '';
|
|
} elseif ($type === 'botol') {
|
|
$this->form->bottle_id = '';
|
|
$this->form->quantity_bottle = '';
|
|
}
|
|
}
|
|
}
|