currency.ts 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import getMeta from '@/utils/meta'
  2. const DEFAULT_LOCALE = getMeta('ol-i18n')?.currentLangCode ?? 'en'
  3. const ZERO_DECIMAL_CURRENCIES = ['clp', 'jpy', 'krw', 'vnd']
  4. export function formatCurrency(
  5. amount: number,
  6. currency: string,
  7. locale: string = DEFAULT_LOCALE,
  8. stripIfInteger = false
  9. ): string {
  10. const isZeroDecimal = ZERO_DECIMAL_CURRENCIES.includes(currency.toLowerCase())
  11. const fractionDigits = isZeroDecimal ? 0 : 2
  12. const options: Intl.NumberFormatOptions = {
  13. style: 'currency',
  14. currency,
  15. minimumFractionDigits: fractionDigits,
  16. maximumFractionDigits: fractionDigits,
  17. }
  18. if (stripIfInteger && Number.isInteger(amount)) {
  19. options.minimumFractionDigits = 0
  20. }
  21. try {
  22. return amount.toLocaleString(locale, {
  23. ...options,
  24. currencyDisplay: 'narrowSymbol',
  25. })
  26. } catch {}
  27. try {
  28. return amount.toLocaleString(locale, options)
  29. } catch {}
  30. return `${currency} ${amount}`
  31. }
  32. export function convertToMinorUnits(amount: number, currency: string): number {
  33. const isNoCentsCurrency = ['clp', 'jpy', 'krw', 'vnd'].includes(
  34. currency.toLowerCase()
  35. )
  36. // Determine the multiplier based on currency
  37. let multiplier = 100 // default for most currencies (2 decimal places)
  38. if (isNoCentsCurrency) {
  39. multiplier = 1 // no decimal places
  40. }
  41. // Convert and round to an integer
  42. return Math.round(amount * multiplier)
  43. }