eu-vat-validation
Version:
A VAT number validation class
88 lines (80 loc) • 3.64 kB
JavaScript
import CountryVATCheckers from "./CountryVATCheckers";
export default class VatValidator {
constructor(defaultVatCode = "DE") {
this.defaultVatCode = defaultVatCode;
}
validate(toCheck) {
// To change the default country (e.g. from the UK to Germany - DE):
// 1. Change the country code in the defCCode variable below to "DE".
// 2. Remove the question mark from the regular expressions associated with the UK VAT number:
// i.e. "(GB)?" -> "(GB)"
// 3. Add a question mark into the regular expression associated with Germany's number
// following the country code: i.e. "(DE)" -> "(DE)?"
const defCCode = this.defaultVatCode;
// Note - VAT codes without the "**" in the comment do not have check digit checking.
const vatexp = [
/^(AT)U(\d{8})$/, //** Austria
/^(BE)(0?\d{9})$/, //** Belgium
/^(BG)(\d{9,10})$/, //** Bulgaria
/^(CHE)(\d{9})(MWST|TVA|IVA)?$/, //** Switzerland
/^(CY)([0-59]\d{7}[A-Z])$/, //** Cyprus
/^(CZ)(\d{8,10})(\d{3})?$/, //** Czech Republic
/^(DE)([1-9]\d{8})$/, //** Germany
/^(DK)(\d{8})$/, //** Denmark
/^(EE)(10\d{7})$/, //** Estonia
/^(EL)(\d{9})$/, //** Greece
/^(ES)([A-Z]\d{8})$/, //** Spain (National juridical entities)
/^(ES)([A-HN-SW]\d{7}[A-J])$/, //** Spain (Other juridical entities)
/^(ES)([0-9YZ]\d{7}[A-Z])$/, //** Spain (Personal entities type 1)
/^(ES)([KLMX]\d{7}[A-Z])$/, //** Spain (Personal entities type 2)
/^(EU)(\d{9})$/, //** EU-type
/^(FI)(\d{8})$/, //** Finland
/^(FR)(\d{11})$/, //** France (1)
/^(FR)([A-HJ-NP-Z]\d{10})$/, // France (2)
/^(FR)(\d[A-HJ-NP-Z]\d{9})$/, // France (3)
/^(FR)([A-HJ-NP-Z]{2}\d{9})$/, // France (4)
/^(GB)?(\d{9})$/, //** UK (Standard)
/^(GB)?(\d{12})$/, //** UK (Branches)
/^(GB)?(GD\d{3})$/, //** UK (Government)
/^(GB)?(HA\d{3})$/, //** UK (Health authority)
/^(HR)(\d{11})$/, //** Croatia
/^(HU)(\d{8})$/, //** Hungary
/^(IE)(\d{7}[A-W])$/, //** Ireland (1)
/^(IE)([7-9][A-Z\*\+)]\d{5}[A-W])$/, //** Ireland (2)
/^(IE)(\d{7}[A-W][AH])$/, //** Ireland (3)
/^(IT)(\d{11})$/, //** Italy
/^(LV)(\d{11})$/, //** Latvia
/^(LT)(\d{9}|\d{12})$/, //** Lithunia
/^(LU)(\d{8})$/, //** Luxembourg
/^(MT)([1-9]\d{7})$/, //** Malta
/^(NL)(\d{9})B\d{2}$/, //** Netherlands
/^(NO)(\d{9})$/, //** Norway (not EU)
/^(PL)(\d{10})$/, //** Poland
/^(PT)(\d{9})$/, //** Portugal
/^(RO)([1-9]\d{1,9})$/, //** Romania
/^(RU)(\d{10}|\d{12})$/, //** Russia
/^(RS)(\d{9})$/, //** Serbia
/^(SI)([1-9]\d{7})$/, //** Slovenia
/^(SK)([1-9]\d[2346-9]\d{7})$/, //** Slovakia Republic
/^(SE)(\d{10}01)$/ //** Sweden
];
// Load up the string to check
let VATNumber = toCheck.toUpperCase();
// Remove spaces etc. from the VAT number to help validation
VATNumber = VATNumber.replace(/(\s|-|\.)+/g, "");
const countryVatCheckers = new CountryVATCheckers();
return vatexp
.filter(regexp => regexp.test(VATNumber))
.map(regexp => {
regexp.test(VATNumber);
let cCode = RegExp.$1; // Isolate country code
const cNumber = RegExp.$2; // Isolate the number
if (cCode.length === 0) {
cCode = defCCode;
} // Set up default country code
// Call the appropriate country VAT validation routine depending on the country code
return countryVatCheckers[`${cCode}VATCheckDigit`](cNumber);
})
.reduce((memo, isValid) => isValid, false);
}
}