Region-aware foundation: per-practice currency, tax & date formatting#9
Merged
Conversation
Foundation for region-aware behavior (Phase 2). Adds country, currency, taxRatePercent, and vatNumber to the practices table (US/usd/8% defaults so existing practices are unchanged), plus a pure locale module: formatCurrency, formatDate (UTC, locale-ordered), regulatoryFramework(country), and regionDefaults(country) for onboarding/settings. 7 tests. Note: additive schema — run pnpm db:push on deploy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Invoice tax was a fixed 8% and Stripe checkout was fixed to USD; both now read the practice's region config: - billing.createInvoice and templates.addItemsFromTemplate compute tax from practice.taxRatePercent (fallback 8%) - new billing.getTaxConfig query feeds the invoice-form total preview so it matches the server's authoritative calculation - portal checkout charges in practice.currency; createCheckoutSession takes a currency param (defaults usd) - settings.updatePractice accepts country/currency/taxRatePercent/vatNumber and applies regionDefaults() when the country changes US practices are unchanged (defaults usd/8%). Foundation for UK/EU pricing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Admins can now set their practice's country, currency, tax/VAT rate, and VAT number from Settings → Practice Info. Picking a country prefills the usual currency/tax/timezone defaults (overridable). This is the UI surface for the region fields wired through billing + checkout, making Phase 2 usable end to end. Adds UK/EU/CA/AU timezones to the picker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Currency was displayed as hardcoded USD/$ across the app even though billing now charges in the practice currency. Wire the region through every money surface: - new useCurrencyFormatter() hook reads billing.getTaxConfig and formats with the practice currency/country (React Query dedupes the request) - converted billing list/detail, new-invoice form, inventory, dashboard KPIs + revenue chart, reports, and the template price in settings - client portal invoices format in the practice currency/locale (portal getInvoices now returns currency + country per row) - invoice/estimate PDFs take a pre-formatted region-aware balanceDue - formatCurrency now coerces string/null/NaN amounts safely (DB values arrive as strings); +3 tests US practices are visually unchanged. Closes the region-aware display gap so a GB practice sees £ and dd/mm dates end to end. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
sendInvoiceEmail hardcoded a $ on the invoice total in both the client email and the logged communication. Read the practice currency/country and format via the shared helper so emailed totals match the rest of the app (e.g. £ for GB practices). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Region-aware foundation
Makes OpenVPM work correctly outside the US without changing anything for US practices. Today currency, tax, and date formatting are hardcoded to USD / 8% / US order; this wires a practice's region through billing and the whole UI so a clinic in another country sees the right currency, tax, and dates end to end.
US practices are unchanged — all defaults are US/USD/8%.
What's included
Schema —
country,currency,taxRatePercent,vatNumberonpractices(additive, with US defaults so existing rows keep working).Locale utilities (
lib/locale/format.ts, unit-tested) —formatCurrency,formatDate,regionDefaults(country), andregulatoryFramework(country)(the last sets up future controlled-drug/prescribing differences).De-hardcoded billing
Region-aware display everywhere — a shared
useCurrencyFormatter()hook (backed by a lightweightbilling.getTaxConfigquery) so amounts and dates render in the practice's region across billing, inventory, dashboard KPIs + revenue chart, reports, the client portal, invoice PDFs, and invoice emails.Notes
pnpm db:pushon deploy.pnpm test,pnpm type-check,pnpm buildall green (186 tests).🤖 Generated with Claude Code