| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-05-06 | 2.7 kB | |
| v2.9.16 -- Finance correctness + currency + notifications + i18n source code.tar.gz | 2026-05-06 | 458.7 MB | |
| v2.9.16 -- Finance correctness + currency + notifications + i18n source code.zip | 2026-05-06 | 460.4 MB | |
| Totals: 3 Items | 919.1 MB | 0 | |
Mostly correctness and reach. No breaking changes; one new column on ProjectBudget (currency_code default "EUR", reversible migration).
Finance correctness
- Decimal precision on dashboard SUMs:
cast(Decimal as Float)replaced withcast(Decimal as Numeric)across all 5 aggregations (invoice ×2, payment, budget ×4). No more silent precision loss past 2^53 cents. - Budget-search crash:
b.wbs_code.toLowerCase()→(b.wbs_id ?? '').toLowerCase()(the API returnswbs_id). - EVM forecast formula: hint corrected to
EAC = AC + (BAC − EV) / CPIto match the service. - TCPI sign flip on over-budget projects: clamped to 0 when remaining budget ≤ 0.
- EVM snapshot wrote zeros:
Create Snapshotnow derives BAC/PV/EV/AC server-side from the actual budget and payments atsnapshot_dateand persists the derived numbers. cancelledadded to invoice status filter.
ProjectBudget currency_code
New String(3) column (default "EUR", NOT NULL) on the budget row, surfaced through schemas + UI. BudgetsTab now renders the row's actual currency instead of always falling back to EUR. Inspector-guarded reversible migration v2916_project_budget_currency.py.
FinanceSummaryCards switched to /dashboard/
Single useQuery(['finance','dashboard',projectId]) replaces three list calls + ~150 lines of FE reduce/coerce. Uses the SQL aggregator that already existed.
Mobile card view for BudgetsTab
8-column budget table forced horizontal scroll on phones. Now stacks cards on <md breakpoints; table reappears at md.
Communication notifications
9 new subscribers wired in notifications/events.py:
rfi.assigned→ assigneerfi.responded→ original requestersubmittal.submitted→ reviewer + project ownersubmittal.approved/rejected/revise_resubmit→ submittertransmittal.issued→ each recipienttransmittal.acknowledged/responded→ original sender
Transmittal events are now actually published (transmittals/service.py had zero _safe_publish calls before). submittal.rejected and submittal.revise_resubmit event names also added so subscribers can fan out cleanly.
i18n — files.* namespace coverage
22 locales backfilled: ar fr es pt zh hi ja got their missing 65–80 keys; tr it nl pl cs ko sv no da fi bg hr id ro th vi gained the full 137-key block. Total ~2 737 strings. All 26 supported locales now have full files.* coverage.
See [CHANGELOG.md](https://github.com/datadrivenconstruction/OpenConstructionERP/blob/v2.9.16/CHANGELOG.md#2916 for the full list.