Skip to content

Add Estonia (EE) tax regime - #871

Open
sandragc8 wants to merge 1 commit into
invopop:mainfrom
sandragc8:add-estonia-regime
Open

Add Estonia (EE) tax regime#871
sandragc8 wants to merge 1 commit into
invopop:mainfrom
sandragc8:add-estonia-regime

Conversation

@sandragc8

Copy link
Copy Markdown

Summary

This PR adds a new tax regime for Estonia (EE). The motivation is the scenario in the assignment: a company already invoicing in one country opens a subsidiary in Estonia, which GOBL did not yet cover.

I used the existing EU regimes (Austria and Ireland) as structural references, since Estonia is an EU member state with a VAT system and the euro.

What's included

  • VAT category with four rates:
    • Standard general rate — 24% (current), with historical values kept so past-dated invoices still resolve: 22% since 2024-01-01 and 20% since 2009-07-01.
    • reduced13% (accommodation services).
    • super-reduced9% (books, press publications, certain medicines).
    • zero0% (exports, intra-community supply).
  • KMKR VAT identity validation (tax_identity.go): EE + 9 digits, validated after the country prefix is stripped during normalization. Includes the mod-10 weighted checksum (weights [3,7,1,3,7,1,3,7]).
  • Credit notes enabled as invoice corrections.
  • Regime registered in regimes/regimes.go, generated data/regimes/ee.json, and a CHANGELOG.md entry.

Tests

  • regimes/ee/tax_identity_test.go — table tests with real valid KMKR numbers and invalid cases (format, length, un-normalized prefix, bad checksum).
  • regimes/ee/ee_test.go — sanity check of the regime definition.
  • The global regimes_test.go validates the new RegimeDef automatically.

Sources

VAT rates and effective dates come from the Estonian Tax and Customs Board (EMTA): https://www.emta.ee/en/business-client/taxes-and-payment/value-added-tax/vat-rates-and-supply-exempt-tax/standard-vat-rate

Scope — what I deliberately left out

To keep the change focused and reviewable, I limited it to what the law requires for correct invoicing, in line with the "minimum complexity for legal correctness" principle:

  • No e-invoicing addon (PEPPOL / national CTC). Estonia supports e-invoicing, but that belongs in a separate addon rather than the base regime.
  • No transitional 20% provisions (cash-accounting / long-term property contracts valid until mid-2025). These depend on time-of-supply rules, not on a standing rate, so modelling them as an active rate would be misleading.
  • No full exemptions catalogue (financial, insurance, real estate). The global VAT keys (exempt, reverse-charge, etc.) already cover the common cases.
  • No live VIES/EMTA lookup for registration status — that's an application-layer concern; the regime validates format and checksum offline, consistent with the other regimes (AT, IE).

Happy to extend any of the above if you'd prefer it in scope.

Add a new tax regime for Estonia covering VAT, following the structure of
the existing EU regimes such as Austria.

- VAT category with standard (24%), reduced (13%), super-reduced (9%) and
  zero rates. The standard rate keeps its historical values (20% from 2009,
  22% from 2024, 24% from 2025) so past-dated invoices resolve correctly.
- KMKR VAT identity validation: 9-digit format plus the mod-10 weighted
  checksum, with the EE prefix stripped during normalization.
- Credit notes enabled for invoice corrections.

Regenerated data/regimes/ee.json and registered the regime in regimes.go.
@sandragc8
sandragc8 force-pushed the add-estonia-regime branch from 534ed50 to dfac148 Compare June 21, 2026 08:59
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.83333% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.76%. Comparing base (166bec4) to head (dfac148).
⚠️ Report is 67 commits behind head on main.

Files with missing lines Patch % Lines
regimes/ee/tax_identity.go 92.85% 1 Missing and 1 partial ⚠️
regimes/ee/ee.go 97.72% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #871      +/-   ##
==========================================
- Coverage   94.76%   94.76%   -0.01%     
==========================================
  Files         343      345       +2     
  Lines       18754    18887     +133     
==========================================
+ Hits        17773    17898     +125     
- Misses        597      601       +4     
- Partials      384      388       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@samlown samlown left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I'd just check the copy in the description, and the rate assignment.

Comment thread regimes/ee/ee.go
Comment on lines +42 to +44
VAT (Käibemaks) is applied to most goods and services. The standard rate
is 24% since 1 July 2025, raised from 22% (in force since 1 January 2024),
which in turn replaced the long-standing 20% rate in force since 2009.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually try to avoid adding rates in the description as they're already defined in the tax categories and may become desynchronised.

},
{
// Higher reduced rate, currently applied to accommodation services.
Rate: tax.RateReduced,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This I think feels more like an "intermediate" rate as opposed to reduced.

},
{
// Lower reduced rate for books, press publications and certain medicines.
Rate: tax.RateSuperReduced,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably "reduced", unless you see evidence for something different.

@samlown

samlown commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

We also lost the PR checklist here.

@samlown samlown added the regime Related to a specific regime. label Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

regime Related to a specific regime.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants