I have an API endpoint that points to /api/invoices
and it returns a list of invoices.
Some invoices return something like this:
{
"id": 2555,
"entity_id": 88,
"net_total": 7.5,
"total_vat": 1.725000000000000088817841970012523233890533447265625,
"grand_total": 9.2249999999999996447286321199499070644378662109375,
}
As you can see, there’s too many decimal places. My money columns are all defined as double(20,5)
, because the software needs to handle up to 5 decimal places (but mostly is only 2) and 20 units.
Is there any way to force either through MySQL or Laravel, to always return 5 decimal places? I can’t use:
->selectRaw('ROUND(total_vat, 5) as total_vat')
Because I have around 100 columns and I get them all without using ->select()
.
2
Answers
The solution is to convert the columns into decimals and maintain the same structure, like said in this post https://stackoverflow.com/a/24135191/3355243.
I did a few tests and the column value kept the original data.
However, this will lead to another issue, which is laravel casting decimal as string. By using postman, we can see that currency values comes as string, like "15.00". To solve this we can use cast Eloquent casts decimal as string:
I wasn't able to find / check if using the cast creates any problem with the original value.
Be careful while converting
DOUBLE
toDECIMAL
, as, like in my case, this may trigger severe problems in your project. For example, my mobile App stopped working after the conversion, because is not ready to handle the currency values as string.I would suggest using API Resources for transforming data.
If you just return
Invoices::all()
in your API, then yes, it will return "as is".But a typical way to transform any data would be API Resources:
Then, inside of that resource, you return only what you need and transformed however you want, including the 5 digits:
app/Http/Resources/InvoiceResource.php:
Then, in Controller:
Also, API Resources would add "data" wrapper layer by default when returned, so you may want to avoid that, then add this to AppServiceProvider:
app/Providers/AppServiceProvider.php: