From 8742bd59daf3b17faf21a59fe23136cb9e623464 Mon Sep 17 00:00:00 2001 From: Mert Demir Date: Sun, 29 Sep 2024 22:24:10 +0900 Subject: [PATCH] Fix format for integer amounts (#231) * support both fractions and integer values * test fractions * prettier --- .../expenses/create-from-receipt-button.tsx | 1 + src/lib/utils.test.ts | 13 +++++++++---- src/lib/utils.ts | 8 +++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/app/groups/[groupId]/expenses/create-from-receipt-button.tsx b/src/app/groups/[groupId]/expenses/create-from-receipt-button.tsx index 4c276b50..cb2bfe58 100644 --- a/src/app/groups/[groupId]/expenses/create-from-receipt-button.tsx +++ b/src/app/groups/[groupId]/expenses/create-from-receipt-button.tsx @@ -206,6 +206,7 @@ export function CreateFromReceiptButton({ groupCurrency, receiptInfo.amount, locale, + true, )} ) : ( diff --git a/src/lib/utils.test.ts b/src/lib/utils.test.ts index 08bb6690..f904e4c5 100644 --- a/src/lib/utils.test.ts +++ b/src/lib/utils.test.ts @@ -57,10 +57,15 @@ describe('formatCurrency', () => { ] for (const variation of variations) { - it(`formats ${variation.amount} in ${variation.locale}`, () => { - expect(formatCurrency(currency, variation.amount, variation.locale)).toBe( - variation.result, - ) + it(`formats ${variation.amount} in ${variation.locale} without fractions`, () => { + expect( + formatCurrency(currency, variation.amount * 100, variation.locale), + ).toBe(variation.result) + }) + it(`formats ${variation.amount} in ${variation.locale} with fractions`, () => { + expect( + formatCurrency(currency, variation.amount, variation.locale, true), + ).toBe(variation.result) }) } }) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 6313f414..9798960d 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -28,10 +28,16 @@ export function formatCategoryForAIPrompt(category: Category) { return `"${category.grouping}/${category.name}" (ID: ${category.id})` } +/** + * @param fractions Financial values in this app are generally processed in cents (or equivalent). + * They are are therefore integer representations of the amount (e.g. 100 for USD 1.00). + * Set this to `true` if you need to pass a value with decimal fractions instead (e.g. 1.00 for USD 1.00). + */ export function formatCurrency( currency: string, amount: number, locale: string, + fractions?: boolean, ) { const format = new Intl.NumberFormat(locale, { minimumFractionDigits: 2, @@ -40,7 +46,7 @@ export function formatCurrency( // '€' will be placed in correct position currency: 'EUR', }) - const formattedAmount = format.format(amount) + const formattedAmount = format.format(fractions ? amount : amount / 100) return formattedAmount.replace('€', currency) }