feat(tax): add Argentina tax pack (official-argentina@1.0.0) - #207
Draft
carvalab wants to merge 4 commits into
Draft
feat(tax): add Argentina tax pack (official-argentina@1.0.0)#207carvalab wants to merge 4 commits into
carvalab wants to merge 4 commits into
Conversation
carvalab
added a commit
to carvalab/FloCafe
that referenced
this pull request
Jul 31, 2026
Pre-existing CI regression surfaced by PR FreeOpenSourcePOS#207. Commit 3a75876 ('publish country packs separately') moved India and Thailand from BUNDLED_COUNTRY_PACKS to catalog-only delivery, and the e2e-server fixture seeds country='TH' without ever simulating the post-first-run owner action of installing Thailand from Settings → Tax Configuration. The active pack for country=TH then falls back to the zero-rules generic pack, and the checkout throws 'no tax rules apply to category standard for business type restaurant' → 400. The Playwright spec at prepaid-payment-reconciliation.spec.ts:13/55 times out waiting for 'Tax ฿4.20'. This is the same regression that has been silently failing the most recent two main CI runs (30614681034, 30619469114) before this PR even opened. Fix by inlining the same install-tax-pack SQL helper that the unit and integration tests already use (tests/helpers/test-setup.ts: installAndActivateTestTaxPack), since e2e-server.cjs runs from compiled dist/ and cannot import the .ts helper. Only Thailand is installed — it's the only country-specific pack actually exercised by e2e specs. No production code touched. India is left catalog-only as 3a75876 intended.
carvalab
force-pushed
the
feat/tax-pack-argentina
branch
2 times, most recently
from
July 31, 2026 18:38
e56310c to
e7a81ac
Compare
Scope (approved before this draft): - Merchant: IVA-registered restaurants (Responsable Inscripto), domestic sales of standard supplies. - Tax: one IVA rule at the general rate of 21%, applied across every category (product, addon, packaging, delivery, service_charge, unclassified). - Default pricing is tax-inclusive to match Argentina's consumer- price-display rule (Res. 4/2025); individual products can still be set exclusive per-item for B2B use. Source: Ley de Impuesto al Valor Agregado, texto ordenado en 1997 (Ley 23.349 t.o. Decreto 280/1997, Anexo I), Articulo 28 -- 'La alicuota del impuesto sera del veintiuno por ciento (21%)'. Continuously in force since BO 15/04/1997. Cross-references: ARCA biblioteca cuadro legislativo Articulo 28; InfoLeg norma 42701. Intentionally unsupported (do not add to this pack without a scope bump): IIBB (provincial, registration-dependent); reduced 10.5%; incremented 27% (utilities); 2.5% and 0%; Monotributo; withholding and perception regimes; ARCA CAE fiscal-invoice authorization (belongs to the capability-plugin seam FreeOpenSourcePOS#142). Tests: - tests/tax-engine.test.ts: ARS 100 exclusive -> 21 -> 121; ARS 121 inclusive -> net 100 / IVA 21; all charge kinds apply the rule; unclassified never silently zero. - tests/tax-pack-management.test.ts: installs AR alongside IN/TH and confirms the 24-point activation checklist accepts it (only check FreeOpenSourcePOS#6, signed artifact, fails pre-signing, same as IN/TH seeds). - tests/integration-tax.test.ts: AR exclusive order (ARS 1000 -> 210 IVA -> 1210 total); 20% discount recompute (168/968); inclusive product keeps IVA inside the displayed price and persists behavior as inclusive; bill copies the order tax; every breakdown asserted to contain no IIBB/Ingresos Brutos component. Docs: docs/tax-packs.md gains a 'Country pack scopes' section pinning the approved merchant scope, the IVA source, every excluded area, and the upgrade path for provincial IIBB (only after FloCafe models province + activity code + customer registration status).
Pre-existing CI regression, included here to keep this PR's CI green. Logically belongs to commit 3a75876 ('publish country packs separately'), not to the Argentina pack. 3a75876 moved India and Thailand from BUNDLED_COUNTRY_PACKS to catalog-only delivery. tests/e2e-server.cjs seeds country='TH' without simulating the post-first-run owner action of installing Thailand from Settings -> Tax Configuration. The active pack for country=TH then falls back to the zero-rules generic pack, and checkout throws 'no tax rules apply to category standard for business type restaurant' (400). The Playwright spec at prepaid-payment-reconciliation.spec.ts:13/55 times out waiting for 'Tax ฿4.20'. Same regression silently failed the most recent two main CI runs (30614681034, 30619469114) before this PR opened. Fix: inline the same install-tax-pack SQL helper that the unit and integration tests already use (tests/helpers/test-setup.ts: installAndActivateTestTaxPack), since e2e-server.cjs runs from compiled dist/ and cannot import the .ts helper. Only Thailand is installed -- the only country-specific pack exercised by e2e specs. India stays catalog-only as 3a75876 intended. No production code touched.
User feedback: the 21% IVA is what the end consumer pays at the counter, which is roughly 99% of restaurant POS transactions. The previous scope text led with 'IVA-registered restaurants operating as Responsable Inscripto', which framed the pack around the merchant's tax-status instead of the consumer-facing calculation the pack actually models. The pack's calculation is identical for end-consumer sales (Factura B, IVA embedded) and B2B sales between Responsables Inscriptos (Factura A, IVA itemized) -- same 21% number, different invoice presentation. That makes Factura A in-scope too, just framed as a side note about invoicing rather than as a scope restriction. The Monotributo exclusion is reworded to clarify that a Monotributo merchant would need a separate zero-IVA pack variant because its invoicing and registration paths are structurally different, not because the math is incompatible. No rate change, no rule change, no test change. Pack data, pack activation, all tests still green. Docs only.
carvalab
force-pushed
the
feat/tax-pack-argentina
branch
from
July 31, 2026 22:31
86c7de3 to
6dc4ef8
Compare
Adds a single-bar 'Default for all' control in the fiscal settings panel that lets the owner pick a category for every kind (product, add-on, packaging, delivery, service charge) and apply it in one click. The control also accepts a typed rate (e.g. 10.5) and creates a merchant category with that rate when the value doesn't match an existing one. Per-kind dropdowns below stay for exceptions. Backend: `POST /api/tax-packs/merchant-rate` (owner-only, validated 0 < rate <= 100) upserts a `merchant:<rate>` category + rule for the active version and writes the 5 store-wide overrides in one transaction. Idempotent. `getActiveCountryPack` merges merchant rows into the returned pack so the engine resolves them. Activate copies merchant categories and rules across versions; the install-time override-conflict check ignores `merchant:%` aliases.
carvalab
force-pushed
the
feat/tax-pack-argentina
branch
from
July 31, 2026 23:09
6dc4ef8 to
e970c0c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a signed-JSON tax pack for Argentina. Data only, no executable tax code.
Scope (approved before this draft):
Source: Ley 23.349 t.o. Decreto 280/1997 Art. 28 ("La alicuota del impuesto sera del veintiuno por ciento (21%)"), in force since BO 15/04/1997. Cross-checked against ARCA biblioteca, InfoLeg norma 42701, and the Avalara Argentina VAT guide.
Explicitly out of scope (also documented in docs/tax-packs.md under Country pack scopes, Argentina):
Tests:
Docs:
I verified locally: npm run lint, npm run build, npm run build:frontend, npm run test:tax-engine, npm test, git diff --check all clean. Test totals: tax-engine 12/12, Integration Tax 114/114, Tax Pack Management 103/103.
Publishing (tag, push to upstream, CI sign) is not in this PR. That step stays gated on maintainer review per the task spec; I did not touch either signing secret.