parfum/app/Traits/StockTransfer/WithStockTransferAddItem.php
Yoga Pangestu dffc9f9e72 feat: add stock transfer management functionality
- 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.
2026-01-09 21:41:49 +07:00

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 = '';
}
}
}