mgv-backoffice 1.45.0 → 1.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -136,6 +136,48 @@ export function fmtMoney(
136
136
  return `${negative ? '-' : ''}${currency}${abs}`
137
137
  }
138
138
 
139
+ // Symbols for the fiat currencies that have one. USD stablecoins (USDT,
140
+ // USDC) are not here: they read as "$" via DOLLAR_LIKE below.
141
+ const CURRENCY_SYMBOLS: Record<string, string> = { EUR: '€', GBP: '£' }
142
+ const DOLLAR_LIKE = new Set(['USD', 'USDT', 'USDC'])
143
+
144
+ /**
145
+ * Display symbol for an ISO / ticker currency code: "€" for EUR, "£" for
146
+ * GBP, "$" for USD and the USD stablecoins — and for a missing code, so
147
+ * rows with no currency keep reading as dollars. Any other code (BTC,
148
+ * ETH, …) has no symbol and returns null; callers suffix the code instead.
149
+ */
150
+ export function currencySymbol(code: string | null | undefined): string | null {
151
+ const c = (code ?? '').trim().toUpperCase()
152
+ if (!c || DOLLAR_LIKE.has(c)) return '$'
153
+ return CURRENCY_SYMBOLS[c] ?? null
154
+ }
155
+
156
+ /**
157
+ * Format an amount in its own currency: fiat with a symbol goes through
158
+ * fmtMoney ("€20.00", "-$1.50"), a USD stablecoin keeps its ticker after
159
+ * the dollar figure ("$25.00 USDT") so it isn't mistaken for cash, and any
160
+ * other asset prints as a plain quantity with its code ("0.5 BTC", up to 8
161
+ * decimals). Em-dash for missing / non-finite amounts, like fmtMoney.
162
+ */
163
+ export function fmtCurrencyAmount(
164
+ n: number | string | null | undefined,
165
+ code: string | null | undefined,
166
+ digits = 2,
167
+ ): string {
168
+ const c = (code ?? '').trim().toUpperCase()
169
+ const symbol = currencySymbol(c)
170
+ if (symbol !== null) {
171
+ const money = fmtMoney(n, digits, symbol)
172
+ return c && c !== 'USD' && DOLLAR_LIKE.has(c) && money !== EM_DASH ? `${money} ${c}` : money
173
+ }
174
+ if (n === null || n === undefined) return EM_DASH
175
+ if (typeof n === 'string' && n.trim() === '') return EM_DASH
176
+ const v = typeof n === 'string' ? Number(n) : n
177
+ if (!isFinite(v)) return EM_DASH
178
+ return `${v.toLocaleString(undefined, { maximumFractionDigits: 8 })} ${c}`
179
+ }
180
+
139
181
  /**
140
182
  * Format an ISO date string / epoch as a "Mon D, YYYY" calendar label
141
183
  * (en-US, e.g. "Jan 5, 2026"). Falls back to the raw value on parse