2.6.0¶
Released: TBD
Highlights¶
- Tax rates now store the whole percent (
7) instead of the decimal fraction (0.07), so the stored value matches the percent everyone actually reads — and the old "100× under-tax" footgun is gone.
Added¶
TaxRate.rate_fraction— a read-onlyrate / 100view for fraction consumers, the symmetric counterpart torate_percent. See Tax Rate Stored as Percent.scripts/backfill_tax_rate_percent.py— idempotent, dry-run-by-default backfill that multiplies existingtax_rates.raterows by 100.
Changed¶
tax_filings.TaxRate.rateis now a whole percent (7.0000) instead of a decimal fraction (0.0700).rate_percentis now an identity alias ofrate(kept for back-compat). This supersedes the "rate stays the canonical fraction" design in Unify Tax-Rate Models.items.ITBMSTaxRate.rateand the per-lineInvoiceDetail.tax_rate/SupplierInvoiceDetail.tax_ratesnapshots are unchanged — they were already whole percents; the two halves of the in-flight unification now agree.
Fixed¶
- Removes the fraction/percent scale gap on the unified
TaxRatethat made any consumer readingrate(instead ofrate_percent) compute0.07%of the base.
Migrations¶
tax_rate_store_percent(20260619_tax_rate_store_percent.py, down_revisiondrop_employee_bank_account_id) — updates thetax_rates.ratecolumn comment and converts existing rows× 100(idempotent guard0 < rate < 1; covers both existing tenants and fresh tenants seeded as fractions byexpand_unified_tax_rate).- One-off script (optional pre-deploy audit / manual repair):
scripts/backfill_tax_rate_percent.py— same idempotent conversion, dry run by default;--applyto commit,--tenant <id>to scope.
Frontend impact¶
- The gated, accountant-only
taxRatesmanagement surface changes meaning (breaking for callers that send/read the fraction): createTaxRate/updateTaxRateinputratenow expects a whole percent (7for 7%), not0.07.TaxRate.ratein responses now returns the whole percent;TaxRate.ratePercentis unchanged in meaning and now equalsrate.- Item-picker and invoicing surfaces are unaffected — they already consume
ratePercent/ the per-line percent snapshot.
Versioning notes¶
- Bumped with
uv run python scripts/bump_version.py 2.6.0 --changelog-stub. - Deploy order: ship the migration (it converts every tenant automatically);
optionally dry-run
scripts/backfill_tax_rate_percent.pyfirst to preview the change. Frontend callers of thetaxRateswrite/read path must switch to the percent convention in lockstep.