Skip to content

Commit 61c9a1c

Browse files
committed
Update validators.js
Update isVAT.js Add basic regex support to all countries listed in [VAT identification number - Wikipedia](https://en.wikipedia.org/wiki/VAT_identification_number); More extended validation for PT(Portugal). Update isVAT.js Update isVAT.js Update isVAT.js Update isVAT.js Update isVAT.js Update isVAT.js Update validators.js Update validators.js Update validators.js Update isVAT.js Update isVAT.js Update isVAT.js Update isVAT.js Update isVAT.js Update isVAT.js
1 parent cfcf911 commit 61c9a1c

2 files changed

Lines changed: 936 additions & 20 deletions

File tree

src/lib/isVAT.js

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,109 @@
11
import assertString from './util/assertString';
2+
import * as algorithms from './util/algorithms';
3+
4+
const PT = (str) => {
5+
const match = str.match(/^(PT)?(\d{9})$/);
6+
if (!match) {
7+
return false;
8+
}
9+
10+
const tin = match[2];
11+
12+
const checksum = 11 - (algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 8).map(a => parseInt(a, 10)), 9) % 11);
13+
if (checksum > 9) {
14+
return parseInt(tin[8], 10) === 0;
15+
}
16+
return checksum === parseInt(tin[8], 10);
17+
};
218

