Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 4 additions & 21 deletions src/components/CurrencyListContextProvider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';

import {convertToFrontendAmountAsInteger, sanitizeCurrencyCode} from '@libs/CurrencyUtils';
import {format, formatToParts} from '@libs/NumberFormatUtils';
import {convertToDisplayStringWithoutCurrencyForLocale, convertToFrontendAmountAsInteger, sanitizeCurrencyCode} from '@libs/CurrencyUtils';
import {format} from '@libs/NumberFormatUtils';

import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -57,25 +57,8 @@ function CurrencyListContextProvider({children}: React.PropsWithChildren) {
);

const convertToDisplayStringWithoutCurrency = useCallback(
(amountInCents: number, currencyCode: string = CONST.CURRENCY.USD): string => {
const sanitizedCurrency = sanitizeCurrencyCode(currencyCode);
const decimals = getCurrencyDecimals(sanitizedCurrency);
const convertedAmount = convertToFrontendAmountAsInteger(amountInCents, decimals);
return formatToParts(preferredLocale, convertedAmount, {
style: 'currency',
currency: sanitizedCurrency,

// We are forcing the number of decimals because we override the default number of decimals in the backend for some currencies
// See: https://github.com/Expensify/PHP-Libs/pull/834
minimumFractionDigits: decimals,
// For currencies that have decimal places > 2, floor to 2 instead as we don't support more than 2 decimal places.
maximumFractionDigits: 2,
})
.filter((x) => x.type !== 'currency')
.filter((x) => x.type !== 'literal' || x.value.trim().length !== 0)
.map((x) => x.value)
.join('');
},
(amountInCents: number, currencyCode: string = CONST.CURRENCY.USD): string =>
convertToDisplayStringWithoutCurrencyForLocale(preferredLocale, amountInCents, currencyCode, getCurrencyDecimals),
[getCurrencyDecimals, preferredLocale],
);

Expand Down
24 changes: 19 additions & 5 deletions src/libs/CurrencyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,19 @@ function convertToDisplayStringEnLocale(amountInCents: number, currency: string
}

/**
* Same as convertToDisplayStringWithoutCurrency but always formats with the `en` locale, with decimals
* injected. Used alongside convertToDisplayStringEnLocale for stored values (e.g. formula-computed
* report titles) that must not depend on the viewer's locale or this module's Onyx fallback.
* Given an amount in "cents", format it for the passed locale without the currency symbol. Decimals are
* injected so this function does not depend on this module's Onyx fallback.
*/
function convertToDisplayStringWithoutCurrencyEnLocale(
function convertToDisplayStringWithoutCurrencyForLocale(
locale: Locale | undefined,
amountInCents: number,
currency: string | undefined,
getCurrencyDecimalsImpl: CurrencyListActionsContextType['getCurrencyDecimals'],
): string {
const sanitizedCurrency = sanitizeCurrencyCode(currency);
const decimals = getCurrencyDecimalsImpl(sanitizedCurrency);
const convertedAmount = convertToFrontendAmountAsInteger(amountInCents, decimals);
return formatToParts(CONST.LOCALES.EN, convertedAmount, {
return formatToParts(locale, convertedAmount, {
style: 'currency',
currency: sanitizedCurrency,

Expand All @@ -177,6 +177,19 @@ function convertToDisplayStringWithoutCurrencyEnLocale(
.join('');
}

/**
* Same as convertToDisplayStringWithoutCurrency but always formats with the `en` locale, with decimals
* injected. Used alongside convertToDisplayStringEnLocale for stored values (e.g. formula-computed
* report titles) that must not depend on the viewer's locale or this module's Onyx fallback.
*/
function convertToDisplayStringWithoutCurrencyEnLocale(
amountInCents: number,
currency: string | undefined,
getCurrencyDecimalsImpl: CurrencyListActionsContextType['getCurrencyDecimals'],
): string {
return convertToDisplayStringWithoutCurrencyForLocale(CONST.LOCALES.EN, amountInCents, currency, getCurrencyDecimalsImpl);
}

/**
* Given the amount in the "cents", convert it to a short string (no decimals) for display in the UI.
* The backend always handle things in "cents" (subunit equal to 1/100)
Expand Down Expand Up @@ -226,5 +239,6 @@ export {
convertToDisplayStringEnLocale,
convertAmountToDisplayString,
convertToDisplayStringWithoutCurrencyEnLocale,
convertToDisplayStringWithoutCurrencyForLocale,
convertToShortDisplayString,
};
Loading