October 23, 2024
Chicago 12, Melborne City, USA
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.IN THIS IMAGE AS YOU CAN SEE GRAND TOTAL FIELD NOT UPDATING



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video