OiO.lk Blog PHP Filament Resource: Grand Total Not Updating on Product/Quantity Changes
PHP

Filament Resource: Grand Total Not Updating on Product/Quantity Changes


I’m building an order management system using Filament in Laravel. However, I’m running into an issue where the grand total only updates when the discount field is changed, but it does not recalculate when products or quantities are added/updated.

// OrderResource.php

namespace App\Filament\Resources;

use App\Models\Order;
use App\Models\Product;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Illuminate\Support\Facades\Log;

class OrderResource extends Resource
{
    protected static ?string $model = Order::class;

    public static function form(Form $form): Form
    {
        return $form->schema([
            Forms\Components\Repeater::make('order_details')
                ->relationship('orderDetails')
                ->schema([
                    Forms\Components\Select::make('product_id')
                        ->options(Product::pluck('name', 'id'))
                        ->reactive()
                        ->required()
                        ->afterStateUpdated(fn($state, callable $set, callable $get) =>
                            self::updateProductSelection($state, $get, $set)
                        ),

                    Forms\Components\TextInput::make('quantity')
                        ->numeric()
                        ->reactive()
                        ->default(1)
                        ->afterStateUpdated(fn($state, callable $get, callable $set) =>
                            self::updateProductTotal($get, $set)
                        ),

                    Forms\Components\TextInput::make('total')->disabled(),
                ])
                ->afterStateUpdated(fn(callable $get, callable $set) =>
                    self::recalculateGrandTotal($get, $set)
                ),

            Forms\Components\TextInput::make('discount')
                ->reactive()
                ->afterStateUpdated(fn($state, callable $get, callable $set) =>
                    self::recalculateGrandTotal($get, $set)
                ),

            Forms\Components\TextInput::make('grand_total')->disabled(),
        ]);
    }

    protected static function updateProductSelection($state, callable $get, callable $set)
    {
        $product = Product::find($state);
        $set('price', $product->price ?? 0);
        self::recalculateGrandTotal($get, $set);
    }

    protected static function updateProductTotal(callable $get, callable $set)
    {
        $price = (float) $get('price');
        $quantity = (int) $get('quantity');
        $set('total', $price * $quantity);
        self::recalculateGrandTotal($get, $set);
    }

    protected static function recalculateGrandTotal(callable $get, callable $set)
    {
        $orderDetails = $get('order_details') ?? [];
        $discount = (float) $get('discount') ?? 0;

        $grandTotal = collect($orderDetails)
            ->sum(fn($detail) => (float) ($detail['total'] ?? 0));

        if ($discount > 0) {
            $grandTotal -= ($grandTotal * $discount) / 100;
        }

        $set('grand_total', $grandTotal);

        Log::info('Grand Total recalculated:', ['grandTotal' => $grandTotal]);
    }
}

The grand total only updates if the discount field is changed, but not when I change products or quantities.
Logs show correct product/quantity updates, but the grand total stays at 0.How can I ensure that grand total updates dynamically when products or quantities change? I don’t want the discount field to control the grand total calculation.



You need to sign in to view this answers

Exit mobile version