feat: Introduce feed purchase editing and refactor cart handling to be associated with specific records.

This commit is contained in:
Yoga Pangestu 2026-02-19 13:10:30 +07:00
parent 2d3fdcb8e2
commit aadd1da05a
6 changed files with 122 additions and 19 deletions

View File

@ -3,6 +3,7 @@
namespace App\Filament\Resources\Manage\FeedPurchases;
use App\Filament\Resources\Manage\FeedPurchases\Pages\CreateFeedPurchase;
use App\Filament\Resources\Manage\FeedPurchases\Pages\EditFeedPurchase;
use App\Filament\Resources\Manage\FeedPurchases\Pages\ListFeedPurchases;
use App\Filament\Resources\Manage\FeedPurchases\Schemas\FeedPurchaseForm;
use App\Filament\Resources\Manage\FeedPurchases\Tables\FeedPurchasesTable;
@ -45,6 +46,7 @@ public static function getPages(): array
return [
'index' => ListFeedPurchases::route('/'),
'create' => CreateFeedPurchase::route('/create'),
'edit' => EditFeedPurchase::route('/{record}/edit'),
];
}
}

View File

@ -19,6 +19,13 @@ class CreateFeedPurchase extends CreateRecord
protected static ?string $title = 'Tambah Belanja Pakan';
public function mount(): void
{
parent::mount();
$this->loadCartFromDb();
}
#[On('cart-updated')]
public function onCartUpdated(): void
{

View File

@ -0,0 +1,65 @@
<?php
namespace App\Filament\Resources\Manage\FeedPurchases\Pages;
use App\Filament\Actions\BackAction;
use App\Filament\Resources\Manage\FeedPurchases\FeedPurchaseResource;
use App\Filament\Resources\Manage\FeedPurchases\Traits\HasCart;
use App\Models\FeedPurchaseItem;
use Filament\Resources\Pages\EditRecord;
use Livewire\Attributes\On;
class EditFeedPurchase extends EditRecord
{
use HasCart;
protected static string $resource = FeedPurchaseResource::class;
protected ?string $heading = 'Ubah Belanja Pakan';
protected static ?string $title = 'Ubah Belanja Pakan';
public function mount(int|string $record): void
{
parent::mount($record);
$this->loadCartFromDb();
}
#[On('cart-updated')]
public function onCartUpdated(): void
{
$this->syncTotalPriceFromCart();
}
protected function syncTotalPriceFromCart(): void
{
$total = (int) FeedPurchaseItem::where('feed_purchase_id', $this->record->id)->sum('subtotal');
$this->form->fill([
...$this->form->getState(),
'total_price' => $total,
]);
}
protected function getHeaderActions(): array
{
return [
BackAction::make()
->url(ListFeedPurchases::getUrl()),
];
}
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('index');
}
protected function mutateFormDataBeforeSave(array $data): array
{
$total = FeedPurchaseItem::where('feed_purchase_id', $this->record->id)->sum('subtotal');
$data['total_price'] = $total;
return $data;
}
}

View File

