refactor(purchase): mengubah nama dan penyimpanan var untuk menampung items dari cartItems ke purchaseItems dan dipindahkan ke component create bukan lagi form

- membuat trait baru untuk calculate total
- menyesuaikan perubahan di atas
This commit is contained in:
Yoga Pangestu 2025-10-30 19:29:18 +07:00
parent 4fbb18b1ce
commit 6343802fd5
8 changed files with 71 additions and 31 deletions

View File

@ -4,6 +4,7 @@
use App\Models\Purchase;
use App\Rules\UnsignedInteger;
use App\Traits\Purchase\WithPurchaseItems;
use App\Traits\Purchase\WithUpdateStock;
use App\Traits\WithMediaHandler;
use Illuminate\Support\Facades\DB;
@ -12,7 +13,7 @@
class PurchaseForm extends Form
{
use WithMediaHandler, WithUpdateStock;
use WithMediaHandler, WithPurchaseItems, WithUpdateStock;
public ?Purchase $purchase = null;
@ -44,14 +45,12 @@ class PurchaseForm extends Form
public string $quantity_edit = '';
public $cartItems;
public function rules(): array
{
return [
'invoice_number' => ['nullable', 'string', 'max:50'],
'note' => ['nullable', 'string', 'max:100'],
'purchase_date' => ['required', 'date'],
'purchase_date' => ['required', 'date', 'before_or_equal:today'],
'outlet_id' => ['required', Rule::exists('outlets', 'id')],
'total' => ['required', new UnsignedInteger],
'image' => ['nullable', 'array', 'max:1'],
@ -86,14 +85,16 @@ public function store()
{
$this->validate();
DB::transaction(function () {
$purchaseItems = $this->loadPurchaseItems();
DB::transaction(function () use ($purchaseItems) {
$purchase = Purchase::create($this->prepareSavedData());
$purchase->load('outlet');
$this->uploadMedia($this->image, $purchase, 'image');
foreach ($this->cartItems as $item) {
foreach ($purchaseItems as $item) {
$item->update(['purchase_id' => $purchase->id]);
$this->increaseOutletStock($purchase->outlet, $item);

View File

@ -7,9 +7,10 @@
use App\Models\Outlet;
use App\Models\Perfume;
use App\Models\Product;
use App\Models\PurchaseItem;
use App\Traits\Purchase\WithAddItem;
use App\Traits\Purchase\WithCalculateTotal;
use App\Traits\Purchase\WithDeleteItem;
use App\Traits\Purchase\WithPurchaseItems;
use App\Traits\Purchase\WithUpdateItem;
use App\Traits\WithAuthorization;
use App\Traits\WithConfirmation;
@ -21,7 +22,7 @@
#[Title('Tambah Belanja')]
class Create extends Component
{
use WithAddItem, WithAuthorization, WithConfirmation, WithDeleteItem, WithToast, WithUpdatedData, WithUpdateItem;
use WithAddItem, WithAuthorization, WithCalculateTotal, WithConfirmation, WithDeleteItem, WithPurchaseItems, WithToast, WithUpdatedData, WithUpdateItem;
public PurchaseForm $form;
@ -33,6 +34,8 @@ class Create extends Component
public array $bottles = [];
public $purchaseItems;
public function mount()
{
$this->outlets = Outlet::pluck('name', 'id')->toArray();
@ -43,14 +46,14 @@ public function mount()
$this->bottles = Bottle::pluck('name', 'id')->toArray();
$this->form->cartItems = PurchaseItem::whereNull('purchase_id')->get();
$this->purchaseItems = $this->loadPurchaseItems();
$this->form->total = currency($this->form->cartItems->sum('total_price'), '');
$this->form->total = $this->getTotal();
}
public function save()
{
if ($this->form->cartItems->isEmpty()) {
if ($this->purchaseItems->isEmpty()) {
$this->toast('Keranjang tidak boleh kosong.', 'Gagal', 'danger');
return;

View File

@ -59,7 +59,7 @@ public function addItem(string $type)
return;
}
$existingItem = $this->form->cartItems
$existingItem = $this->purchaseItems
->where('purchasable_type', $model)
->where('purchasable_id', $itemModel->id)
->first();
@ -71,11 +71,12 @@ public function addItem(string $type)
$existingItem->refresh();
$this->form->cartItems = $this->form->cartItems->map(fn ($i) => $i->id === $existingItem->id ? $existingItem : $i);
$this->purchaseItems = $this->purchaseItems->map(fn ($i) => $i->id === $existingItem->id ? $existingItem : $i);
$this->toast('Jumlah '.$type.' diperbarui di keranjang.', 'Berhasil');
} else {
$item = PurchaseItem::create([
'user_id' => auth()->id(),
'purchasable_id' => $itemModel->id,
'purchasable_type' => $model,
'quantity' => $quantity,
@ -83,18 +84,25 @@ public function addItem(string $type)
'total_price' => $costPrice * $quantity,
]);
$this->form->cartItems->push($item);
$this->purchaseItems->push($item);
$this->toast(Str::ucfirst($type).' ditambahkan ke keranjang.', 'Berhasil');
}
$this->form->total = currency($this->form->cartItems->sum('total_price'), '');
$this->form->total = currency($this->getTotal());
$this->reset('form.perfume_id');
$this->reset('form.product_id');
$this->reset('form.bottle_id');
$this->reset('form.quantity_perfume');
$this->reset('form.quantity_product');
$this->reset('form.quantity_bottle');
switch ($type) {
case 'parfum':
$this->reset(['form.perfume_id', 'form.quantity_perfume']);
break;
case 'produk':
$this->reset(['form.product_id', 'form.quantity_product']);
break;
case 'botol':
$this->reset(['form.bottle_id', 'form.quantity_bottle']);
break;
}
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace App\Traits\Purchase;
trait WithCalculateTotal
{
public function getTotal()
{
return $this->purchaseItems->sum(fn ($item) => $item->unit_price * $item->quantity);
}
}

View File

@ -8,11 +8,11 @@ trait WithDeleteItem
{
public function deleteItem(PurchaseItem $item)
{
$this->form->cartItems = $this->form->cartItems->reject(fn ($i) => $i->id === $item->id);
$this->purchaseItems = $this->purchaseItems->reject(fn ($i) => $i->id === $item->id);
$item->delete();
$this->form->total = currency($this->form->cartItems->sum('total_price'), '');
$this->form->total = currency($this->purchaseItems->sum('total_price'), '');
$this->toast('Item berhasil dihapus.');
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Traits\Purchase;
use App\Models\PurchaseItem;
trait WithPurchaseItems
{
public function loadPurchaseItems()
{
return $this->purchaseItems = PurchaseItem::query()
->currentUser()
->where('user_id', auth()->id())
->whereNull('purchase_id')
->latest()
->get();
}
}

View File

@ -17,7 +17,7 @@ public function openModal(PurchaseItem $item)
$this->form->item_id = $item->id;
$this->form->quantity_edit = currency($item->quantity, '');
$this->form->quantity_edit = currency($item->quantity);
}
public function closeModal()
@ -36,9 +36,9 @@ public function updateItem()
$item->refresh();
$this->form->cartItems = $this->form->cartItems->map(fn ($i) => $i->id === $item->id ? $item : $i);
$this->purchaseItems = $this->purchaseItems->map(fn ($i) => $i->id === $item->id ? $item : $i);
$this->form->total = currency($this->form->cartItems->sum('total_price'), '');
$this->form->total = currency($this->purchaseItems->sum('total_price'));
$this->toast('Item berhasil diperbarui.');

View File

@ -15,7 +15,7 @@
<div class="w-full lg:w-3/4 space-y-4">
<flux:card class="space-y-6 p-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<flux:input label="Nomor Invoice" placeholder="INV-2025-0001"
<flux:input label="Nomor Faktur" placeholder="INV-2025-0001"
wire:model.live.debounce.500ms="form.invoice_number" autofocus autocomplete="off" />
<flux:input label="Catatan" placeholder="Belanja pas hujan"
@ -96,9 +96,8 @@
<flux:select.option value="{{ $key }}">{{ $bottle }}</flux:select.option>
@endforeach
</flux:select>
<flux:input label="Kuantitas" placeholder="50"
wire:model.live="form.quantity_bottle" autocomplete="off"
x-mask:dynamic="$money($input, ',')" />
<flux:input label="Kuantitas" placeholder="50" wire:model.live="form.quantity_bottle"
autocomplete="off" x-mask:dynamic="$money($input, ',')" />
<div class="flex justify-end">
<flux:button variant="primary" color="zinc" wire:click="addItem('botol')">
@ -136,7 +135,7 @@
</flux:table.columns>
<flux:table.rows>
@forelse($form->cartItems as $item)
@forelse($purchaseItems as $item)
<flux:table.row>
<flux:table.cell>
<flux:heading>