Custom summaries with value calculated in column
I'm encountering an issue with a dynamic column in Filament that calculates a price on the fly and needs to display a summarized total at the bottom of the table. The column does not store data in the database but computes it dynamically within the column definition. The problem arises because the calculation seems to be performed multiple times, resulting in an incorrect total.
2 Replies
Here is the relevant code:
This is TenantRateResource extends Resource, in the method
This is ListTenantRates.php
table(Table $table): Table
TextColumn::make('calculated_price')
->label('Subtotal')
->getStateUsing(function (TenantRate $record, HasTable $livewire) {
$filterFrom = $livewire->getTableFilterState('tenant')['from'] ?? Carbon::now()->startOfMonth();
$filterTo = $livewire->getTableFilterState('tenant')['to'] ?? Carbon::now()->endOfMonth();
$from = Carbon::parse($filterFrom);
$to = Carbon::parse($filterTo);
$tenantRateCalculator = new TenantRateCalculator($record->tenant);
$price = $tenantRateCalculator->calculate($from, $to);
$livewire->updateTotalCalculatedPrice($price);
return $price; // I need access this price in summarize
})
->summarize(
Summarizer::make()
->label('Total')
->using(function (TenantRate $record, HasTable $livewire) {
return $livewire->getTotalCalculatedPrice(); // This solution is temporary, here you must add the price
})
),
TextColumn::make('calculated_price')
->label('Subtotal')
->getStateUsing(function (TenantRate $record, HasTable $livewire) {
$filterFrom = $livewire->getTableFilterState('tenant')['from'] ?? Carbon::now()->startOfMonth();
$filterTo = $livewire->getTableFilterState('tenant')['to'] ?? Carbon::now()->endOfMonth();
$from = Carbon::parse($filterFrom);
$to = Carbon::parse($filterTo);
$tenantRateCalculator = new TenantRateCalculator($record->tenant);
$price = $tenantRateCalculator->calculate($from, $to);
$livewire->updateTotalCalculatedPrice($price);
return $price; // I need access this price in summarize
})
->summarize(
Summarizer::make()
->label('Total')
->using(function (TenantRate $record, HasTable $livewire) {
return $livewire->getTotalCalculatedPrice(); // This solution is temporary, here you must add the price
})
),
<?php
namespace App\Filament\Resources\TenantRateResource\Pages;
use App\Filament\Resources\TenantRateResource;
use App\Filament\Widgets\TenantRateTotal;
use Filament\Resources\Pages\ListRecords;
class ListTenantRates extends ListRecords
{
protected static string $resource = TenantRateResource::class;
public $totalCalculatedPrice = 0;
protected function getHeaderActions(): array
{
return [];
}
public function updateTotalCalculatedPrice($amount)
{
$this->totalCalculatedPrice += $amount;
}
public function getTotalCalculatedPrice()
{
/* To temporarily resolve this, I divided the total by 3 in the getTotalCalculatedPrice method. This workaround is necessary because the state is being duplicated three times, likely due to how the table rendering process manages state: */
return $this->totalCalculatedPrice / 3;
}
public function updatedTableFilters(): void
{
parent::updatedTableFilters();
$this->totalCalculatedPrice = 0;
}
}
<?php
namespace App\Filament\Resources\TenantRateResource\Pages;
use App\Filament\Resources\TenantRateResource;
use App\Filament\Widgets\TenantRateTotal;
use Filament\Resources\Pages\ListRecords;
class ListTenantRates extends ListRecords
{
protected static string $resource = TenantRateResource::class;
public $totalCalculatedPrice = 0;
protected function getHeaderActions(): array
{
return [];
}
public function updateTotalCalculatedPrice($amount)
{
$this->totalCalculatedPrice += $amount;
}
public function getTotalCalculatedPrice()
{
/* To temporarily resolve this, I divided the total by 3 in the getTotalCalculatedPrice method. This workaround is necessary because the state is being duplicated three times, likely due to how the table rendering process manages state: */
return $this->totalCalculatedPrice / 3;
}
public function updatedTableFilters(): void
{
parent::updatedTableFilters();
$this->totalCalculatedPrice = 0;
}
}
Were you able to solve it?