@ -32,17 +32,6 @@ function () {
}
);
$cartItems = FeedPurchaseItem::with('feed')
->whereNull('feed_purchase_id')
->latest()
->get()
->map(function ($cartItem) {
$cartItem->subtotal = $cartItem->unit_price * $cartItem->quantity;
$cartItem->feedImage = $cartItem->feed?->getFirstMediaUrl('feeds');
return $cartItem;
});
return $schema
->components([
Section::make('Informasi Belanja')
@ -73,7 +62,7 @@ function () {
->prefix('Rp')
->required()
->dehydrateStateUsing(fn ($state) => (int) str()->replace(',', '', (string) ($state ?? 0)))
->default(fn () => (int) FeedPurchaseItem::whereNull('feed_purchase_id')->sum('subtotal')),
->default(fn ($record) => (int) FeedPurchaseItem::where('feed_purchase_id', $record?->id)->sum('subtotal')),
Textarea::make('notes')
->label('Catatan')
@ -103,8 +92,17 @@ function () {
Section::make('Keranjang')
->schema([
View::make('filament.resources.manage.feed-purchases.cart')
->viewData([
'cartItems' => $cartItems,
->viewData(fn ($record) => [
'cartItems' => FeedPurchaseItem::with('feed')
->where('feed_purchase_id', $record?->id)
->latest()
->get()
->map(function ($cartItem) {
$cartItem->subtotal = $cartItem->unit_price * $cartItem->quantity;
$cartItem->feedImage = $cartItem->feed?->getFirstMediaUrl('feeds');
return $cartItem;
}),
]),
])
->columnSpan([

View File

@ -3,6 +3,7 @@
namespace App\Filament\Resources\Manage\FeedPurchases\Tables;
use App\Filament\Actions\Cheerful\DeleteAction;
use App\Filament\Actions\Cheerful\EditAction;
use App\Filament\Actions\Cheerful\ForceDeleteAction;
use App\Filament\Actions\Cheerful\RestoreAction;
use App\Filament\Actions\DefaultBulkActions;
@ -85,6 +86,9 @@ public static function configure(Table $table): Table
->native(false),
])
->recordActions([
EditAction::make()
->label('Ubah'),
DeleteAction::make(),
ForceDeleteAction::make(),

View File

@ -11,7 +11,9 @@ trait HasCart
public function loadCartFromDb(): void
{
$this->cart = FeedPurchaseItem::whereNull('feed_purchase_id')
$id = isset($this->record) ? $this->record->id : null;
$this->cart = FeedPurchaseItem::where('feed_purchase_id', $id)
->get()
->pluck('quantity', 'feed_id')
->map(fn ($qty) => ['qty' => (int) $qty])
@ -25,7 +27,9 @@ public function addFeed(int $feedId): void
return;
}
$item = FeedPurchaseItem::whereNull('feed_purchase_id')
$id = isset($this->record) ? $this->record->id : null;
$item = FeedPurchaseItem::where('feed_purchase_id', $id)
->where('feed_id', $feedId)
->first();
@ -34,7 +38,7 @@ public function addFeed(int $feedId): void
$item->update(['subtotal' => $item->quantity * $item->unit_price]);
} else {
FeedPurchaseItem::create([
'feed_purchase_id' => null,
'feed_purchase_id' => $id,
'feed_id' => $feedId,
'quantity' => 1,
'unit_price' => $feed->price,
@ -42,13 +46,20 @@ public function addFeed(int $feedId): void
]);
}
// Update stock if editing
if ($id) {
$feed->increment('stock', 1);
}
$this->loadCartFromDb();
$this->dispatch('cart-updated');
}
public function decreaseQty(int $feedId): void
{
$item = FeedPurchaseItem::whereNull('feed_purchase_id')
$id = isset($this->record) ? $this->record->id : null;
$item = FeedPurchaseItem::where('feed_purchase_id', $id)
->where('feed_id', $feedId)
->first();
@ -60,6 +71,11 @@ public function decreaseQty(int $feedId): void
$item->delete();
}
// Update stock if editing
if ($id) {
$item->feed?->decrement('stock', 1);
}
$this->loadCartFromDb();
$this->dispatch('cart-updated');
}
@ -67,7 +83,18 @@ public function decreaseQty(int $feedId): void
public function removeCartItem(int $itemId): void
{
FeedPurchaseItem::where('id', $itemId)->whereNull('feed_purchase_id')->delete();
$id = isset($this->record) ? $this->record->id : null;
$item = FeedPurchaseItem::find($itemId);
if ($item && $item->feed_purchase_id == $id) {
// Revert stock if editing
if ($id) {
$item->feed?->decrement('stock', $item->quantity);
}
$item->delete();
}
$this->loadCartFromDb();
$this->dispatch('cart-updated');
}