319
export const vatMatchers = {
4-
GB: /^GB((\d{3} \d{4} ([0-8][0-9]|9[0-6]))|(\d{9} \d{3})|(((GD[0-4])|(HA[5-9]))[0-9]{2}))$/,
5-
IT: /^(IT)?[0-9]{11}$/,
6-
NL: /^(NL)?[0-9]{9}B[0-9]{2}$/,
20+
/**
21+
* European Union VAT identification numbers
22+
*/
23+
AT: str => /^(AT)?U\d{8}$/.test(str),
24+
BE: str => /^(BE)?\d{10}$/.test(str),
25+
BG: str => /^(BG)?\d{9,10}$/.test(str),
26+
HR: str => /^(HR)?\d{11}$/.test(str),
27+
CY: str => /^(CY)?\w{9}$/.test(str),
28+
CZ: str => /^(CZ)?\d{8,10}$/.test(str),
29+
DK: str => /^(DK)?\d{8}$/.test(str),
30+
EE: str => /^(EE)?\d{9}$/.test(str),
31+
FI: str => /^(FI)?\d{8}$/.test(str),
32+
FR: str => /^(FR)?\w{2}\d{9}$/.test(str),
33+
DE: str => /^(DE)?\d{9}$/.test(str),
34+
EL: str => /^(EL)?\d{9}$/.test(str),
35+
HU: str => /^(HU)?\d{8}$/.test(str),
36+
IE: str => /^(IE)?\d{7}\w{1}(W)?$/.test(str),
37+
IT: str => /^(IT)?\d{11}$/.test(str),
38+
LV: str => /^(LV)?\d{11}$/.test(str),
39+
LT: str => /^(LT)?\d{9,12}$/.test(str),
40+
LU: str => /^(LU)?\d{8}$/.test(str),
41+
MT: str => /^(MT)?\d{8}$/.test(str),
42+
NL: str => /^(NL)?\d{9}B\d{2}$/.test(str),
43+
PL: str => /^(PL)?(\d{10}|(\d{3}-\d{3}-\d{2}-\d{2})|(\d{3}-\d{2}-\d{2}-\d{3}))$/.test(str),
44+
PT,
45+
RO: str => /^(RO)?\d{2,10}$/.test(str),
46+
SK: str => /^(SK)?\d{10}$/.test(str),
47+
SI: str => /^(SI)?\d{8}$/.test(str),
48+
ES: str => /^(ES)?\w\d{7}[A-Z]$/.test(str),
49+
SE: str => /^(SE)?\d{12}$/.test(str),
50+
51+
/**
52+
* VAT numbers of non-EU countries
53+
*/
54+
AL: str => /^(AL)?\w{9}[A-Z]$/.test(str),
55+
MK: str => /^(MK)?\d{13}$/.test(str),
56+
AU: str => /^(AU)?\d{11}$/.test(str),
57+
BY: str => /^(УНП )?\d{9}$/.test(str),
58+
CA: str => /^(CA)?\d{9}$/.test(str),
59+
IS: str => /^(IS)?\d{5,6}$/.test(str),
60+
IN: str => /^(IN)?\d{15}$/.test(str),
61+
ID: str => /^(ID)?(\d{15}|(\d{2}.\d{3}.\d{3}.\d{1}-\d{3}.\d{3}))$/.test(str),
62+
IL: str => /^(IL)?\d{9}$/.test(str),
63+
KZ: str => /^(KZ)?\d{9}$/.test(str),
64+
NZ: str => /^(NZ)?\d{9}$/.test(str),
65+
NG: str => /^(NG)?(\d{12}|(\d{8}-\d{4}))$/.test(str),
66+
NO: str => /^(NO)?\d{9}MVA$/.test(str),
67+
PH: str => /^(PH)?(\d{12}|\d{3} \d{3} \d{3} \d{3})$/.test(str),
68+
RU: str => /^(RU)?(\d{10}|\d{12})$/.test(str),
69+
SM: str => /^(SM)?\d{5}$/.test(str),
70+
SA: str => /^(SA)?\d{15}$/.test(str),
71+
RS: str => /^(RS)?\d{9}$/.test(str),
72+
CH: str => /^(CH)?(\d{6}|\d{9}|(\d{3}.\d{3})|(\d{3}.\d{3}.\d{3}))(TVA|MWST|IVA)$/.test(str),
73+
TR: str => /^(TR)?\d{10}$/.test(str),
74+
UA: str => /^(UA)?\d{12}$/.test(str),
75+
GB: str => /^GB((\d{3} \d{4} ([0-8][0-9]|9[0-6]))|(\d{9} \d{3})|(((GD[0-4])|(HA[5-9]))[0-9]{2}))$/.test(str),
76+
UZ: str => /^(UZ)?\d{9}$/.test(str),
77+
78+
/**
79+
* VAT numbers of Latin American countries
80+
*/
81+
AR: str => /^(AR)?\d{11}$/.test(str),
82+
BO: str => /^(BO)?\d{7}$/.test(str),
83+
BR: str => /^(BR)?((\d{2}.\d{3}.\d{3}\/\d{4}-\d{2})|(\d{3}.\d{3}.\d{3}-\d{2}))$/.test(str),
84+
CL: str => /^(CL)?\d{8}-\d{1}$/.test(str),
85+
CO: str => /^(CO)?\d{10}$/.test(str),
86+
CR: str => /^(CR)?\d{9,12}$/.test(str),
87+
EC: str => /^(EC)?\d{13}$/.test(str),
88+
SV: str => /^(SV)?\d{4}-\d{6}-\d{3}-\d{1}$/.test(str),
89+
GT: str => /^(GT)?\d{7}-\d{1}$/.test(str),
90+
HN: str => /^(HN)?$/.test(str),
91+
MX: str => /^(MX)?\w{3,4}\d{6}\w{3}$/.test(str),
92+
NI: str => /^(NI)?\d{3}-\d{6}-\d{4}\w{1}$/.test(str),
93+
PA: str => /^(PA)?$/.test(str),
94+
PY: str => /^(PY)?\d{6,8}-\d{1}$/.test(str),
95+
PE: str => /^(PE)?\d{11}$/.test(str),
96+
DO: str => /^(DO)?(\d{11}|(\d{3}-\d{7}-\d{1})|[1,4,5]{1}\d{8}|([1,4,5]{1})-\d{2}-\d{5}-\d{1})$/.test(str),
97+
UY: str => /^(UY)?\d{12}$/.test(str),
98+
VE: str => /^(VE)?[J,G,V,E]{1}-(\d{9}|(\d{8}-\d{1}))$/.test(str),
799
};
8100

9101
export default function isVAT(str, countryCode) {
10102
assertString(str);
11103
assertString(countryCode);
12104

13105
if (countryCode in vatMatchers) {
14-
return vatMatchers[countryCode].test(str);
106+
return vatMatchers[countryCode](str);
15107
}
16108
throw new Error(`Invalid country code: '${countryCode}'`);
17109
}

0 commit comments

Comments
 (0)