Files
zod-backend/src/common/utils/currency.util.ts
Abdalhamid Alhamad 6d6dc1471f feat: add timezone support to user and device entities
- Introduced optional timezone fields in User and Device entities to store user preferences and device timezones.
- Updated request DTOs for login and user updates to include timezone information.
- Enhanced AuthService to handle timezone during device registration and updates.
- Added migration to incorporate timezone fields in the database schema.
2026-01-14 16:12:08 +03:00

112 lines
3.1 KiB
TypeScript

/**
* Currency utility functions
* Handles currency code mapping and formatting
*/
/**
* ISO 4217 numeric currency codes to ISO currency code mapping
* Common codes used in the system:
* - 682: SAR (Saudi Riyal)
* - 900: USD (US Dollar) - if used
* - 784: AED (UAE Dirham)
* - 414: KWD (Kuwaiti Dinar)
* - 512: OMR (Omani Rial)
* - 048: BHD (Bahraini Dinar)
* - 400: JOD (Jordanian Dinar)
*/
export const NUMERIC_TO_CURRENCY_CODE: Record<string, string> = {
'682': 'SAR',
'900': 'USD',
'784': 'AED',
'414': 'KWD',
'512': 'OMR',
'048': 'BHD',
'400': 'JOD',
'586': 'PKR',
};
/**
* Currency decimal places mapping
* ISO 4217 standard decimal places for each currency
*/
export const CURRENCY_DECIMAL_PLACES: Record<string, number> = {
'SAR': 2, // Saudi Riyal
'USD': 2, // US Dollar
'AED': 2, // UAE Dirham
'KWD': 3, // Kuwaiti Dinar
'OMR': 3, // Omani Rial
'BHD': 3, // Bahraini Dinar
'JOD': 3, // Jordanian Dinar
'PKR': 2, // Pakistani Rupee
'JPY': 0, // Japanese Yen (if used)
'KRW': 0, // South Korean Won (if used)
};
/**
* Convert numeric currency code to ISO currency code
* @param numericCode - Numeric currency code (e.g., '682')
* @returns ISO currency code (e.g., 'SAR') or the original code if not found
*/
export function numericToCurrencyCode(numericCode: string | null | undefined): string {
if (!numericCode) {
return 'SAR'; // Default fallback
}
// If already an ISO code (3 letters), return as is
if (/^[A-Z]{3}$/.test(numericCode)) {
return numericCode;
}
// Map numeric code to ISO code
return NUMERIC_TO_CURRENCY_CODE[numericCode] || numericCode;
}
/**
* Format amount based on currency decimal places
* @param amount - Amount to format (number or string)
* @param currency - ISO currency code (e.g., 'SAR', 'KWD')
* @returns Formatted amount string
*/
export function formatCurrencyAmount(amount: number | string, currency: string): string {
const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
if (isNaN(numAmount)) {
return '0';
}
const decimalPlaces = CURRENCY_DECIMAL_PLACES[currency] ?? 2;
return numAmount.toFixed(decimalPlaces);
}
/**
* Get currency from account or transaction, with fallback
* @param accountCurrency - Currency from account entity (may be numeric like '682')
* @param transactionCurrency - Currency from transaction entity (may be numeric)
* @param fallback - Fallback currency (default: 'SAR')
* @returns ISO currency code
*/
export function getCurrency(
accountCurrency?: string | null,
transactionCurrency?: string | null,
fallback: string = 'SAR'
): string {
// Convert account currency first (it may be numeric like '682')
if (accountCurrency) {
const converted = numericToCurrencyCode(accountCurrency);
if (converted && converted !== accountCurrency) {
return converted; // Successfully converted from numeric to ISO
}
// If already ISO format, return as is
if (/^[A-Z]{3}$/.test(accountCurrency)) {
return accountCurrency;
}
}
// Convert transaction currency (may be numeric)
if (transactionCurrency) {
return numericToCurrencyCode(transactionCurrency);
}
return fallback;
}