Skip to content

2.1.0

Released: TBD

Highlights

  • Foundation for one unified tax rate. First (additive, backward-compatible) phase of merging the two tax-rate models so non-accountants eventually pick a single named rate ("ITBMS 7%") and the system derives the percent, the DGI code, and the GL accounts from it. Nothing breaks yet — existing ITBMSTaxRate keeps working. See Unify Tax-Rate Models.

Added

  • TaxRate.displayName / dgiCode / ratePercent. A human label (tenant-editable), the 2-char DGI code (00/01/02/03), and a read-only whole-percent view (rate × 100) so consumers never have to know the fraction convention. Settable on createTaxRate / updateTaxRate (displayName, dgiCode).
  • Item.tax_rate_id — a nullable FK to the canonical tax_filings.TaxRate, added alongside the existing itbms_tax_rate_id. Backfilled for existing items by the migration.
  • Dual-write of Item.tax_rate_id. Item create/update/bulk paths now resolve and set tax_rate_id from the item's ITBMS rate (matched on the DGI code, currently-effective row), so items created after this release also have it populated — not just the migration backfill.

Changed

  • No read-path changes. Item.tax_rate_id is now populated (backfill + dual-write) but not yet consumed — ITBMSTaxRate remains the operational source until the MIGRATE phase.

Fixed

  • None.

Migrations

  • expand_unified_tax_rate (down_revision = rename_tax_rate_account_columns) — adds tax_rates.display_name + tax_rates.dgi_code; backfills the 4 ITBMS sale rates into tax_rates as open-ended rows (idempotent, mapped by the DGI code string — no float-equality risk); adds nullable items.tax_rate_id + FK and backfills it from itbms_tax_rate_id joined on the DGI code. upgrade + downgrade implemented; downgrade leaves the backfilled rate rows in place. GL accounts on the seeded rows are left NULL (enriched in the next phase).

Frontend impact

  • New optional, additive fields are available to read: TaxRate.displayName, TaxRate.dgiCode, TaxRate.ratePercent, and Item.taxRate. Item.taxRate resolves for existing items (migration backfill), newly created items (dual-write), and new tenants (the migration seeds the 4 rate rows for every tenant). Keep itbmsTaxRate as the source of truth for nowtax_rate_id is populated but not yet read by tax math/posting (that's the MIGRATE phase). GL accounts on the seeded rate rows are still NULL (populated in the next phase); posting falls back to client/supplier accounts as today. No breaking changes; nothing must migrate yet.

Versioning notes

  • Bumped with uv run python scripts/bump_version.py 2.1.0 --changelog-stub. MINOR — purely additive (new optional fields, a new nullable column, an additive migration). Phase 1a of the expand/contract rollout in the feature page; the breaking removal of ITBMSTaxRate lands in a later MAJOR (CONTRACT phase).