F
Filament15mo ago
F alko

Issue with money formatting

Tables\Columns\TextColumn::make('price')
->money('eur', 100)
->sortable(),
Tables\Columns\TextColumn::make('price')
->money('eur', 100)
->sortable(),
I have a price field that is an unsigned integer contain the value 450. I expect to get €4.50, yet I get: €4.00. It seams to have a problem with minor units. Am I doing something wrong? I am on Filament v3.0.60 btw.
3 Replies
blakdronzer
blakdronzer15mo ago
Well to what i understand from the documentation provided - it practically divides the money by 100
F alko
F alkoOP15mo ago
Yea, so 450 should become 4.50 not 4.00 right?
Jo
Jo15mo ago
I think it's a bug, because in the format_money() helper we have this:
if ($divideBy) {
$money = bcdiv((string) $money, (string) $divideBy);
}
if ($divideBy) {
$money = bcdiv((string) $money, (string) $divideBy);
}
So, for example, if we do bcdiv(450, 100); in tinker, it's going to come back as 4 which is obviously not what we want. To get 4.5 we would have to do bcdiv(450, 100, 2). I think it needs a PR for Filament\Tables\Columns\Concerns\CanFormatState::money and Filament\Support\format_money to fix it. Maybe a $decimals param? But there's no money() for the forms, so it's still going to make more work I think. Maybe it's easier to just do money('eur') (remove the 100) in Filament and then fix everything else with some accessor/mutator magic in the model:
use Illuminate\Database\Eloquent\Casts\Attribute;

public function price(): Attribute
{
return Attribute::make(
get: fn ($value) => $value / 100,
set: fn ($value) => $value * 100
);
}
use Illuminate\Database\Eloquent\Casts\Attribute;

public function price(): Attribute
{
return Attribute::make(
get: fn ($value) => $value / 100,
set: fn ($value) => $value * 100
);
}
That way, your price will display as 4.50 in the table and form and even in frontend blade etc but it will always be saved as 450 in the database.
Want results from more Discord servers?
Add your server