[PR #6954] Honor per-currency decimal places across app #6841

Open
opened 2026-02-28 21:33:25 -06:00 by GiteaMirror · 0 comments
Owner

Original Pull Request: https://github.com/actualbudget/actual/pull/6954

State: open
Merged: No


Sorry for yet another PR, but I noticed that Vietnamese Dong got added with the wrong decimal places, due to the longstanding issue with not handling other than 2 decimal places.

I originally included sync-server adapter work here, but that was decided to be out of scope, so this PR now focuses on desktop-client + loot-core currency precision only.

Summary

This PR fixes the "everything assumes 2 decimal places" problem.

Amounts now use each currency's decimalPlaces across account creation, transaction editing/table flows, search/formula paths, and budget-related UI code. This avoids the x10/x100/x1000 inflation issues when using zero-decimal or three-decimal currencies.

I also corrected VND metadata to use decimalPlaces: 0.

IMPORTANT: If this is merged and released at the same time as #6902, there will be no db migration needed. If after, a DB migration MAY be needed to fix the 100x issue on existing values.

Tests added/updated

  • Added transaction table round-trip tests for:
    • zero-decimal currencies
    • three-decimal currencies
    • existing two-decimal default behavior (packages/desktop-client/src/components/transactions/table/utils.test.ts)
  • Added utility tests for decimal-aware formatting helpers:
    • integerToCurrencyWithDecimal
    • appendDecimals (packages/loot-core/src/shared/util.test.ts)
  • Added E2E coverage for zero-decimal account flows (JPY, VND):
    • starting balance remains stable
    • close-account modal shows the correct balance text (packages/desktop-client/e2e/accounts.test.ts)
  • Updated E2E snapshots for account creation to check that the starting balance bug mentioned in #6902 is fixed.

Issues addressed

This PR is aimed at the non-2-decimal currency requests:

Test plan

  • yarn test
  • yarn typecheck
  • Manual smoke test with a zero-decimal currency (for example JPY / VND)

AI assistance

This change was made with the help of GPT-5.3 Codex.


Bundle Stats

Bundle Files count Total bundle size % Changed
desktop-client 27 14.85 MB → 14.85 MB (+5.26 kB) +0.03%
loot-core 1 5.82 MB → 5.82 MB (+1.02 kB) +0.02%
api 1 4.43 MB → 4.43 MB (+967 B) +0.02%
View detailed bundle stats

desktop-client

Total

Files count Total bundle size % Changed
27 14.85 MB → 14.85 MB (+5.26 kB) +0.03%
Changeset
File Δ Size
src/hooks/useTransactionsSearch.ts 📈 +90 B (+9.51%) 946 B → 1.01 kB
home/runner/work/actual/actual/packages/loot-core/src/shared/util.ts 📈 +665 B (+6.99%) 9.29 kB → 9.93 kB
src/components/modals/TrackingBudgetMenuModal.tsx 📈 +198 B (+5.39%) 3.59 kB → 3.78 kB
src/components/modals/EnvelopeBudgetMenuModal.tsx 📈 +198 B (+5.38%) 3.59 kB → 3.78 kB
src/components/transactions/table/utils.ts 📈 +83 B (+4.08%) 1.99 kB → 2.07 kB
src/components/budget/envelope/CoverMenu.tsx 📈 +206 B (+3.85%) 5.23 kB → 5.43 kB
src/components/mobile/transactions/FocusableAmountInput.tsx 📈 +487 B (+3.49%) 13.63 kB → 14.1 kB
src/queries/index.ts 📈 +85 B (+3.18%) 2.61 kB → 2.7 kB
src/components/modals/CreateLocalAccountModal.tsx 📈 +179 B (+2.61%) 6.7 kB → 6.87 kB
src/components/autocomplete/CategoryAutocomplete.tsx 📈 +429 B (+2.42%) 17.34 kB → 17.76 kB
home/runner/work/actual/actual/packages/loot-core/src/shared/currencies.ts 📈 +130 B (+2.24%) 5.66 kB → 5.79 kB
src/components/modals/EditFieldModal.tsx 📈 +160 B (+1.70%) 9.21 kB → 9.36 kB
src/components/mobile/transactions/TransactionListItem.tsx 📈 +214 B (+1.48%) 14.1 kB → 14.31 kB
src/components/settings/Currency.tsx 📈 +311 B (+1.42%) 21.41 kB → 21.71 kB
src/components/mobile/transactions/TransactionEdit.tsx 📈 +764 B (+1.21%) 61.8 kB → 62.55 kB
src/components/accounts/BalanceHistoryGraph.tsx 📈 +111 B (+1.06%) 10.23 kB → 10.33 kB
src/hooks/useFormulaExecution.ts 📈 +87 B (+1.06%) 8.02 kB → 8.1 kB
src/components/modals/CloseAccountModal.tsx 📈 +93 B (+0.76%) 11.88 kB → 11.97 kB
src/components/transactions/TransactionsTable.tsx 📈 +515 B (+0.58%) 86.2 kB → 86.7 kB
src/components/mobile/transactions/TransactionList.tsx 📈 +83 B (+0.41%) 19.55 kB → 19.64 kB
src/components/modals/ImportTransactionsModal/ImportTransactionsModal.tsx 📈 +105 B (+0.36%) 28.5 kB → 28.6 kB
src/components/accounts/Account.tsx 📈 +155 B (+0.30%) 50.67 kB → 50.82 kB
src/accounts/mutations.ts 📈 +38 B (+0.17%) 21.94 kB → 21.97 kB
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger

Asset File Size % Changed
static/js/index.js 9.54 MB → 9.54 MB (+4.65 kB) +0.05%
static/js/TransactionList.js 106.22 kB → 106.51 kB (+297 B) +0.27%
static/js/wide.js 164.15 kB → 164.3 kB (+155 B) +0.09%
static/js/narrow.js 637.77 kB → 637.86 kB (+90 B) +0.01%
static/js/ReportRouter.js 1.16 MB → 1.16 MB (+87 B) +0.01%

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
static/js/indexeddb-main-thread-worker-e59fee74.js 12.94 kB 0%
static/js/workbox-window.prod.es5.js 5.64 kB 0%
static/js/ca.js 188.15 kB 0%
static/js/da.js 106.35 kB 0%
static/js/de.js 180.07 kB 0%
static/js/en-GB.js 7.18 kB 0%
static/js/en.js 170.37 kB 0%
static/js/es.js 174.55 kB 0%
static/js/fr.js 179.6 kB 0%
static/js/it.js 171.16 kB 0%
static/js/nb-NO.js 156.96 kB 0%
static/js/nl.js 106.37 kB 0%
static/js/pl.js 88.37 kB 0%
static/js/pt-BR.js 154.22 kB 0%
static/js/th.js 181.87 kB 0%
static/js/uk.js 214.74 kB 0%
static/js/resize-observer.js 18.37 kB 0%
static/js/BackgroundImage.js 120.54 kB 0%
static/js/AppliedFilters.js 9.71 kB 0%
static/js/usePayeeRuleCounts.js 10.04 kB 0%
static/js/useTransactionBatchActions.js 13.23 kB 0%
static/js/FormulaEditor.js 1.04 MB 0%

loot-core

Total

Files count Total bundle size % Changed
1 5.82 MB → 5.82 MB (+1.02 kB) +0.02%
Changeset
File Δ Size
home/runner/work/actual/actual/packages/loot-core/src/shared/currencies.ts 📈 +124 B (+2.23%) 5.43 kB → 5.55 kB
home/runner/work/actual/actual/packages/loot-core/src/shared/util.ts 📈 +170 B (+2.17%) 7.67 kB → 7.83 kB
home/runner/work/actual/actual/packages/loot-core/src/server/transactions/transaction-rules.ts 📈 +467 B (+1.81%) 25.25 kB → 25.71 kB
home/runner/work/actual/actual/packages/loot-core/src/server/accounts/app.ts 📈 +185 B (+0.66%) 27.28 kB → 27.46 kB
home/runner/work/actual/actual/packages/loot-core/src/server/budget/schedule-template.ts 📈 +50 B (+0.54%) 9.01 kB → 9.06 kB
home/runner/work/actual/actual/packages/loot-core/src/server/budget/category-template-context.ts 📈 +38 B (+0.16%) 23.49 kB → 23.53 kB
home/runner/work/actual/actual/packages/loot-core/src/server/rules/action.ts 📈 +9 B (+0.10%) 8.83 kB → 8.84 kB
View detailed bundle breakdown

Added

Asset File Size % Changed
kcab.worker.C4PlGq7G.js 0 B → 5.82 MB (+5.82 MB) -

Removed

Asset File Size % Changed
kcab.worker.BwrdDDMW.js 5.82 MB → 0 B (-5.82 MB) -100%

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged
No assets were unchanged


api

Total

Files count Total bundle size % Changed
1 4.43 MB → 4.43 MB (+967 B) +0.02%
Changeset
File Δ Size
src/shared/currencies.ts 📈 +120 B (+2.23%) 5.25 kB → 5.36 kB
src/shared/util.ts 📈 +150 B (+2.20%) 6.66 kB → 6.81 kB
src/server/transactions/transaction-rules.ts 📈 +427 B (+1.86%) 22.43 kB → 22.84 kB
src/server/accounts/app.ts 📈 +177 B (+0.74%) 23.3 kB → 23.48 kB
src/server/budget/schedule-template.ts 📈 +46 B (+0.55%) 8.12 kB → 8.17 kB
src/server/budget/category-template-context.ts 📈 +38 B (+0.18%) 20.99 kB → 21.03 kB
src/server/rules/action.ts 📈 +9 B (+0.11%) 7.83 kB → 7.84 kB
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger

Asset File Size % Changed
bundle.api.js 4.43 MB → 4.43 MB (+967 B) +0.02%

Smaller
No assets were smaller

Unchanged
No assets were unchanged

**Original Pull Request:** https://github.com/actualbudget/actual/pull/6954 **State:** open **Merged:** No --- Sorry for _yet another PR_, but I noticed that Vietnamese Dong got added with the wrong decimal places, due to the longstanding issue with not handling other than 2 decimal places. I originally included sync-server adapter work here, but that was decided to be out of scope, so this PR now focuses on desktop-client + loot-core currency precision only. ## Summary This PR fixes the "everything assumes 2 decimal places" problem. Amounts now use each currency's `decimalPlaces` across account creation, transaction editing/table flows, search/formula paths, and budget-related UI code. This avoids the x10/x100/x1000 inflation issues when using zero-decimal or three-decimal currencies. I also corrected VND metadata to use `decimalPlaces: 0`. **IMPORTANT**: If this is merged and released at the same time as #6902, there will be no db migration needed. If after, a DB migration MAY be needed to fix the 100x issue on existing values. ## Tests added/updated - Added transaction table round-trip tests for: - zero-decimal currencies - three-decimal currencies - existing two-decimal default behavior (`packages/desktop-client/src/components/transactions/table/utils.test.ts`) - Added utility tests for decimal-aware formatting helpers: - `integerToCurrencyWithDecimal` - `appendDecimals` (`packages/loot-core/src/shared/util.test.ts`) - Added E2E coverage for zero-decimal account flows (`JPY`, `VND`): - starting balance remains stable - close-account modal shows the correct balance text (`packages/desktop-client/e2e/accounts.test.ts`) - Updated E2E snapshots for account creation to check that the starting balance bug mentioned in #6902 is fixed. ## Issues addressed This PR is aimed at the non-2-decimal currency requests: - Fixes #325 - Fixes #3255 - Fixes #5748 (Addresses the 3-decimal precision note in [this comment](https://github.com/actualbudget/actual/issues/5748#issuecomment-3313806953).) ## Test plan - [x] `yarn test` - [x] `yarn typecheck` - [x] Manual smoke test with a zero-decimal currency (for example `JPY` / `VND`) ## AI assistance This change was made with the help of GPT-5.3 Codex. <!--- actual-bot-sections ---> <hr /> <!--- bundlestats-action-comment key:combined start ---> ### Bundle Stats Bundle | Files count | Total bundle size | % Changed ------ | ----------- | ----------------- | --------- desktop-client | 27 | 14.85 MB → 14.85 MB (+5.26 kB) | +0.03% loot-core | 1 | 5.82 MB → 5.82 MB (+1.02 kB) | +0.02% api | 1 | 4.43 MB → 4.43 MB (+967 B) | +0.02% <details> <summary>View detailed bundle stats</summary> #### desktop-client **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 27 | 14.85 MB → 14.85 MB (+5.26 kB) | +0.03% <details> <summary>Changeset</summary> File | Δ | Size ---- | - | ---- `src/hooks/useTransactionsSearch.ts` | 📈 +90 B (+9.51%) | 946 B → 1.01 kB `home/runner/work/actual/actual/packages/loot-core/src/shared/util.ts` | 📈 +665 B (+6.99%) | 9.29 kB → 9.93 kB `src/components/modals/TrackingBudgetMenuModal.tsx` | 📈 +198 B (+5.39%) | 3.59 kB → 3.78 kB `src/components/modals/EnvelopeBudgetMenuModal.tsx` | 📈 +198 B (+5.38%) | 3.59 kB → 3.78 kB `src/components/transactions/table/utils.ts` | 📈 +83 B (+4.08%) | 1.99 kB → 2.07 kB `src/components/budget/envelope/CoverMenu.tsx` | 📈 +206 B (+3.85%) | 5.23 kB → 5.43 kB `src/components/mobile/transactions/FocusableAmountInput.tsx` | 📈 +487 B (+3.49%) | 13.63 kB → 14.1 kB `src/queries/index.ts` | 📈 +85 B (+3.18%) | 2.61 kB → 2.7 kB `src/components/modals/CreateLocalAccountModal.tsx` | 📈 +179 B (+2.61%) | 6.7 kB → 6.87 kB `src/components/autocomplete/CategoryAutocomplete.tsx` | 📈 +429 B (+2.42%) | 17.34 kB → 17.76 kB `home/runner/work/actual/actual/packages/loot-core/src/shared/currencies.ts` | 📈 +130 B (+2.24%) | 5.66 kB → 5.79 kB `src/components/modals/EditFieldModal.tsx` | 📈 +160 B (+1.70%) | 9.21 kB → 9.36 kB `src/components/mobile/transactions/TransactionListItem.tsx` | 📈 +214 B (+1.48%) | 14.1 kB → 14.31 kB `src/components/settings/Currency.tsx` | 📈 +311 B (+1.42%) | 21.41 kB → 21.71 kB `src/components/mobile/transactions/TransactionEdit.tsx` | 📈 +764 B (+1.21%) | 61.8 kB → 62.55 kB `src/components/accounts/BalanceHistoryGraph.tsx` | 📈 +111 B (+1.06%) | 10.23 kB → 10.33 kB `src/hooks/useFormulaExecution.ts` | 📈 +87 B (+1.06%) | 8.02 kB → 8.1 kB `src/components/modals/CloseAccountModal.tsx` | 📈 +93 B (+0.76%) | 11.88 kB → 11.97 kB `src/components/transactions/TransactionsTable.tsx` | 📈 +515 B (+0.58%) | 86.2 kB → 86.7 kB `src/components/mobile/transactions/TransactionList.tsx` | 📈 +83 B (+0.41%) | 19.55 kB → 19.64 kB `src/components/modals/ImportTransactionsModal/ImportTransactionsModal.tsx` | 📈 +105 B (+0.36%) | 28.5 kB → 28.6 kB `src/components/accounts/Account.tsx` | 📈 +155 B (+0.30%) | 50.67 kB → 50.82 kB `src/accounts/mutations.ts` | 📈 +38 B (+0.17%) | 21.94 kB → 21.97 kB </details> <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** Asset | File Size | % Changed ----- | --------- | --------- static/js/index.js | 9.54 MB → 9.54 MB (+4.65 kB) | +0.05% static/js/TransactionList.js | 106.22 kB → 106.51 kB (+297 B) | +0.27% static/js/wide.js | 164.15 kB → 164.3 kB (+155 B) | +0.09% static/js/narrow.js | 637.77 kB → 637.86 kB (+90 B) | +0.01% static/js/ReportRouter.js | 1.16 MB → 1.16 MB (+87 B) | +0.01% **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- static/js/indexeddb-main-thread-worker-e59fee74.js | 12.94 kB | 0% static/js/workbox-window.prod.es5.js | 5.64 kB | 0% static/js/ca.js | 188.15 kB | 0% static/js/da.js | 106.35 kB | 0% static/js/de.js | 180.07 kB | 0% static/js/en-GB.js | 7.18 kB | 0% static/js/en.js | 170.37 kB | 0% static/js/es.js | 174.55 kB | 0% static/js/fr.js | 179.6 kB | 0% static/js/it.js | 171.16 kB | 0% static/js/nb-NO.js | 156.96 kB | 0% static/js/nl.js | 106.37 kB | 0% static/js/pl.js | 88.37 kB | 0% static/js/pt-BR.js | 154.22 kB | 0% static/js/th.js | 181.87 kB | 0% static/js/uk.js | 214.74 kB | 0% static/js/resize-observer.js | 18.37 kB | 0% static/js/BackgroundImage.js | 120.54 kB | 0% static/js/AppliedFilters.js | 9.71 kB | 0% static/js/usePayeeRuleCounts.js | 10.04 kB | 0% static/js/useTransactionBatchActions.js | 13.23 kB | 0% static/js/FormulaEditor.js | 1.04 MB | 0% </div> </details> --- #### loot-core **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 1 | 5.82 MB → 5.82 MB (+1.02 kB) | +0.02% <details> <summary>Changeset</summary> File | Δ | Size ---- | - | ---- `home/runner/work/actual/actual/packages/loot-core/src/shared/currencies.ts` | 📈 +124 B (+2.23%) | 5.43 kB → 5.55 kB `home/runner/work/actual/actual/packages/loot-core/src/shared/util.ts` | 📈 +170 B (+2.17%) | 7.67 kB → 7.83 kB `home/runner/work/actual/actual/packages/loot-core/src/server/transactions/transaction-rules.ts` | 📈 +467 B (+1.81%) | 25.25 kB → 25.71 kB `home/runner/work/actual/actual/packages/loot-core/src/server/accounts/app.ts` | 📈 +185 B (+0.66%) | 27.28 kB → 27.46 kB `home/runner/work/actual/actual/packages/loot-core/src/server/budget/schedule-template.ts` | 📈 +50 B (+0.54%) | 9.01 kB → 9.06 kB `home/runner/work/actual/actual/packages/loot-core/src/server/budget/category-template-context.ts` | 📈 +38 B (+0.16%) | 23.49 kB → 23.53 kB `home/runner/work/actual/actual/packages/loot-core/src/server/rules/action.ts` | 📈 +9 B (+0.10%) | 8.83 kB → 8.84 kB </details> <details> <summary>View detailed bundle breakdown</summary> <div> **Added** Asset | File Size | % Changed ----- | --------- | --------- kcab.worker.C4PlGq7G.js | 0 B → 5.82 MB (+5.82 MB) | - **Removed** Asset | File Size | % Changed ----- | --------- | --------- kcab.worker.BwrdDDMW.js | 5.82 MB → 0 B (-5.82 MB) | -100% **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** No assets were unchanged </div> </details> --- #### api **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 1 | 4.43 MB → 4.43 MB (+967 B) | +0.02% <details> <summary>Changeset</summary> File | Δ | Size ---- | - | ---- `src/shared/currencies.ts` | 📈 +120 B (+2.23%) | 5.25 kB → 5.36 kB `src/shared/util.ts` | 📈 +150 B (+2.20%) | 6.66 kB → 6.81 kB `src/server/transactions/transaction-rules.ts` | 📈 +427 B (+1.86%) | 22.43 kB → 22.84 kB `src/server/accounts/app.ts` | 📈 +177 B (+0.74%) | 23.3 kB → 23.48 kB `src/server/budget/schedule-template.ts` | 📈 +46 B (+0.55%) | 8.12 kB → 8.17 kB `src/server/budget/category-template-context.ts` | 📈 +38 B (+0.18%) | 20.99 kB → 21.03 kB `src/server/rules/action.ts` | 📈 +9 B (+0.11%) | 7.83 kB → 7.84 kB </details> <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** Asset | File Size | % Changed ----- | --------- | --------- bundle.api.js | 4.43 MB → 4.43 MB (+967 B) | +0.02% **Smaller** No assets were smaller **Unchanged** No assets were unchanged </div> </details> </details> <!--- bundlestats-action-comment key:combined end --->
GiteaMirror added the pull-request label 2026-02-28 21:33:25 -06:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#6841