It seems it's time for value object Money:
class Money
{
public readonly int $amount;
public readonly Currency $currency = Currency::USD;
public static function fromFloat(float $value): self
{
return new self(round($value * 100));
}
public static function fromInt(int $value): self
{
return new self($value);
}
}
enum Currency
{
case USD;
case EUR;
// ...
}
After that you can call desired behaviour from different part of your app:
$money = Money::fromFloat($request->input('price'); // user input is "12.34"
$money = Money::fromInt($some_api->getAmount()); // some external api gives "1234"
$money = Money::fromString("EUR 176"); // etc...
You will always have consistent money data no matter where it came from and in what format.
Also the important thing, cast column price of Product model to Money type as described here: https://laravel.com/docs/12.x/eloquent-mutators#value-object-casting