fix(dashboard): render money in the property's currency, not hardcoded USD - #301
Conversation
telivity-otaip
left a comment
There was a problem hiding this comment.
Direction is right — thank you. Hardcoded $ + toFixed(2) and create paths forcing USD are real bugs for non-USD properties; formatMoney + PropertyContext.currencyCode is the right approach.
Requesting changes: description says all render sites are covered, but Folios, Cashier, FrontDesk, Reports table bodies, Dashboard portfolio table rows, and HouseAccounts balances still use $\u2026toFixed(2). Please either finish those in this PR or narrow the description / split a follow-up — happy either way, and happy to help if you want a second pair of hands.
|
Clarifying the request-changes note: Folios, Cashier, FrontDesk, Reports table bodies, Dashboard portfolio table rows, and HouseAccounts balances still use |
|
You're right, and the real number is worse than your list — thanks for catching it. I grepped a single pattern ( So my description overstated the diff — that's on me, and it's the same class of mistake as the bug itself: trusting one pattern to represent all occurrences. Plan, unless you'd prefer otherwise: finish all 63 in this PR rather than split, since a half-converted dashboard is arguably worse than none — a user seeing The mechanical part is easy; the fiddly part is that each render needs the property's Taking you up on the offer if it stalls — but no need yet. |
…y by hand Completes the review: 63 renders across 15 files, not the 18 my first pass claimed — I had grepped a single pattern, which is the same mistake as the bug itself. The design changed to make that safe. Rather than thread currencyCode into every component that happens to show an amount — including module-level helpers that cannot call a hook — lib/money keeps the active property's currency in a module value that PropertyContext pushes on change. That is the pattern lib/api.ts already uses for propertyId, so it follows the codebase rather than inventing a mechanism. Call sites are now formatMoney(amount), with an explicit second argument only where a record carries its own currency. Nothing needs a hook in scope, which is what made the earlier partial attempts fragile.
|
Done — all 63 across the 15 files, zero One design change worth flagging, because it's what made finishing it safe: rather than thread Call sites are plain Portfolio mode still falls back to the default deliberately — properties spanning currencies have no single right answer, and asserting one property's code over the others would be wrong. |
…sultants/haip into fix/currency-display
|
Correction to my previous comment: when I posted it the push had actually been rejected (non-fast-forward) and I didn't check before saying it was done. Apologies — it's pushed now, verified as The rejection was because you'd merged Worth noting your |
Maintainer polish on the currency-display work: four leftover bare-$ renders in the cashier session report summary. Co-authored-by: telivity-otaip <telivity-otaip@users.noreply.github.com>
telivity-otaip
left a comment
There was a problem hiding this comment.
Thanks for finishing the full pass, Charles — and for the honest correction on the push. The activeCurrency module value (same pattern as setPropertyId in lib/api.ts) is the right call; it made the remaining call sites safe without threading hooks everywhere.
Merging with full credit to you. Small maintainer polish on top of your PR: four leftover bare-$ amounts in the Cashier session-report summary now go through formatMoney as well.
Running a property with
currencyCode: 'JPY', every money value in the dashboard renders as US dollars — a ¥511,275 reservation shows as$511275.00.Two defects, the second worse than the first
Display (18 sites).
`$${Number(amount).toFixed(2)}`— a hardcoded symbol and hardcoded two decimal places, ignoring thecurrencyCodethat is already on every record. For yen the decimals are wrong too: JPY has no minor unit, so the correct render is¥511,275.Writes (7 sites).
currencyCode: 'USD'is hardcoded when creating rate plans, reservations, house accounts and ledger entries. On a non-USD property that writes incorrect data silently — a rate plan created through the UI on a yen property is stored as USD.The root of both:
PropertySummarydoesn't carrycurrencyCode, so the dashboard has no way to know the property's currency even though the API returns it.The change
lib/money.ts—formatMoney/formatMoneyPlainviaIntl.NumberFormat, so symbol, separators and fraction digits all derive from the ISO 4217 code. Unknown codes degrade to1234.00 XYZrather than a wrong symbol.currencyCodeadded toPropertySummaryand exposed fromPropertyContext. Portfolio mode falls back to the default deliberately — properties spanning currencies have no single answer, and asserting one property's code over others would be wrong.NightAudit's revenue helper is module-level so it takes the currency as a parameter rather than reaching for a hook.Notes
Removed a local
formatMoneyshadow inChannels.tsxthat duplicated the new shared helper.You ship German, Portuguese, Spanish, French, Croatian, Italian and Serbian dashboard locales — this is the money half of that same internationalisation, and it currently blocks any non-USD operator.
Found running HAIP self-hosted for a property trading in yen.