Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p

## [Unreleased]

### Changed

- `catalogues/cef`: the `cef-vatex` extension validates VATEX codes against the pattern `^VATEX-[A-Z]{2}(-[A-Z0-9]+)+$` instead of enumerating the 75 official codes, so that the country codes admitted by national profiles, such as the French `VATEX-FR-CGI*` ones, are accepted. Each profile's schematron checks the codes it allows.

## [v0.503.0] - 2026-07-15

### Added
Expand Down
13 changes: 13 additions & 0 deletions addons/eu/en16931/tax_combo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,19 @@ func TestTaxComboValidation(t *testing.T) {
assert.NoError(t, rules.Validate(c, tax.AddonContext(en16931.V2017)))
})

t.Run("country-extension vatex code passes the catalogue pattern", func(t *testing.T) {
c := &tax.Combo{
Category: tax.CategoryVAT,
Key: tax.KeyExempt,
Ext: tax.ExtensionsOf(cbc.CodeMap{
"cef-vatex": "VATEX-FR-CGI261-1",
}),
}
norm.Normalize(c, tax.AddonContext(en16931.V2017))
err := rules.Validate(c, tax.AddonContext(en16931.V2017))
assert.NoError(t, err)
})

t.Run("reverse charge without vatex", func(t *testing.T) {
c := &tax.Combo{
Category: tax.CategoryVAT,
Expand Down
35 changes: 35 additions & 0 deletions catalogues/cef/cef_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package cef_test

import (
"regexp"
"testing"

_ "github.com/invopop/gobl"
"github.com/invopop/gobl/tax"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestInit(t *testing.T) {
Expand All @@ -14,3 +16,36 @@ func TestInit(t *testing.T) {
assert.NotNil(t, ed)
assert.Equal(t, "cef-vatex", ed.Key.String())
}

func TestVATEXPattern(t *testing.T) {
ed := tax.ExtensionForKey("cef-vatex")
require.NotNil(t, ed)
require.NotEmpty(t, ed.Pattern)
re := regexp.MustCompile(ed.Pattern)

valid := []string{
"VATEX-EU-79-C",
"VATEX-EU-132-1A",
"VATEX-EU-143-1FA",
"VATEX-EU-AE",
"VATEX-FR-FRANCHISE",
"VATEX-SA-34-1",
"VATEX-FR-CGI261-1", // outside the official list
}
for _, code := range valid {
assert.True(t, re.MatchString(code), code)
}

invalid := []string{
"EXEMPT-132",
"VATEX",
"VATEX-EU",
"VATEX-eu-132",
"vatex-EU-132",
"VATEX-E-132",
"VATEX-EU-132-",
}
for _, code := range invalid {
assert.False(t, re.MatchString(code), code)
}
}
Loading
Loading