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 AppFilamentResources;
use AppModelsOrder;
use AppModelsProduct;
use FilamentForms;
use FilamentResourcesForm;
use FilamentResourcesResource;
use IlluminateSupportFacadesLog;
class OrderResource extends Resource
{
protected static ?string $model = Order::class;
public static function form(Form $form): Form
{
return $form->schema([
FormsComponentsRepeater::make('order_details')
->relationship('orderDetails')
->schema([
FormsComponentsSelect::make('product_id')
->options(Product::pluck('name', 'id'))
->reactive()
->required()
->afterStateUpdated(fn($state, callable $set, callable $get) =>
self::updateProductSelection($state, $get, $set)
),
FormsComponentsTextInput::make('quantity')
->numeric()
->reactive()
->default(1)
->afterStateUpdated(fn($state, callable $get, callable $set) =>
self::updateProductTotal($get, $set)
),
FormsComponentsTextInput::make('total')->disabled(),
])
->afterStateUpdated(fn(callable $get, callable $set) =>
self::recalculateGrandTotal($get, $set)
),
FormsComponentsTextInput::make('discount')
->reactive()
->afterStateUpdated(fn($state, callable $get, callable $set) =>
self::recalculateGrandTotal($get, $set)
),
FormsComponentsTextInput::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.