Task: Currency add dialog: Save button stays disabled

Table of Contents

This page documents a task in the Sprint 24 quick bug fixes: currency CRUD, party re-provisioning story. It captures the goal, current status, acceptance, and any notes or results.

Goal

In the Qt client, Reference Data > Currencies > Add opens CurrencyDetailDialog in create mode. Filling in all fields (ISO code, name, numeric code, symbol, fractions per unit, change reason, commentary) does not enable the Save button — it stays disabled and the currency cannot be created. Found while manually testing the generic HistoryDialog widget; unrelated to that change. Repro against main to confirm scope and find the root cause in CurrencyDetailDialog's create-mode dirty/validation tracking.

Status

Field Value
State DONE
Parent story Sprint 24 quick bug fixes: currency CRUD, party re-provisioning
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-07-21

Acceptance

  • Root cause identified in CurrencyDetailDialog's create-mode dirty/validation tracking.
  • Filling in all required fields enables Save; a new currency can be created from the Qt client.

Plan

Root cause: CurrencyDetailDialog::setupConnections() wired every editable widget to the dirty-flag handler (onFieldChanged=/ =onCodeChanged) except the two QSpinBox fields — fractionsPerUnitSpinBox and roundingPrecisionSpinBox — which had no valueChanged connection at all, so editing only those never set hasChanges_ and Save stayed disabled. Traced to a template gap: cpp_qt_detail_dialog.cpp.mustache's connection loop had branches for every other field kind (is_line_edit, is_static_combo, is_dynamic_combo, is_flagged_combo, is_check_box, is_text_edit) but none for is_spin_box — so every generated detail dialog with a spin-box field has the same gap, not just currency.

Fixed the template and regenerated the 23 refdata entities with a spin-box field (out of ~57 total across the app; refdata is the only commissioned component today, so scope stopped there). Regenerating also surfaced a second, unrelated template bug in cpp_qt_client_model.cpp.mustache: its is_int column-rendering case did an unchecked static_cast<qlonglong>, with no is_optional_int branch mirroring the existing is_optional_string one — silently dropping the null case for std::optional<int> columns (surfaced via payment_frequency's period_multiplier). Fixed by adding the missing classification in core.py and the corresponding template branch.

Notes

Manual QA testing of this task's scenario also surfaced a second, genuinely unrelated bug — the currencies list pagination counter/data desync — tracked and fixed separately as Currencies list window paging does not seem to work.

Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario, run through the QA Validation Runner panel) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
Verify Currency Save button enables from spin-box fields PASSED  

PRs

PR Title
#1670 [qt/codegen] Fix currency Save-button and pagination state machines

Review

Comment summary File Decision Notes
       

Result

Fixed at the codegen level rather than hand-patched: added an is_spin_box branch to cpp_qt_detail_dialog.cpp.mustache's setupConnections() loop, wiring QSpinBox::valueChanged to onFieldChanged, and regenerated all 23 refdata entities with a spin-box detail field. Also fixed the is_optional_int gap in cpp_qt_client_model.cpp.mustache=/=core.py uncovered along the way. Full test suite green (382 assertions, 119 cases), SQL schemas validated, and Verify Currency Save button enables from spin-box fields PASSED manually — filling in only the fractions-per-unit or rounding-precision spin box now enables Save, and the create/read/ update/delete/history/eventing round-trip all check out.

Emacs 29.3 (Org mode 9.6.15)