Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #858 +/- ##
==========================================
+ Coverage 94.76% 94.79% +0.02%
==========================================
Files 343 347 +4
Lines 18754 18894 +140
==========================================
+ Hits 17773 17911 +138
- Misses 597 598 +1
- Partials 384 385 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
samlown
left a comment
There was a problem hiding this comment.
Great PR! A few style changes I think would help.
There was a problem hiding this comment.
Pull request overview
Adds Luxembourg (LU) as a first-class tax regime in GOBL, including VAT rate definitions with historical changes, LU-specific identity validation/normalization, and regime-scoped invoice validation rules, plus examples and regenerated data outputs.
Changes:
- Register new
LUregime and expose it through the global regimes registry. - Implement LU VAT categories (4 rates) with since-dated history (incl. 2023 temporary reduction) and identity validations (TVA mod-89, RCS format).
- Add LU examples (YAML + golden JSON) and regenerate schema/rules/regime JSON, plus a changelog entry.
Reviewed changes
Copilot reviewed 18 out of 22 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
regimes/regimes.go |
Registers the LU regime package via blank import. |
regimes/lu/lu.go |
Defines the LU regime (currency, timezone, corrections, categories, identities) and registers rules/normalizers. |
regimes/lu/tax_categories.go |
Adds LU VAT category with 4 rates and since-dated history (+ sources). |
regimes/lu/tax_identity.go |
Adds LU TVA normalization and mod-89 validation rules. |
regimes/lu/org_identities.go |
Adds LU RCS identity type, normalization, and format validation rules. |
regimes/lu/bill_invoices.go |
Adds LU invoice rule requiring supplier to have either TVA tax ID code or an RCS identity. |
regimes/lu/*_test.go |
Unit tests for LU regime construction, identity normalization/validation, and invoice rule. |
examples/lu/*.yaml |
Adds LU example documents (standard, multi-rate, 2023 historical rate example, credit note). |
examples/lu/out/*.json |
Golden outputs for the LU examples. |
data/schemas/tax/regime-code.json |
Adds LU to the regime-code schema enum. |
data/rules/lu.json |
Generated LU ruleset output. |
data/regimes/lu.json |
Generated LU regime definition output. |
CHANGELOG.md |
Notes the addition of the LU regime. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
samlown
left a comment
There was a problem hiding this comment.
Still a few issues with the approaches for handling test functions: we should be re-using as much as possible.
Luxembourg (LU) applies VAT (Taxe sur la Valeur Ajoutée, TVA) administered by the AED. As an EU member it follows Directive 2006/112/EC. Four rates are defined with full historical data going back to 1992: - Standard (general): 17 % / 16 % (2023 temp) / 17 % / 15 % - Intermediate (parking): 14 % / 13 % (2023 temp) / 14 % / 12 % - Reduced: 8 % / 7 % (2023 temp) / 8 % / 6 % - Super-reduced: 3 % (unchanged since 2015) The 2023 temporary reduction (Law of 30 Nov 2022) is encoded as Since-dated RateValueDef entries, so GOBL automatically picks the correct rate for any invoice date. TVA numbers are validated with a mod-89 check (last two digits of the 8-digit code must equal the first six digits mod 89). RCS numbers (Registre de Commerce et des Sociétés) are supported as an org identity with format [BFGH] + 1–6 digits. Suppliers must carry either a TVA code or an RCS identity on invoices. Four example invoices are included: standard B2B (17 %), multi-rate, a 2023-dated invoice that exercises the historical 16 %/7 % rates, and a credit note. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three corrections after review: - The temporary 2023 rate reduction was enacted by the Law of 26 October 2022 (Mémorial A No. 534), not 30 November 2022. Citation and source URL fixed, and the description now correctly states the super-reduced rate was excluded from the reduction. - RCS validation accepted only [BFGH] section letters, which would have rejected valid registrations such as section A (sole traders) and E (civil companies). Any single uppercase section letter is now accepted: the list of sections has grown over time and the registry is the authority on which exist. Also documented that the RCS number is a registry reference, not a tax identifier — accepting it in place of a TVA code on invoices is a structural baseline for non-VAT-registered businesses, not a legal equivalence. - The 3% super-reduced rate predates 2015 by decades, so its single value is now anchored at the regime's 1992 history baseline instead of 2015. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Run the full `go generate .` to pick up the regime-code schema enum and the data/rules export that the regimes-only generator misses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per CONTRIBUTING.md, the preferred language is English (American). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace is.Func with is.AnyOf for the TVA/RCS assertion and condense the comment to one line. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Split TVA validation into discrete length, digit, and checksum rules so error codes pinpoint the exact failure. Inline the RCS format check using is.MatchesRegexp to remove an unnecessary wrapper. Rework supplier identity rule to only require an RCS identity when no TVA code is present, rather than treating the two as alternatives. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The rules in tax_identity.go and bill_invoices.go were refined after the last `go generate .` run, leaving data/rules/lu.json stale. Regenerate so the JSON reflects the three TVA assertions (length, digits-only, mod-89 checksum), the RCS format regex, and the conditional supplier identities check. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds Luxembourg (
LU) as a new tax regime.What's included
regimes/lu— regime definition following the structure of the recently merged Norway regime (Feat/regime no #849):Since-dated history: standard 17%, intermediate ("parking") 14%, reduced 8%, super-reduced 3%. The history includes the temporary one-point reduction in force throughout 2023 (Law of 26 October 2022, Mémorial A No. 534) — the standard, intermediate, and reduced rates dropped to 16/13/7% and were restored on 2024-01-01; the super-reduced rate was excluded from the measure. An invoice dated within 2023 automatically calculates with the temporary rates.LUprefix, spaces, and dashes.RCS): Luxembourg Business Registers company number, format<section letter> + 1–6 digits(e.g.B263475). Any single uppercase section letter is accepted — the published list of sections (A sole traders, B commercial companies, C GIEs, E civil companies, …) has grown over time, so a closed list risks rejecting valid registrations.examples/lu— four documents with golden outputs: standard B2B invoice (17%), multi-rate invoice (17/8/3%), a 2023-dated invoice demonstrating the historical 16%/7% rates, and a credit note.data/regimes/lu.json,data/rules/lu.json, regime-code schema) and a CHANGELOG entry.Scope decisions
eu-en16931-v2017addon. Alu-*addon would be speculative at this point (pending ViDA).Sources
Structured sources are also embedded in the regime and category definitions.
Pre-Review Checklist
go generate .to ensure that the Schemas and Regime data are up to date.