Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

jsvat

Package Overview
Dependencies
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsvat - npm Package Compare versions

Comparing version 0.6.1 to 0.9.0

build/config.js

9

bower.json
{
"name": "jsvat",
"version": "0.6.1",
"version": "0.9.0",
"description": "Check the validity of the format of an EU VAT number",

@@ -17,4 +17,7 @@ "main": "./dist/jsvat.js",

},
"ignore": {
},
"ignore": [
".bithoundrc",
".log",
".travis.yml"
],
"keywords": [

@@ -21,0 +24,0 @@ "jsvat",

@@ -1,176 +0,7 @@

var jsvat = (function () {
var jsvat = (function() {
'use strict';
var CONDITIONS = {
austria: {
multipliers: [1, 2, 1, 2, 1, 2, 1],
regex: /^(AT)U(\d{8})$/
},
belgium: {
regex: /^(BE)(0?\d{9})$/
},
bulgaria: {
multipliers: {
physical: [2, 4, 8, 5, 10, 9, 7, 3, 6],
foreigner: [21, 19, 17, 13, 11, 9, 7, 3, 1],
miscellaneous: [4, 3, 2, 7, 6, 5, 4, 3, 2]
},
regex: /^(BG)(\d{9,10})$/
},
switzerland: {
multipliers: [5, 4, 3, 2, 7, 6, 5, 4],
regex: /^(CHE)(\d{9})(MWST)?$/
},
cyprus: {
regex: /^(CY)([0-59]\d{7}[A-Z])$/
},
czech_republic: {
multipliers: [8, 7, 6, 5, 4, 3, 2],
lookup: [8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 10],
regex: /^(CZ)(\d{8,10})(\d{3})?$/,
additional: [
/^\d{8}$/,
/^[0-5][0-9][0|1|5|6]\d[0-3]\d\d{3}$/,
/^6\d{8}$/,
/^\d{2}[0-3|5-8]\d[0-3]\d\d{4}$/
]
},
germany: {
regex: /^(DE)([1-9]\d{8})$/
},
denmark: {
multipliers: [2, 7, 6, 5, 4, 3, 2, 1],
regex: /^(DK)(\d{8})$/
},
estonia: {
multipliers: [3, 7, 1, 3, 7, 1, 3, 7],
regex: /^(EE)(10\d{7})$/
},
greece: {
multipliers: [256, 128, 64, 32, 16, 8, 4, 2],
regex: /^(EL)(\d{9})$/
},
spain: {
multipliers: [2, 1, 2, 1, 2, 1, 2],
regex: [
/^(ES)([A-Z]\d{8})$/,
/^(ES)([A-HN-SW]\d{7}[A-J])$/,
/^(ES)([0-9YZ]\d{7}[A-Z])$/,
/^(ES)([KLMX]\d{7}[A-Z])$/
],
additional: [
/^[A-H|J|U|V]\d{8}$/,
/^[A-H|N-S|W]\d{7}[A-J]$/,
/^[0-9|Y|Z]\d{7}[A-Z]$/,
/^[K|L|M|X]\d{7}[A-Z]$/
]
},
europe: {
regex: /^(EU)(\d{9})$/
},
finland: {
multipliers: [7, 9, 10, 5, 8, 4, 2],
regex: /^(FI)(\d{8})$/
},
france: {
regex: [
/^(FR)(\d{11})$/,
/^(FR)([A-HJ-NP-Z]\d{10})$/,
/^(FR)(\d[A-HJ-NP-Z]\d{9})$/,
/^(FR)([A-HJ-NP-Z]{2}\d{9})$/
]
var COUNTRIES = {};
},
united_kingdom: {
multipliers: [8, 7, 6, 5, 4, 3, 2],
regex: [
/^(GB)?(\d{9})$/,
/^(GB)?(\d{12})$/,
/^(GB)?(GD\d{3})$/,
/^(GB)?(HA\d{3})$/
]
},
croatia: {
regex: /^(HR)(\d{11})$/
},
hungary: {
multipliers: [9, 7, 3, 1, 9, 7, 3],
regex: /^(HU)(\d{8})$/
},
ireland: {
multipliers: [8, 7, 6, 5, 4, 3, 2],
regex: [
/^(IE)(\d{7}[A-W])$/,
/^(IE)([7-9][A-Z\*\+)]\d{5}[A-W])$/,
/^(IE)(\d{7}[A-W][AH])$/
]
},
italy: {
multipliers: [1, 2, 1, 2, 1, 2, 1, 2, 1, 2],
regex: /^(IT)(\d{11})$/
},
latvia: {
multipliers: [9, 1, 4, 8, 3, 10, 2, 5, 7, 6],
regex: /^(LV)(\d{11})$/
},
lithunia: {
multipliers: {
short: [3, 4, 5, 6, 7, 8, 9, 1],
med: [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2],
alt: [3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4]
},
regex: /^(LT)(\d{9}|\d{12})$/
},
luxembourg: {
regex: /^(LU)(\d{8})$/
},
malta: {
multipliers: [3, 4, 6, 7, 8, 9],
regex: /^(MT)([1-9]\d{7})$/
},
netherlands: {
multipliers: [9, 8, 7, 6, 5, 4, 3, 2],
regex: /^(NL)(\d{9})B\d{2}$/
},
norway: {
multipliers: [3, 2, 7, 6, 5, 4, 3, 2],
regex: /^(NO)(\d{9})$/
},
poland: {
multipliers: [6, 5, 7, 2, 3, 4, 5, 6, 7],
regex: /^(PL)(\d{10})$/
},
portugal: {
multipliers: [9, 8, 7, 6, 5, 4, 3, 2],
regex: /^(PT)(\d{9})$/
},
romania: {
multipliers: [7, 5, 3, 2, 1, 7, 5, 3, 2],
regex: /^(RO)([1-9]\d{1,9})$/
},
russia: {
multipliers: {
m_1: [2, 4, 10, 3, 5, 9, 4, 6, 8, 0],
m_2: [7, 2, 4, 10, 3, 5, 9, 4, 6, 8, 0],
m_3: [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8, 0]
},
regex: /^(RU)(\d{10}|\d{12})$/
},
serbia: {
regex: /^(RS)(\d{9})$/
},
slovenia: {
multipliers: [8, 7, 6, 5, 4, 3, 2],
regex: /^(SI)([1-9]\d{7})$/
},
slovakia_republic: {
regex: /^(SK)([1-9]\d[2346-9]\d{7})$/
},
sweden: {
regex: /^(SE)(\d{10}01)$/
}
};
function _validateRegex(vat, regex) {

@@ -182,8 +13,5 @@ return regex.test(vat);

var parsedNum = regex.exec(vat);
var vatNum = parsedNum[2];
//var code = parsedNum[1];
var number = parsedNum[2];
//if (!code || code.length === 0) code = 'GB';
return _checks[countryName](number, countryName);
return COUNTRIES[countryName].calcs(vatNum);
}

@@ -199,34 +27,83 @@

function getClearVAT(vat) {
return vat.toString().toUpperCase().replace(/(\s|-|\.)+/g, '');
}
function _makeArr(regex) {
//TODO (S.Panfilov) this is not cross-browser check
if (!Array.isArray(regex)) {
return [regex];
}
return regex;
}
function isCountryBlocked(config, countryName) {
if (!config || Object.keys(config).length === 0) return false; //TODO (S.Panfilov) Object.keys didn't supports by old browsers
var country = config[countryName];
return (country === null || country === undefined) ? true : !country;
}
var exports = {
checkVAT: function (vat) {
config: {},
checkVAT: function(vat, isDetailed) {
if (!vat) return false;
vat = vat.toString().toUpperCase().replace(/(\s|-|\.)+/g, '');
for (var countryName in CONDITIONS) {
if (CONDITIONS.hasOwnProperty(countryName)) {
var regex = CONDITIONS[countryName].regex;
vat = getClearVAT(vat);
//TODO (S.Panfilov) this is not cross-browser check
if (Array.isArray(regex)) {
for (var i = 0; i < regex.length; i++) {
if (_validate(vat, regex[i], countryName)) return true;
var result = {
isValid: false,
countries: []
};
for (var countryName in COUNTRIES) {
if (COUNTRIES.hasOwnProperty(countryName)) {
//Make sure country check not skipped in config
if (!isCountryBlocked(exports.config, countryName)) {
var regexArr = _makeArr(COUNTRIES[countryName].rules.regex);
for (var i = 0; i < regexArr.length; i++) {
//If once become a true, shouldn't be a false any more
result.isValid = (_validate(vat, regexArr[i], countryName)) ? true : result.isValid;
if (!isDetailed && result.isValid) return result.isValid;
var isValidForCurrCountry = _validate(vat, regexArr[i], countryName);
if (isValidForCurrCountry) {
result.countries.push(countryName);
}
// if (result.isValid) {
// //If not detailed just return bool and exit
// if (!isDetailed) {
// return result.isValid
// }
// else {
// //if detailed, should fill array of countries
// result.push(countryName);
// }
}
} else {
if (_validate(vat, regex, countryName)) return true;
}
}
}
return false;
return isDetailed ? result : result.isValid;
}
};
COUNTRIES.austria = {
calcs: function(vat) {
var total = 0;
var temp;
var expect;
var expect;
var temp;
var _checks = {
austria: function (vat, countryName) {
var total = 0;
for (var i = 0; i < 7; i++) {
temp = vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
temp = vat.charAt(i) * this.rules.multipliers[i];
if (temp > 9)

@@ -245,3 +122,19 @@ total += Math.floor(temp / 10) + temp % 10;

},
belgium: function (vat) {
rules: {
multipliers: [
1,
2,
1,
2,
1,
2,
1
],
regex: /^(AT)U(\d{8})$/
}
};
COUNTRIES.belgium = {
calcs: function(vat) {
var expect;
if (vat.length === 9) {

@@ -257,96 +150,78 @@ vat = '0' + vat;

},
bulgaria: function (vat, countryName) {
var checkNineLengthVat = function () {
var total =0;
temp = 0;
for (var i = 0; i < 8; i++) {
temp += +vat.charAt(i) * (i + 1);
}
rules: {
regex: /^(BE)(0?\d{9})$/
}
};
COUNTRIES.bulgaria = (function() {
total = temp % 11;
if (total !== 10) {
expect = +vat.slice(8);
return total === expect;
}
function _checkNineLengthVat(vat) {
var total;
var temp = 0;
var expect;
temp = 0;
for (var j = 0; j < 8; j++) {
temp += +vat.charAt(j) * (j + 3);
}
for (var i = 0; i < 8; i++) {
temp += +vat.charAt(i) * (i + 1);
}
total = temp % 11;
if (total === 10) total = 0;
total = temp % 11;
if (total !== 10) {
expect = +vat.slice(8);
return total === expect;
};
}
var isPhysicalPerson = function () {
var total = 0;
// 10 digit VAT code - see if it relates to a standard physical person
if ((/^\d\d[0-5]\d[0-3]\d\d{4}$/).test(vat)) {
// Check month
var month = +vat.slice(2, 4);
if ((month > 0 && month < 13) || (month > 20 && month < 33) || (month > 40 && month < 53)) {
temp = 0;
for (var j = 0; j < 8; j++) {
temp += +vat.charAt(j) * (j + 3);
}
total = 0;
for (var k = 0; k < 9; k++) {
total += +vat.charAt(k) * CONDITIONS[countryName].multipliers.physical[k];
}
// Establish check digit.
total = total % 11;
if (total === 10) total = 0;
total = temp % 11;
if (total === 10) total = 0;
expect = +vat.slice(8);
// Check to see if the check digit given is correct, If not, try next type of person
if (total === +vat.substr(9, 1)) return true;
}
}
return total === expect;
}
return false;
function _isPhysicalPerson(vat, rules) {
var total = 0;
// 10 digit VAT code - see if it relates to a standard physical person
if ((/^\d\d[0-5]\d[0-3]\d\d{4}$/).test(vat)) {
// Check month
var month = +vat.slice(2, 4);
if ((month > 0 && month < 13) || (month > 20 && month < 33) || (month > 40 && month < 53)) {
};
total = 0;
for (var i = 0; i < 9; i++) {
total += +vat.charAt(i) * rules.multipliers.physical[i];
}
// Establish check digit.
total = total % 11;
if (total === 10) total = 0;
// It doesn't relate to a standard physical person - see if it relates to a foreigner.
var isForeigner = function () {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var l = 0; l < 9; l++) {
total += +vat.charAt(l) * CONDITIONS[countryName].multipliers.foreigner[l];
// Check to see if the check digit given is correct, If not, try next type of person
if (total === +vat.substr(9, 1)) return true;
}
}
// Check to see if the check digit given is correct, If not, try next type of person
if (total % 10 === +vat.substr(9, 1)) {
return true;
}
};
return false;
}
var miscellaneousVAT = function () {
var total = 0;
// Finally, if not yet identified, see if it conforms to a miscellaneous VAT number
function _isForeigner(vat, rules) {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 9; i++) {
total += +vat.charAt(i) * rules.multipliers.foreigner[i];
}
for (var m = 0; m < 9; m++) {
total += +vat.charAt(m) * CONDITIONS[countryName].multipliers.miscellaneous[m];
}
// Establish check digit.
total = 11 - total % 11;
if (total === 10) return false;
if (total === 11) total = 0;
// Check to see if the check digit given is correct, If not, we have an error with the VAT number
expect = +vat.substr(9, 1);
return total === expect;
};
if (vat.length === 9) {
return checkNineLengthVat();
} else {
return isPhysicalPerson() || isForeigner() || miscellaneousVAT();
// Check to see if the check digit given is correct, If not, try next type of person
if (total % 10 === +vat.substr(9, 1)) {
return true;
}
}
},
switzerland: function (vat, countryName) {
function _miscellaneousVAT(vat, rules) {
var total = 0;
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
// Finally, if not yet identified, see if it conforms to a miscellaneous VAT number
for (var i = 0; i < 9; i++) {
total += +vat.charAt(i) * rules.multipliers.miscellaneous[i];
}

@@ -360,7 +235,88 @@

// Check to see if the check digit given is correct, If not, we have an error with the VAT number
expect = +vat.substr(8, 1);
var expect = +vat.substr(9, 1);
return total === expect;
}
return {
calcs: function(vat) {
if (vat.length === 9) {
return _checkNineLengthVat(vat);
} else {
return _isPhysicalPerson(vat, this.rules) || _isForeigner(vat, this.rules) || _miscellaneousVAT(vat, this.rules);
}
},
rules: {
multipliers: {
physical: [
2,
4,
8,
5,
10,
9,
7,
3,
6
],
foreigner: [
21,
19,
17,
13,
11,
9,
7,
3,
1
],
miscellaneous: [
4,
3,
2,
7,
6,
5,
4,
3,
2
]
},
regex: /^(BG)(\d{9,10})$/
}
};
})();
COUNTRIES.croatia = {
calcs: function(vat) {
var expect;
// Checks the check digits of a Croatian VAT number using ISO 7064, MOD 11-10 for check digit.
var product = 10;
var sum = 0;
for (var i = 0; i < 10; i++) {
// Extract the next digit and implement the algorithm
sum = (+vat.charAt(i) + product) % 10;
if (sum === 0) {
sum = 10;
}
product = (2 * sum) % 11;
}
// Now check that we have the right check digit
expect = +vat.slice(10, 11);
return (product + expect) % 10 === 1;
},
cyprus: function (vat) {
rules: {
regex: /^(HR)(\d{11})$/
}
};
COUNTRIES.cyprus = {
calcs: function(vat) {
var total = 0;
var expect;
// Not allowed to start with '12'

@@ -405,11 +361,15 @@ if (+vat.slice(0, 2) === 12) return false;

},
czech_republic: function (vat, countryName) {
rules: {
regex: /^(CY)([0-59]\d{7}[A-Z])$/
}
};
COUNTRIES.czech_republic = (function() {
function _isLegalEntities(vat, rules) {
var total = 0;
// Legal entities
if (CONDITIONS[countryName].additional[0].test(vat)) {
if (rules.additional[0].test(vat)) {
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * rules.multipliers[i];
}

@@ -423,12 +383,17 @@

// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(7, 8);
var expect = +vat.slice(7, 8);
return total === expect;
}
// Individuals type 2
else if (CONDITIONS[countryName].additional[2].test(vat)) {
return false;
}
function _isIndividualType2(vat, rules) {
var total = 0;
if (rules.additional[2].test(vat)) {
// Extract the next digit and multiply by the counter.
for (var j = 0; j < 7; j++) {
total += +vat.charAt(j + 1) * CONDITIONS[countryName].multipliers[j];
total += +vat.charAt(j + 1) * rules.multipliers[j];
}

@@ -442,50 +407,67 @@

// Convert calculated check digit according to a lookup table;
expect = +vat.slice(8, 9);
return CONDITIONS[countryName].lookup[total - 1] === expect;
var expect = +vat.slice(8, 9);
return rules.lookup[total - 1] === expect;
}
// Individuals type 3
else if (CONDITIONS[countryName].additional[3].test(vat)) {
return false;
}
function _isIndividualType3(vat, rules) {
if (rules.additional[3].test(vat)) {
var temp = +vat.slice(0, 2) + vat.slice(2, 4) + vat.slice(4, 6) + vat.slice(6, 8) + vat.slice(8);
expect = +vat % 11 === 0;
var expect = +vat % 11 === 0;
return !!(temp % 11 === 0 && expect);
}
// else error
return false;
},
germany: function (vat) {
}
return {
calcs: function(vat) {
// Checks the check digits of a German VAT number.
if (_isLegalEntities(vat, this.rules)) return true;
if (_isIndividualType2(vat, this.rules)) return true;
if (_isIndividualType3(vat, this.rules)) return true;
var product = 10;
var sum = 0;
var checkDigit = 0;
for (var i = 0; i < 8; i++) {
// Extract the next digit and implement peculiar algorithm!.
sum = (+vat.charAt(i) + product) % 10;
if (sum === 0) {
sum = 10;
}
product = (2 * sum) % 11;
return false;
},
rules: {
multipliers: [
8,
7,
6,
5,
4,
3,
2
],
"lookup": [
8,
7,
6,
5,
4,
3,
2,
1,
0,
9,
10
],
regex: /^(CZ)(\d{8,10})(\d{3})?$/,
additional: [
/^\d{8}$/,
/^[0-5][0-9][0|1|5|6]\d[0-3]\d\d{3}$/,
/^6\d{8}$/,
/^\d{2}[0-3|5-8]\d[0-3]\d\d{4}$/
]
}
}
})();
COUNTRIES.denmark = {
calcs: function(vat) {
var total = 0;
// Establish check digit.
if (11 - product === 10) {
checkDigit = 0;
} else {
checkDigit = 11 - product;
}
// Compare it with the last two characters of the VAT number. If the same, then it is a valid
// check digit.
expect = +vat.slice(8, 9);
return checkDigit === expect;
},
denmark: function (vat, countryName) {
var total = 0;
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}

@@ -495,7 +477,24 @@

},
estonia: function (vat, countryName) {
rules: {
multipliers: [
2,
7,
6,
5,
4,
3,
2,
1
],
regex: /^(DK)(\d{8})$/
}
};
COUNTRIES.estonia = {
calcs: function(vat) {
var total = 0;
var expect;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}

@@ -511,90 +510,18 @@

},
greece: function (vat, countryName) {
var total = 0;
//eight character numbers should be prefixed with an 0.
if (vat.length === 8) {
vat = '0' + vat;
}
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
// Establish check digit.
total = total % 11;
if (total > 9) {
total = 0;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(8, 9);
return total === expect;
},
spain: function (vat, countryName) {
var i = 0;
var total = 0;
// National juridical entities
if (CONDITIONS[countryName].additional[0].test(vat)) {
// Extract the next digit and multiply by the counter.
for (i = 0; i < 7; i++) {
temp = vat.charAt(i + 1) * CONDITIONS[countryName].multipliers[i];
if (temp > 9)
total += Math.floor(temp / 10) + temp % 10;
else
total += temp;
}
// Now calculate the check digit itself.
total = 10 - total % 10;
if (total === 10) {
total = 0;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(8, 9);
return total === expect;
}
// Juridical entities other than national ones
else if (CONDITIONS[countryName].additional[1].test(vat)) {
// Extract the next digit and multiply by the counter.
for (i = 0; i < 7; i++) {
temp = vat.charAt(i + 1) * CONDITIONS[countryName].multipliers[i];
if (temp > 9)
total += Math.floor(temp / 10) + temp % 10;
else
total += temp;
}
// Now calculate the check digit itself.
total = 10 - total % 10;
total = String.fromCharCode(total + 64);
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = vat.slice(8, 9);
return total === expect;
}
// Personal number (NIF) (starting with numeric of Y or Z)
else if (CONDITIONS[countryName].additional[2].test(vat)) {
var tempnumber = vat;
if (tempnumber.substring(0, 1) === 'Y') tempnumber = tempnumber.replace(/Y/, '1');
if (tempnumber.substring(0, 1) === 'Z') tempnumber = tempnumber.replace(/Z/, '2');
expect = 'TRWAGMYFPDXBNJZSQVHLCKE'.charAt(+tempnumber.substring(0, 8) % 23);
return tempnumber.charAt(8) === expect;
}
// Personal number (NIF) (starting with K, L, M, or X)
else if (CONDITIONS[countryName].additional[3].test(vat)) {
expect = 'TRWAGMYFPDXBNJZSQVHLCKE'.charAt(+vat.substring(1, 8) % 23);
return vat.charAt(8) === expect;
}
else return false;
},
europe: function () {
//TODO (S.Panfilov) wtf?
rules: {
multipliers: [
3,
7,
1,
3,
7,
1,
3,
7
],
regex: /^(EE)(10\d{7})$/
}
};
COUNTRIES.europe = {
calcs: function(vat) {
// We know little about EU numbers apart from the fact that the first 3 digits represent the

@@ -604,6 +531,13 @@ // country, and that there are nine digits in total.

},
finland: function (vat, countryName) {
rules: {
regex: /^(EU)(\d{9})$/
}
};
COUNTRIES.finland = {
calcs: function(vat) {
var total = 0;
var expect;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
for (var i = 0; i < 7; i++) total += +vat.charAt(i) * this.rules.multipliers[i];

@@ -620,4 +554,20 @@ // Establish check digit.

},
france: function (vat) {
rules: {
multipliers: [
7,
9,
10,
5,
8,
4,
2
],
regex: /^(FI)(\d{8})$/
}
};
COUNTRIES.france = {
calcs: function(vat) {
var total;
var expect;
// Checks the check digits of a French VAT number.

@@ -638,81 +588,92 @@ if (!(/^\d{11}$/).test(vat)) {

},
united_kingdom: function (vat, countryName) {
var total = 0;
// Government departments
if (vat.substr(0, 2) === 'GD') {
expect = 500;
return vat.substr(2, 3) < expect;
}
rules: {
regex: [
/^(FR)(\d{11})$/,
/^(FR)([A-HJ-NP-Z]\d{10})$/,
/^(FR)(\d[A-HJ-NP-Z]\d{9})$/,
/^(FR)([A-HJ-NP-Z]{2}\d{9})$/
]
}
};
COUNTRIES.germany = {
calcs: function(vat) {
// Checks the check digits of a German VAT number.
var product = 10;
var sum = 0;
var checkDigit = 0;
var expect;
// Health authorities
if (vat.substr(0, 2) === 'HA') {
expect = 499;
return vat.substr(2, 3) > expect;
}
for (var i = 0; i < 8; i++) {
// Standard and commercial numbers
// 0 VAT numbers disallowed!
if (+vat.slice(0) === 0) return false;
// Check range is OK for modulus 97 calculation
var no = +vat.slice(0, 7);
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
// Extract the next digit and implement peculiar algorithm!.
sum = (+vat.charAt(i) + product) % 10;
if (sum === 0) {
sum = 10;
}
product = (2 * sum) % 11;
}
// Old numbers use a simple 97 modulus, but new numbers use an adaptation of that (less 55). Our
// VAT number could use either system, so we check it against both.
// Establish check digits by subtracting 97 from total until negative.
var checkDigit = total;
while (checkDigit > 0) {
checkDigit = checkDigit - 97;
// Establish check digit.
if (11 - product === 10) {
checkDigit = 0;
} else {
checkDigit = 11 - product;
}
// Get the absolute value and compare it with the last two characters of the VAT number. If the
// same, then it is a valid traditional check digit. However, even then the number must fit within
// certain specified ranges.
checkDigit = Math.abs(checkDigit);
if (checkDigit === +vat.slice(7, 9) && no < 9990001 && (no < 100000 || no > 999999) && (no < 9490001 || no > 9700000)) return true;
// Now try the new method by subtracting 55 from the check digit if we can - else add 42
if (checkDigit >= 55)
checkDigit = checkDigit - 55;
else
checkDigit = checkDigit + 42;
expect = +vat.slice(7, 9);
return !!(checkDigit === expect && no > 1000000);
// Compare it with the last two characters of the VAT number. If the same, then it is a valid
// check digit.
expect = +vat.slice(8, 9);
return checkDigit === expect;
},
croatia: function (vat) {
rules: {
regex: /^(DE)([1-9]\d{8})$/
}
};
COUNTRIES.greece = {
calcs: function(vat) {
var total = 0;
var expect;
//eight character numbers should be prefixed with an 0.
if (vat.length === 8) {
vat = '0' + vat;
}
// Checks the check digits of a Croatian VAT number using ISO 7064, MOD 11-10 for check digit.
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
var product = 10;
var sum = 0;
for (var i = 0; i < 10; i++) {
// Extract the next digit and implement the algorithm
sum = (+vat.charAt(i) + product) % 10;
if (sum === 0) {
sum = 10;
}
product = (2 * sum) % 11;
// Establish check digit.
total = total % 11;
if (total > 9) {
total = 0;
}
// Now check that we have the right check digit
expect = +vat.slice(10, 11);
return (product + expect) % 10 === 1;
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(8, 9);
return total === expect;
},
hungary: function (vat, countryName) {
rules: {
multipliers: [
256,
128,
64,
32,
16,
8,
4,
2
],
regex: /^(EL)(\d{9})$/
}
};
COUNTRIES.hungary = {
calcs: function(vat) {
var total = 0;
var expect;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}

@@ -728,6 +689,22 @@

},
ireland: function (vat, countryName) {
rules: {
multipliers: [
9,
7,
3,
1,
9,
7,
3
],
regex: /^(HU)(\d{8})$/
}
};
COUNTRIES.ireland = {
calcs: function(vat) {
var total = 0;
var expect;
// If the code is type 1 format, we need to convert it to the new before performing the validation.
if (/^\d[A-Z\*\+]/.test(vat)) {
if (this.rules.typeFormats.first.test(vat)) {
vat = '0' + vat.substring(2, 7) + vat.substring(0, 1) + vat.substring(7, 8);

@@ -738,7 +715,7 @@ }

for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// If the number is type 3 then we need to include the trailing A or H in the calculation
if (/^\d{7}[A-Z][AH]$/.test(vat)) {
if (this.rules.typeFormats.third.test(vat)) {
// Add in a multiplier for the character A (1*9=9) or H (8*9=72)

@@ -764,4 +741,29 @@ if (vat.charAt(8) === 'H') {

},
italy: function (vat, countryName) {
rules: {
multipliers: [
8,
7,
6,
5,
4,
3,
2
],
typeFormats: {
first: /^\d[A-Z\*\+]/,
third: /^\d{7}[A-Z][AH]$/
},
regex: [
/^(IE)(\d{7}[A-W])$/,
/^(IE)([7-9][A-Z\*\+)]\d{5}[A-W])$/,
/^(IE)(\d{7}[A-W][AH])$/
]
}
};
COUNTRIES.italy = {
calcs: function(vat) {
var total = 0;
var temp;
var expect;
// The last three digits are the issuing office, and cannot exceed more 201, unless 999 or 888

@@ -779,3 +781,3 @@ if (+vat.slice(0, 7) === 0) {

for (var i = 0; i < 10; i++) {
temp = +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
temp = +vat.charAt(i) * this.rules.multipliers[i];
if (temp > 9)

@@ -797,5 +799,103 @@ total += Math.floor(temp / 10) + temp % 10;

},
lithunia: function (vat, countryName) {
rules: {
multipliers: [
1,
2,
1,
2,
1,
2,
1,
2,
1,
2
],
regex: /^(IT)(\d{11})$/
}
};
COUNTRIES.latvia = {
calcs: function(vat) {
var total = 0;
var expect;
// Differentiate between legal entities and natural bodies. For the latter we simply check that
// the first six digits correspond to valid DDMMYY dates.
if ((/^[0-3]/).test(vat)) {
return !!(/^[0-3][0-9][0-1][0-9]/).test(vat);
} else {
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 10; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// Establish check digits by getting modulus 11.
if (total % 11 === 4 && vat[0] === 9) total = total - 45;
if (total % 11 === 4) {
total = 4 - total % 11;
} else if (total % 11 > 4) {
total = 14 - total % 11;
} else if (total % 11 < 4) {
total = 3 - total % 11;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(10, 11);
return total === expect;
}
},
rules: {
multipliers: [
9,
1,
4,
8,
3,
10,
2,
5,
7,
6
],
regex: /^(LV)(\d{11})$/
}
};
COUNTRIES.lithunia = (function() {
function _extractDigit(vat, multiplier, key) {
return +vat.charAt(key) * multiplier[key];
}
function _doubleCheckCalculation(vat, total, rules) {
if (total % 11 === 10) {
total = 0;
for (var i = 0; i < 8; i++) {
total += _extractDigit(vat, rules.multipliers.short, i)
}
}
return total;
}
function extractDigit(vat, total) {
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * (i + 1);
}
return total;
}
function checkDigit(total) {
total = total % 11;
if (total === 10) {
total = 0;
}
return total;
}
function _check9DigitVat(vat, rules) {
// 9 character VAT numbers are for legal persons
var total = 0;
if (vat.length === 9) {

@@ -807,58 +907,111 @@

// Extract the next digit and multiply by the counter+1.
total = 0;
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * (i + 1);
}
total = extractDigit(vat, total);
// Can have a double check digit calculation!
if (total % 11 === 10) {
total = 0;
for (var j = 0; j < 8; j++) {
total += +vat.charAt(j) * CONDITIONS[countryName].multipliers.short[j];
}
}
total = _doubleCheckCalculation(vat, total, rules);
// Establish check digit.
total = total % 11;
if (total === 10) {
total = 0;
}
total = checkDigit(total);
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(8, 9);
var expect = +vat.slice(8, 9);
return total === expect;
}
return false;
}
function extractDigit12(vat, total, rules) {
for (var k = 0; k < 11; k++) {
total += _extractDigit(vat, rules.multipliers.med, k)
}
return total;
}
function _doubleCheckCalculation12(vat, total, rules) {
if (total % 11 === 10) {
total = 0;
for (var l = 0; l < 11; l++) {
total += _extractDigit(vat, rules.multipliers.alt, l)
}
}
return total;
}
function _check12DigitVat(vat, rules) {
var total = 0;
// 12 character VAT numbers are for temporarily registered taxpayers
else {
if (vat.length === 12) {
// 11th character must be one
if (!(/^\d{10}1/).test(vat)) return false;
if (!(rules.check).test(vat)) return false;
// Extract the next digit and multiply by the counter+1.
total = 0;
for (var k = 0; k < 11; k++) {
total += +vat.charAt(k) * CONDITIONS[countryName].multipliers.med[k];
}
total = extractDigit12(vat, total, rules);
// Can have a double check digit calculation!
if (total % 11 === 10) {
total = 0;
for (var l = 0; l < 11; l++) {
total += +vat.charAt(l) * CONDITIONS[countryName].multipliers.alt[l];
}
}
total = _doubleCheckCalculation12(vat, total, rules);
// Establish check digit.
total = total % 11;
if (total === 10) {
total = 0;
}
total = checkDigit(total);
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(11, 12);
var expect = +vat.slice(11, 12);
return total === expect;
}
},
luxembourg: function (vat) {
return false;
}
return {
calcs: function(vat) {
return _check9DigitVat(vat, this.rules) || _check12DigitVat(vat, this.rules);
},
rules: {
multipliers: {
"short": [
3,
4,
5,
6,
7,
8,
9,
1
],
"med": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
1,
2
],
"alt": [
3,
4,
5,
6,
7,
8,
9,
1,
2,
3,
4
]
},
check: /^\d{10}1/,
regex: /^(LT)(\d{9}|\d{12})$/
}
};
})();
COUNTRIES.luxembourg = {
calcs: function(vat) {
var expect = +vat.slice(6, 8);

@@ -870,35 +1023,14 @@ var checkDigit = +vat.slice(0, 6) % 89;

},
latvia: function (vat, countryName) {
rules: {
regex: /^(LU)(\d{8})$/
}
};
COUNTRIES.malta = {
calcs: function(vat) {
var total = 0;
var expect;
// Differentiate between legal entities and natural bodies. For the latter we simply check that
// the first six digits correspond to valid DDMMYY dates.
if ((/^[0-3]/).test(vat)) {
return !!(/^[0-3][0-9][0-1][0-9]/).test(vat);
} else {
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 10; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
// Establish check digits by getting modulus 11.
if (total % 11 === 4 && vat[0] === 9) total = total - 45;
if (total % 11 === 4)
total = 4 - total % 11;
else if (total % 11 > 4)
total = 14 - total % 11;
else if (total % 11 < 4)
total = 3 - total % 11;
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(10, 11);
return total === expect;
}
},
malta: function (vat, countryName) {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 6; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}

@@ -913,7 +1045,22 @@

},
netherlands: function (vat, countryName) {
rules: {
multipliers: [
3,
4,
6,
7,
8,
9
],
regex: /^(MT)([1-9]\d{7})$/
}
};
COUNTRIES.netherlands = {
calcs: function(vat) {
var total = 0;
var expect;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}

@@ -931,4 +1078,20 @@

},
norway: function (vat, countryName) {
rules: {
multipliers: [
9,
8,
7,
6,
5,
4,
3,
2
],
regex: /^(NL)(\d{9})B\d{2}$/
}
};
COUNTRIES.norway = {
calcs: function(vat) {
var total = 0;
var expect;
// See http://www.brreg.no/english/coordination/number.html

@@ -938,3 +1101,3 @@

for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}

@@ -944,7 +1107,8 @@

total = 11 - total % 11;
if (total === 11) {
total = 0;
}
if (total < 10) {
// Compare it with the last character of the VAT number. If it's the same, then it's valid.

@@ -955,7 +1119,24 @@ expect = +vat.slice(8, 9);

},
poland: function (vat, countryName) {
rules: {
multipliers: [
3,
2,
7,
6,
5,
4,
3,
2
],
regex: /^(NO)(\d{9})$/
}
};
COUNTRIES.poland = {
calcs: function(vat) {
var total = 0;
var expect;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 9; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}

@@ -973,7 +1154,25 @@

},
portugal: function (vat, countryName) {
rules: {
multipliers: [
6,
5,
7,
2,
3,
4,
5,
6,
7
],
regex: /^(PL)(\d{10})$/
}
};
COUNTRIES.portugal = {
calcs: function(vat) {
var total = 0;
var expect;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}

@@ -991,7 +1190,24 @@

},
romania: function (vat, countryName) {
rules: {
multipliers: [
9,
8,
7,
6,
5,
4,
3,
2
],
regex: /^(PT)(\d{9})$/
}
};
COUNTRIES.romania = {
calcs: function(vat) {
var total = 0;
var expect;
// Extract the next digit and multiply by the counter.
var vatLength = vat.length;
var multipliers = CONDITIONS[countryName].multipliers.slice(10 - vatLength);
var multipliers = this.rules.multipliers.slice(10 - vatLength);

@@ -1010,36 +1226,26 @@ for (var i = 0; i < vat.length - 1; i++) {

},
serbia: function (vat) {
// Checks the check digits of a Serbian VAT number using ISO 7064, MOD 11-10 for check digit.
rules: {
multipliers: [
7,
5,
3,
2,
1,
7,
5,
3,
2
],
regex: /^(RO)([1-9]\d{1,9})$/
}
};
COUNTRIES.russia = (function() {
var product = 10;
var sum = 0;
var checkDigit;
for (var i = 0; i < 8; i++) {
// Extract the next digit and implement the algorithm
sum = (+vat.charAt(i) + product) % 10;
if (sum === 0) {
sum = 10;
}
product = (2 * sum) % 11;
}
// Now check that we have the right check digit
expect = 1;
checkDigit = (product + (+vat.slice(8, 9))) % 10;
return checkDigit === expect;
},
russia: function (vat, countryName) {
function _check10DigitINN(vat, rules) {
var total = 0;
var expect2;
// Checks the check digits of a Russian INN number
// See http://russianpartner.biz/test_inn.html for algorithm
// 10 digit INN numbers
if (vat.length === 10) {
for (var i = 0; i < 10; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers.m_1[i];
total += +vat.charAt(i) * rules.multipliers.m_1[i];
}

@@ -1053,15 +1259,21 @@

// Compare it with the last character of the VAT number. If it is the same, then it's valid
expect = +vat.slice(9, 10);
var expect = +vat.slice(9, 10);
return total === expect;
}
// 12 digit INN numbers
} else if (vat.length === 12) {
var total1 = 0;
var total2 = 0;
return false;
}
function _check12DigitINN(vat, rules) {
var total1 = 0;
var total2 = 0;
if (vat.length === 12) {
for (var j = 0; j < 11; j++) {
total1 += +vat.charAt(j) * CONDITIONS[countryName].multipliers.m_2[j];
total1 += +vat.charAt(j) * rules.multipliers.m_2[j];
}
total1 = total1 % 11;
if (total1 > 9) {

@@ -1072,3 +1284,3 @@ total1 = total1 % 10;

for (var k = 0; k < 11; k++) {
total2 += +vat.charAt(k) * CONDITIONS[countryName].multipliers.m_3[k];
total2 += +vat.charAt(k) * rules.multipliers.m_3[k];
}

@@ -1083,10 +1295,226 @@

// character of the VAT number. If they're both the same, then it's valid
//expect = +vat.slice(10, 11);
expect = (total1 === +vat.slice(10, 11));
//expect2 = +vat.slice(11, 12);
expect2 = (total2 === +vat.slice(11, 12));
var expect = (total1 === +vat.slice(10, 11));
var expect2 = (total2 === +vat.slice(11, 12));
return (expect) && (expect2);
}
return false;
}
return {
calcs: function(vat) {
// See http://russianpartner.biz/test_inn.html for algorithm
return _check10DigitINN(vat, this.rules) || _check12DigitINN(vat, this.rules);
},
rules: {
multipliers: {
"m_1": [
2,
4,
10,
3,
5,
9,
4,
6,
8,
0
],
"m_2": [
7,
2,
4,
10,
3,
5,
9,
4,
6,
8,
0
],
"m_3": [
3,
7,
2,
4,
10,
3,
5,
9,
4,
6,
8,
0
]
},
regex: /^(RU)(\d{10}|\d{12})$/
}
};
})();
COUNTRIES.serbia = {
calcs: function(vat) {
// Checks the check digits of a Serbian VAT number using ISO 7064, MOD 11-10 for check digit.
var product = 10;
var sum = 0;
var checkDigit;
for (var i = 0; i < 8; i++) {
// Extract the next digit and implement the algorithm
sum = (+vat.charAt(i) + product) % 10;
if (sum === 0) {
sum = 10;
}
product = (2 * sum) % 11;
}
// Now check that we have the right check digit
var expect = 1;
checkDigit = (product + (+vat.slice(8, 9))) % 10;
return checkDigit === expect;
},
sweden: function (vat) {
rules: {
regex: /^(RS)(\d{9})$/
}
};
COUNTRIES.slovakia_republic = {
calcs: function(vat) {
var expect = 0;
var checkDigit = (vat % 11);
return checkDigit === expect;
},
rules: {
regex: /^(SK)([1-9]\d[2346-9]\d{7})$/
}
};
COUNTRIES.slovenia = {
calcs: function(vat) {
var total = 0;
var expect;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// Establish check digits using modulus 11
total = 11 - total % 11;
if (total === 10) {
total = 0;
}
// Compare the number with the last character of the VAT number. If it is the
// same, then it's a valid check digit.
expect = +vat.slice(7, 8);
return !!(total !== 11 && total === expect);
},
rules: {
multipliers: [
8,
7,
6,
5,
4,
3,
2
],
regex: /^(SI)([1-9]\d{7})$/
}
};
COUNTRIES.spain = {
calcs: function(vat) {
var i = 0;
var total = 0;
var temp;
var expect;
// National juridical entities
if (this.rules.additional[0].test(vat)) {
// Extract the next digit and multiply by the counter.
for (i = 0; i < 7; i++) {
temp = vat.charAt(i + 1) * this.rules.multipliers[i];
if (temp > 9)
total += Math.floor(temp / 10) + temp % 10;
else
total += temp;
}
// Now calculate the check digit itself.
total = 10 - total % 10;
if (total === 10) {
total = 0;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(8, 9);
return total === expect;
}
// Juridical entities other than national ones
else if (this.rules.additional[1].test(vat)) {
// Extract the next digit and multiply by the counter.
for (i = 0; i < 7; i++) {
temp = vat.charAt(i + 1) * this.rules.multipliers[i];
if (temp > 9)
total += Math.floor(temp / 10) + temp % 10;
else
total += temp;
}
// Now calculate the check digit itself.
total = 10 - total % 10;
total = String.fromCharCode(total + 64);
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = vat.slice(8, 9);
return total === expect;
}
// Personal number (NIF) (starting with numeric of Y or Z)
else if (this.rules.additional[2].test(vat)) {
var tempnumber = vat;
if (tempnumber.substring(0, 1) === 'Y') tempnumber = tempnumber.replace(/Y/, '1');
if (tempnumber.substring(0, 1) === 'Z') tempnumber = tempnumber.replace(/Z/, '2');
expect = 'TRWAGMYFPDXBNJZSQVHLCKE'.charAt(+tempnumber.substring(0, 8) % 23);
return tempnumber.charAt(8) === expect;
}
// Personal number (NIF) (starting with K, L, M, or X)
else if (this.rules.additional[3].test(vat)) {
expect = 'TRWAGMYFPDXBNJZSQVHLCKE'.charAt(+vat.substring(1, 8) % 23);
return vat.charAt(8) === expect;
} else return false;
},
rules: {
multipliers: [
2,
1,
2,
1,
2,
1,
2
],
regex: [
/^(ES)([A-Z]\d{8})$/,
/^(ES)([A-HN-SW]\d{7}[A-J])$/,
/^(ES)([0-9YZ]\d{7}[A-Z])$/,
/^(ES)([KLMX]\d{7}[A-Z])$/
],
additional: [
/^[A-H|J|U|V]\d{8}$/,
/^[A-H|N-S|W]\d{7}[A-J]$/,
/^[0-9|Y|Z]\d{7}[A-Z]$/,
/^[K|L|M|X]\d{7}[A-Z]$/
]
}
};
COUNTRIES.sweden = {
calcs: function(vat) {
var expect;
// Calculate R where R = R1 + R3 + R5 + R7 + R9, and Ri = INT(Ci/5) + (Ci*2) modulo 10

@@ -1113,32 +1541,115 @@ var R = 0;

},
slovenia: function (vat, countryName) {
rules: {
regex: /^(SE)(\d{10}01)$/
}
};
COUNTRIES.switzerland = {
calcs: function(vat) {
var total = 0;
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// Establish check digit.
total = 11 - total % 11;
if (total === 10) return false;
if (total === 11) total = 0;
// Check to see if the check digit given is correct, If not, we have an error with the VAT number
var expect = +vat.substr(8, 1);
return total === expect;
},
rules: {
multipliers: [
5,
4,
3,
2,
7,
6,
5,
4
],
regex: /^(CHE)(\d{9})(MWST)?$/
}
};
COUNTRIES.united_kingdom = {
calcs: function(vat) {
var total = 0;
var expect;
// Government departments
if (vat.substr(0, 2) === 'GD') {
expect = 500;
return vat.substr(2, 3) < expect;
}
// Health authorities
if (vat.substr(0, 2) === 'HA') {
expect = 499;
return vat.substr(2, 3) > expect;
}
// Standard and commercial numbers
// 0 VAT numbers disallowed!
if (+vat.slice(0) === 0) return false;
// Check range is OK for modulus 97 calculation
var no = +vat.slice(0, 7);
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// Establish check digits using modulus 11
total = 11 - total % 11;
if (total === 10) {
total = 0;
// Old numbers use a simple 97 modulus, but new numbers use an adaptation of that (less 55). Our
// VAT number could use either system, so we check it against both.
// Establish check digits by subtracting 97 from total until negative.
var checkDigit = total;
while (checkDigit > 0) {
checkDigit = checkDigit - 97;
}
// Compare the number with the last character of the VAT number. If it is the
// same, then it's a valid check digit.
expect = +vat.slice(7, 8);
return !!(total !== 11 && total === expect);
// Get the absolute value and compare it with the last two characters of the VAT number. If the
// same, then it is a valid traditional check digit. However, even then the number must fit within
// certain specified ranges.
checkDigit = Math.abs(checkDigit);
if (checkDigit === +vat.slice(7, 9) && no < 9990001 && (no < 100000 || no > 999999) && (no < 9490001 || no > 9700000)) return true;
// Now try the new method by subtracting 55 from the check digit if we can - else add 42
if (checkDigit >= 55)
checkDigit = checkDigit - 55;
else
checkDigit = checkDigit + 42;
expect = +vat.slice(7, 9);
return !!(checkDigit === expect && no > 1000000);
},
slovakia_republic: function (vat) {
var expect = 0;
var checkDigit = (vat % 11);
// Checks the check digits of a Slovakian VAT number.
// Check that the modulus of the whole VAT number is 0 - else error
return checkDigit === expect;
rules: {
multipliers: [
8,
7,
6,
5,
4,
3,
2
],
regex: [
/^(GB)?(\d{9})$/,
/^(GB)?(\d{12})$/,
/^(GB)?(GD\d{3})$/,
/^(GB)?(HA\d{3})$/
]
}
};
//Support of node.js
if (typeof module === 'object' && module.exports) module.exports = exports;
return exports;
})();

@@ -1,2 +0,2 @@

var jsvat=function(){"use strict";function r(r,e){return e.test(r)}function e(r,e,t){var i=e.exec(r),l=i[2];return u[t](l,t)}function t(t,i,l){var a=!1;return r(t,i)&&(a=e(t,i,l)),a}var i,l,a={austria:{multipliers:[1,2,1,2,1,2,1],regex:/^(AT)U(\d{8})$/},belgium:{regex:/^(BE)(0?\d{9})$/},bulgaria:{multipliers:{physical:[2,4,8,5,10,9,7,3,6],foreigner:[21,19,17,13,11,9,7,3,1],miscellaneous:[4,3,2,7,6,5,4,3,2]},regex:/^(BG)(\d{9,10})$/},switzerland:{multipliers:[5,4,3,2,7,6,5,4],regex:/^(CHE)(\d{9})(MWST)?$/},cyprus:{regex:/^(CY)([0-59]\d{7}[A-Z])$/},czech_republic:{multipliers:[8,7,6,5,4,3,2],lookup:[8,7,6,5,4,3,2,1,0,9,10],regex:/^(CZ)(\d{8,10})(\d{3})?$/,additional:[/^\d{8}$/,/^[0-5][0-9][0|1|5|6]\d[0-3]\d\d{3}$/,/^6\d{8}$/,/^\d{2}[0-3|5-8]\d[0-3]\d\d{4}$/]},germany:{regex:/^(DE)([1-9]\d{8})$/},denmark:{multipliers:[2,7,6,5,4,3,2,1],regex:/^(DK)(\d{8})$/},estonia:{multipliers:[3,7,1,3,7,1,3,7],regex:/^(EE)(10\d{7})$/},greece:{multipliers:[256,128,64,32,16,8,4,2],regex:/^(EL)(\d{9})$/},spain:{multipliers:[2,1,2,1,2,1,2],regex:[/^(ES)([A-Z]\d{8})$/,/^(ES)([A-HN-SW]\d{7}[A-J])$/,/^(ES)([0-9YZ]\d{7}[A-Z])$/,/^(ES)([KLMX]\d{7}[A-Z])$/],additional:[/^[A-H|J|U|V]\d{8}$/,/^[A-H|N-S|W]\d{7}[A-J]$/,/^[0-9|Y|Z]\d{7}[A-Z]$/,/^[K|L|M|X]\d{7}[A-Z]$/]},europe:{regex:/^(EU)(\d{9})$/},finland:{multipliers:[7,9,10,5,8,4,2],regex:/^(FI)(\d{8})$/},france:{regex:[/^(FR)(\d{11})$/,/^(FR)([A-HJ-NP-Z]\d{10})$/,/^(FR)(\d[A-HJ-NP-Z]\d{9})$/,/^(FR)([A-HJ-NP-Z]{2}\d{9})$/]},united_kingdom:{multipliers:[8,7,6,5,4,3,2],regex:[/^(GB)?(\d{9})$/,/^(GB)?(\d{12})$/,/^(GB)?(GD\d{3})$/,/^(GB)?(HA\d{3})$/]},croatia:{regex:/^(HR)(\d{11})$/},hungary:{multipliers:[9,7,3,1,9,7,3],regex:/^(HU)(\d{8})$/},ireland:{multipliers:[8,7,6,5,4,3,2],regex:[/^(IE)(\d{7}[A-W])$/,/^(IE)([7-9][A-Z\*\+)]\d{5}[A-W])$/,/^(IE)(\d{7}[A-W][AH])$/]},italy:{multipliers:[1,2,1,2,1,2,1,2,1,2],regex:/^(IT)(\d{11})$/},latvia:{multipliers:[9,1,4,8,3,10,2,5,7,6],regex:/^(LV)(\d{11})$/},lithunia:{multipliers:{"short":[3,4,5,6,7,8,9,1],med:[1,2,3,4,5,6,7,8,9,1,2],alt:[3,4,5,6,7,8,9,1,2,3,4]},regex:/^(LT)(\d{9}|\d{12})$/},luxembourg:{regex:/^(LU)(\d{8})$/},malta:{multipliers:[3,4,6,7,8,9],regex:/^(MT)([1-9]\d{7})$/},netherlands:{multipliers:[9,8,7,6,5,4,3,2],regex:/^(NL)(\d{9})B\d{2}$/},norway:{multipliers:[3,2,7,6,5,4,3,2],regex:/^(NO)(\d{9})$/},poland:{multipliers:[6,5,7,2,3,4,5,6,7],regex:/^(PL)(\d{10})$/},portugal:{multipliers:[9,8,7,6,5,4,3,2],regex:/^(PT)(\d{9})$/},romania:{multipliers:[7,5,3,2,1,7,5,3,2],regex:/^(RO)([1-9]\d{1,9})$/},russia:{multipliers:{m_1:[2,4,10,3,5,9,4,6,8,0],m_2:[7,2,4,10,3,5,9,4,6,8,0],m_3:[3,7,2,4,10,3,5,9,4,6,8,0]},regex:/^(RU)(\d{10}|\d{12})$/},serbia:{regex:/^(RS)(\d{9})$/},slovenia:{multipliers:[8,7,6,5,4,3,2],regex:/^(SI)([1-9]\d{7})$/},slovakia_republic:{regex:/^(SK)([1-9]\d[2346-9]\d{7})$/},sweden:{regex:/^(SE)(\d{10}01)$/}},n={checkVAT:function(r){if(!r)return!1;r=r.toString().toUpperCase().replace(/(\s|-|\.)+/g,"");for(var e in a)if(a.hasOwnProperty(e)){var i=a[e].regex;if(Array.isArray(i)){for(var l=0;l<i.length;l++)if(t(r,i[l],e))return!0}else if(t(r,i,e))return!0}return!1}},u={austria:function(r,e){for(var t=0,n=0;7>n;n++)l=r.charAt(n)*a[e].multipliers[n],t+=l>9?Math.floor(l/10)+l%10:l;return t=10-(t+4)%10,10===t&&(t=0),i=+r.slice(7,8),t===i},belgium:function(r){if(9===r.length&&(r="0"+r),0===+r.slice(1,2))return!1;var e=97-+r.slice(0,8)%97;return i=+r.slice(8,10),e===i},bulgaria:function(r,e){var t=function(){var e=0;l=0;for(var t=0;8>t;t++)l+=+r.charAt(t)*(t+1);if(e=l%11,10!==e)return i=+r.slice(8),e===i;l=0;for(var a=0;8>a;a++)l+=+r.charAt(a)*(a+3);return e=l%11,10===e&&(e=0),i=+r.slice(8),e===i},n=function(){var t=0;if(/^\d\d[0-5]\d[0-3]\d\d{4}$/.test(r)){var i=+r.slice(2,4);if(i>0&&13>i||i>20&&33>i||i>40&&53>i){t=0;for(var l=0;9>l;l++)t+=+r.charAt(l)*a[e].multipliers.physical[l];if(t%=11,10===t&&(t=0),t===+r.substr(9,1))return!0}}return!1},u=function(){for(var t=0,i=0;9>i;i++)t+=+r.charAt(i)*a[e].multipliers.foreigner[i];return t%10===+r.substr(9,1)?!0:void 0},s=function(){for(var t=0,l=0;9>l;l++)t+=+r.charAt(l)*a[e].multipliers.miscellaneous[l];return t=11-t%11,10===t?!1:(11===t&&(t=0),i=+r.substr(9,1),t===i)};return 9===r.length?t():n()||u()||s()},switzerland:function(r,e){for(var t=0,l=0;8>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t=11-t%11,10===t?!1:(11===t&&(t=0),i=+r.substr(8,1),t===i)},cyprus:function(r){var e=0;if(12===+r.slice(0,2))return!1;for(var t=0;8>t;t++){var l=+r.charAt(t);if(t%2===0)switch(l){case 0:l=1;break;case 1:l=0;break;case 2:l=5;break;case 3:l=7;break;case 4:l=9;break;default:l=2*l+3}e+=l}return e%=26,e=String.fromCharCode(e+65),i=r.substr(8,1),e===i},czech_republic:function(r,e){var t=0;if(a[e].additional[0].test(r)){for(var l=0;7>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t=11-t%11,10===t&&(t=0),11===t&&(t=1),i=+r.slice(7,8),t===i}if(a[e].additional[2].test(r)){for(var n=0;7>n;n++)t+=+r.charAt(n+1)*a[e].multipliers[n];return t=11-t%11,10===t&&(t=0),11===t&&(t=1),i=+r.slice(8,9),a[e].lookup[t-1]===i}if(a[e].additional[3].test(r)){var u=+r.slice(0,2)+r.slice(2,4)+r.slice(4,6)+r.slice(6,8)+r.slice(8);return i=+r%11===0,!(u%11!==0||!i)}return!1},germany:function(r){for(var e=10,t=0,l=0,a=0;8>a;a++)t=(+r.charAt(a)+e)%10,0===t&&(t=10),e=2*t%11;return l=11-e===10?0:11-e,i=+r.slice(8,9),l===i},denmark:function(r,e){for(var t=0,i=0;8>i;i++)t+=+r.charAt(i)*a[e].multipliers[i];return t%11===0},estonia:function(r,e){for(var t=0,l=0;8>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t=10-t%10,10===t&&(t=0),i=+r.slice(8,9),t===i},greece:function(r,e){var t=0;8===r.length&&(r="0"+r);for(var l=0;8>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t%=11,t>9&&(t=0),i=+r.slice(8,9),t===i},spain:function(r,e){var t=0,n=0;if(a[e].additional[0].test(r)){for(t=0;7>t;t++)l=r.charAt(t+1)*a[e].multipliers[t],n+=l>9?Math.floor(l/10)+l%10:l;return n=10-n%10,10===n&&(n=0),i=+r.slice(8,9),n===i}if(a[e].additional[1].test(r)){for(t=0;7>t;t++)l=r.charAt(t+1)*a[e].multipliers[t],n+=l>9?Math.floor(l/10)+l%10:l;return n=10-n%10,n=String.fromCharCode(n+64),i=r.slice(8,9),n===i}if(a[e].additional[2].test(r)){var u=r;return"Y"===u.substring(0,1)&&(u=u.replace(/Y/,"1")),"Z"===u.substring(0,1)&&(u=u.replace(/Z/,"2")),i="TRWAGMYFPDXBNJZSQVHLCKE".charAt(+u.substring(0,8)%23),u.charAt(8)===i}return a[e].additional[3].test(r)?(i="TRWAGMYFPDXBNJZSQVHLCKE".charAt(+r.substring(1,8)%23),r.charAt(8)===i):!1},europe:function(){return!0},finland:function(r,e){for(var t=0,l=0;7>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t=11-t%11,t>9&&(t=0),i=+r.slice(7,8),t===i},france:function(r){var e;return/^\d{11}$/.test(r)?(e=+r.substring(2),e=(100*e+12)%97,i=+r.slice(0,2),e===i):!0},united_kingdom:function(r,e){var t=0;if("GD"===r.substr(0,2))return i=500,r.substr(2,3)<i;if("HA"===r.substr(0,2))return i=499,r.substr(2,3)>i;if(0===+r.slice(0))return!1;for(var l=+r.slice(0,7),n=0;7>n;n++)t+=+r.charAt(n)*a[e].multipliers[n];for(var u=t;u>0;)u-=97;return u=Math.abs(u),u===+r.slice(7,9)&&9990001>l&&(1e5>l||l>999999)&&(9490001>l||l>97e5)?!0:(u>=55?u-=55:u+=42,i=+r.slice(7,9),!!(u===i&&l>1e6))},croatia:function(r){for(var e=10,t=0,l=0;10>l;l++)t=(+r.charAt(l)+e)%10,0===t&&(t=10),e=2*t%11;return i=+r.slice(10,11),(e+i)%10===1},hungary:function(r,e){for(var t=0,l=0;7>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t=10-t%10,10===t&&(t=0),i=+r.slice(7,8),t===i},ireland:function(r,e){var t=0;/^\d[A-Z\*\+]/.test(r)&&(r="0"+r.substring(2,7)+r.substring(0,1)+r.substring(7,8));for(var l=0;7>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return/^\d{7}[A-Z][AH]$/.test(r)&&(t+="H"===r.charAt(8)?72:9),t%=23,t=0===t?"W":String.fromCharCode(t+64),i=r.slice(7,8),t===i},italy:function(r,e){var t=0;if(0===+r.slice(0,7))return!1;if(l=+r.slice(7,10),1>l||l>201&&999!==l&&888!==l)return!1;for(var n=0;10>n;n++)l=+r.charAt(n)*a[e].multipliers[n],t+=l>9?Math.floor(l/10)+l%10:l;return t=10-t%10,t>9&&(t=0),i=+r.slice(10,11),t===i},lithunia:function(r,e){var t=0;if(9===r.length){if(!/^\d{7}1/.test(r))return!1;t=0;for(var l=0;8>l;l++)t+=+r.charAt(l)*(l+1);if(t%11===10){t=0;for(var n=0;8>n;n++)t+=+r.charAt(n)*a[e].multipliers["short"][n]}return t%=11,10===t&&(t=0),i=+r.slice(8,9),t===i}if(!/^\d{10}1/.test(r))return!1;t=0;for(var u=0;11>u;u++)t+=+r.charAt(u)*a[e].multipliers.med[u];if(t%11===10){t=0;for(var s=0;11>s;s++)t+=+r.charAt(s)*a[e].multipliers.alt[s]}return t%=11,10===t&&(t=0),i=+r.slice(11,12),t===i},luxembourg:function(r){var e=+r.slice(6,8),t=+r.slice(0,6)%89;return t===e},latvia:function(r,e){var t=0;if(/^[0-3]/.test(r))return!!/^[0-3][0-9][0-1][0-9]/.test(r);for(var l=0;10>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t%11===4&&9===r[0]&&(t-=45),t%11===4?t=4-t%11:t%11>4?t=14-t%11:4>t%11&&(t=3-t%11),i=+r.slice(10,11),t===i},malta:function(r,e){for(var t=0,l=0;6>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t=37-t%37,i=+r.slice(6,8),t===i},netherlands:function(r,e){for(var t=0,l=0;8>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t%=11,t>9&&(t=0),i=+r.slice(8,9),t===i},norway:function(r,e){for(var t=0,l=0;8>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t=11-t%11,11===t&&(t=0),10>t?(i=+r.slice(8,9),t===i):void 0},poland:function(r,e){for(var t=0,l=0;9>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t%=11,t>9&&(t=0),i=+r.slice(9,10),t===i},portugal:function(r,e){for(var t=0,l=0;8>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t=11-t%11,t>9&&(t=0),i=+r.slice(8,9),t===i},romania:function(r,e){for(var t=0,l=r.length,n=a[e].multipliers.slice(10-l),u=0;u<r.length-1;u++)t+=+r.charAt(u)*n[u];return t=10*t%11,10===t&&(t=0),i=+r.slice(r.length-1,r.length),t===i},serbia:function(r){for(var e,t=10,l=0,a=0;8>a;a++)l=(+r.charAt(a)+t)%10,0===l&&(l=10),t=2*l%11;return i=1,e=(t+ +r.slice(8,9))%10,e===i},russia:function(r,e){var t,l=0;if(10===r.length){for(var n=0;10>n;n++)l+=+r.charAt(n)*a[e].multipliers.m_1[n];return l%=11,l>9&&(l%=10),i=+r.slice(9,10),l===i}if(12===r.length){for(var u=0,s=0,c=0;11>c;c++)u+=+r.charAt(c)*a[e].multipliers.m_2[c];u%=11,u>9&&(u%=10);for(var o=0;11>o;o++)s+=+r.charAt(o)*a[e].multipliers.m_3[o];return s%=11,s>9&&(s%=10),i=u===+r.slice(10,11),t=s===+r.slice(11,12),i&&t}},sweden:function(r){for(var e,t=0,l=0;9>l;l+=2)e=+r.charAt(l),t+=Math.floor(e/5)+2*e%10;for(var a=0,n=1;9>n;n+=2)a+=+r.charAt(n);var u=(10-(t+a)%10)%10;return i=+r.slice(9,10),u===i},slovenia:function(r,e){for(var t=0,l=0;7>l;l++)t+=+r.charAt(l)*a[e].multipliers[l];return t=11-t%11,10===t&&(t=0),i=+r.slice(7,8),!(11===t||t!==i)},slovakia_republic:function(r){var e=0,t=r%11;return t===e}};return"object"==typeof module&&module.exports&&(module.exports=n),n}();
var jsvat=function(){"use strict";function r(r,e){return e.test(r)}function e(r,e,t){var i=e.exec(r),s=i[2];return u[t].calcs(s)}function t(t,i,s){var l=!1;return r(t,i)&&(l=e(t,i,s)),l}function i(r){return r.toString().toUpperCase().replace(/(\s|-|\.)+/g,"")}function s(r){return Array.isArray(r)?r:[r]}function l(r,e){if(!r||0===Object.keys(r).length)return!1;var t=r[e];return null===t||void 0===t?!0:!t}var u={},n={config:{},checkVAT:function(r,e){if(!r)return!1;r=i(r);var c={isValid:!1,countries:[]};for(var a in u)if(u.hasOwnProperty(a)&&!l(n.config,a))for(var o=s(u[a].rules.regex),f=0;f<o.length;f++){if(c.isValid=t(r,o[f],a)?!0:c.isValid,!e&&c.isValid)return c.isValid;var d=t(r,o[f],a);d&&c.countries.push(a)}return e?c:c.isValid}};return u.austria={calcs:function(r){for(var e,t,i=0,s=0;7>s;s++)e=r.charAt(s)*this.rules.multipliers[s],i+=e>9?Math.floor(e/10)+e%10:e;return i=10-(i+4)%10,10===i&&(i=0),t=+r.slice(7,8),i===t},rules:{multipliers:[1,2,1,2,1,2,1],regex:/^(AT)U(\d{8})$/}},u.belgium={calcs:function(r){var e;if(9===r.length&&(r="0"+r),0===+r.slice(1,2))return!1;var t=97-+r.slice(0,8)%97;return e=+r.slice(8,10),t===e},rules:{regex:/^(BE)(0?\d{9})$/}},u.bulgaria=function(){function r(r){for(var e,t,i=0,s=0;8>s;s++)i+=+r.charAt(s)*(s+1);if(e=i%11,10!==e)return t=+r.slice(8),e===t;i=0;for(var l=0;8>l;l++)i+=+r.charAt(l)*(l+3);return e=i%11,10===e&&(e=0),t=+r.slice(8),e===t}function e(r,e){var t=0;if(/^\d\d[0-5]\d[0-3]\d\d{4}$/.test(r)){var i=+r.slice(2,4);if(i>0&&13>i||i>20&&33>i||i>40&&53>i){t=0;for(var s=0;9>s;s++)t+=+r.charAt(s)*e.multipliers.physical[s];if(t%=11,10===t&&(t=0),t===+r.substr(9,1))return!0}}return!1}function t(r,e){for(var t=0,i=0;9>i;i++)t+=+r.charAt(i)*e.multipliers.foreigner[i];return t%10===+r.substr(9,1)?!0:void 0}function i(r,e){for(var t=0,i=0;9>i;i++)t+=+r.charAt(i)*e.multipliers.miscellaneous[i];if(t=11-t%11,10===t)return!1;11===t&&(t=0);var s=+r.substr(9,1);return t===s}return{calcs:function(s){return 9===s.length?r(s):e(s,this.rules)||t(s,this.rules)||i(s,this.rules)},rules:{multipliers:{physical:[2,4,8,5,10,9,7,3,6],foreigner:[21,19,17,13,11,9,7,3,1],miscellaneous:[4,3,2,7,6,5,4,3,2]},regex:/^(BG)(\d{9,10})$/}}}(),u.croatia={calcs:function(r){for(var e,t=10,i=0,s=0;10>s;s++)i=(+r.charAt(s)+t)%10,0===i&&(i=10),t=2*i%11;return e=+r.slice(10,11),(t+e)%10===1},rules:{regex:/^(HR)(\d{11})$/}},u.cyprus={calcs:function(r){var e,t=0;if(12===+r.slice(0,2))return!1;for(var i=0;8>i;i++){var s=+r.charAt(i);if(i%2===0)switch(s){case 0:s=1;break;case 1:s=0;break;case 2:s=5;break;case 3:s=7;break;case 4:s=9;break;default:s=2*s+3}t+=s}return t%=26,t=String.fromCharCode(t+65),e=r.substr(8,1),t===e},rules:{regex:/^(CY)([0-59]\d{7}[A-Z])$/}},u.czech_republic=function(){function r(r,e){var t=0;if(e.additional[0].test(r)){for(var i=0;7>i;i++)t+=+r.charAt(i)*e.multipliers[i];t=11-t%11,10===t&&(t=0),11===t&&(t=1);var s=+r.slice(7,8);return t===s}return!1}function e(r,e){var t=0;if(e.additional[2].test(r)){for(var i=0;7>i;i++)t+=+r.charAt(i+1)*e.multipliers[i];t=11-t%11,10===t&&(t=0),11===t&&(t=1);var s=+r.slice(8,9);return e.lookup[t-1]===s}return!1}function t(r,e){if(e.additional[3].test(r)){var t=+r.slice(0,2)+r.slice(2,4)+r.slice(4,6)+r.slice(6,8)+r.slice(8),i=+r%11===0;return!(t%11!==0||!i)}return!1}return{calcs:function(i){return r(i,this.rules)?!0:e(i,this.rules)?!0:!!t(i,this.rules)},rules:{multipliers:[8,7,6,5,4,3,2],lookup:[8,7,6,5,4,3,2,1,0,9,10],regex:/^(CZ)(\d{8,10})(\d{3})?$/,additional:[/^\d{8}$/,/^[0-5][0-9][0|1|5|6]\d[0-3]\d\d{3}$/,/^6\d{8}$/,/^\d{2}[0-3|5-8]\d[0-3]\d\d{4}$/]}}}(),u.denmark={calcs:function(r){for(var e=0,t=0;8>t;t++)e+=+r.charAt(t)*this.rules.multipliers[t];return e%11===0},rules:{multipliers:[2,7,6,5,4,3,2,1],regex:/^(DK)(\d{8})$/}},u.estonia={calcs:function(r){for(var e,t=0,i=0;8>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t=10-t%10,10===t&&(t=0),e=+r.slice(8,9),t===e},rules:{multipliers:[3,7,1,3,7,1,3,7],regex:/^(EE)(10\d{7})$/}},u.europe={calcs:function(r){return!0},rules:{regex:/^(EU)(\d{9})$/}},u.finland={calcs:function(r){for(var e,t=0,i=0;7>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t=11-t%11,t>9&&(t=0),e=+r.slice(7,8),t===e},rules:{multipliers:[7,9,10,5,8,4,2],regex:/^(FI)(\d{8})$/}},u.france={calcs:function(r){var e,t;return/^\d{11}$/.test(r)?(e=+r.substring(2),e=(100*e+12)%97,t=+r.slice(0,2),e===t):!0},rules:{regex:[/^(FR)(\d{11})$/,/^(FR)([A-HJ-NP-Z]\d{10})$/,/^(FR)(\d[A-HJ-NP-Z]\d{9})$/,/^(FR)([A-HJ-NP-Z]{2}\d{9})$/]}},u.germany={calcs:function(r){for(var e,t=10,i=0,s=0,l=0;8>l;l++)i=(+r.charAt(l)+t)%10,0===i&&(i=10),t=2*i%11;return s=11-t===10?0:11-t,e=+r.slice(8,9),s===e},rules:{regex:/^(DE)([1-9]\d{8})$/}},u.greece={calcs:function(r){var e,t=0;8===r.length&&(r="0"+r);for(var i=0;8>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t%=11,t>9&&(t=0),e=+r.slice(8,9),t===e},rules:{multipliers:[256,128,64,32,16,8,4,2],regex:/^(EL)(\d{9})$/}},u.hungary={calcs:function(r){for(var e,t=0,i=0;7>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t=10-t%10,10===t&&(t=0),e=+r.slice(7,8),t===e},rules:{multipliers:[9,7,3,1,9,7,3],regex:/^(HU)(\d{8})$/}},u.ireland={calcs:function(r){var e,t=0;this.rules.typeFormats.first.test(r)&&(r="0"+r.substring(2,7)+r.substring(0,1)+r.substring(7,8));for(var i=0;7>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return this.rules.typeFormats.third.test(r)&&(t+="H"===r.charAt(8)?72:9),t%=23,t=0===t?"W":String.fromCharCode(t+64),e=r.slice(7,8),t===e},rules:{multipliers:[8,7,6,5,4,3,2],typeFormats:{first:/^\d[A-Z\*\+]/,third:/^\d{7}[A-Z][AH]$/},regex:[/^(IE)(\d{7}[A-W])$/,/^(IE)([7-9][A-Z\*\+)]\d{5}[A-W])$/,/^(IE)(\d{7}[A-W][AH])$/]}},u.italy={calcs:function(r){var e,t,i=0;if(0===+r.slice(0,7))return!1;if(e=+r.slice(7,10),1>e||e>201&&999!==e&&888!==e)return!1;for(var s=0;10>s;s++)e=+r.charAt(s)*this.rules.multipliers[s],i+=e>9?Math.floor(e/10)+e%10:e;return i=10-i%10,i>9&&(i=0),t=+r.slice(10,11),i===t},rules:{multipliers:[1,2,1,2,1,2,1,2,1,2],regex:/^(IT)(\d{11})$/}},u.latvia={calcs:function(r){var e,t=0;if(/^[0-3]/.test(r))return!!/^[0-3][0-9][0-1][0-9]/.test(r);for(var i=0;10>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t%11===4&&9===r[0]&&(t-=45),t%11===4?t=4-t%11:t%11>4?t=14-t%11:4>t%11&&(t=3-t%11),e=+r.slice(10,11),t===e},rules:{multipliers:[9,1,4,8,3,10,2,5,7,6],regex:/^(LV)(\d{11})$/}},u.lithunia=function(){function r(r,e,t){return+r.charAt(t)*e[t]}function e(e,t,i){if(t%11===10){t=0;for(var s=0;8>s;s++)t+=r(e,i.multipliers["short"],s)}return t}function t(r,e){for(var t=0;8>t;t++)e+=+r.charAt(t)*(t+1);return e}function i(r){return r%=11,10===r&&(r=0),r}function s(r,s){var l=0;if(9===r.length){if(!/^\d{7}1/.test(r))return!1;l=t(r,l),l=e(r,l,s),l=i(l);var u=+r.slice(8,9);return l===u}return!1}function l(e,t,i){for(var s=0;11>s;s++)t+=r(e,i.multipliers.med,s);return t}function u(e,t,i){if(t%11===10){t=0;for(var s=0;11>s;s++)t+=r(e,i.multipliers.alt,s)}return t}function n(r,e){var t=0;if(12===r.length){if(!e.check.test(r))return!1;t=l(r,t,e),t=u(r,t,e),t=i(t);var s=+r.slice(11,12);return t===s}return!1}return{calcs:function(r){return s(r,this.rules)||n(r,this.rules)},rules:{multipliers:{"short":[3,4,5,6,7,8,9,1],med:[1,2,3,4,5,6,7,8,9,1,2],alt:[3,4,5,6,7,8,9,1,2,3,4]},check:/^\d{10}1/,regex:/^(LT)(\d{9}|\d{12})$/}}}(),u.luxembourg={calcs:function(r){var e=+r.slice(6,8),t=+r.slice(0,6)%89;return t===e},rules:{regex:/^(LU)(\d{8})$/}},u.malta={calcs:function(r){for(var e,t=0,i=0;6>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t=37-t%37,e=+r.slice(6,8),t===e},rules:{multipliers:[3,4,6,7,8,9],regex:/^(MT)([1-9]\d{7})$/}},u.netherlands={calcs:function(r){for(var e,t=0,i=0;8>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t%=11,t>9&&(t=0),e=+r.slice(8,9),t===e},rules:{multipliers:[9,8,7,6,5,4,3,2],regex:/^(NL)(\d{9})B\d{2}$/}},u.norway={calcs:function(r){for(var e,t=0,i=0;8>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t=11-t%11,11===t&&(t=0),10>t?(e=+r.slice(8,9),t===e):void 0},rules:{multipliers:[3,2,7,6,5,4,3,2],regex:/^(NO)(\d{9})$/}},u.poland={calcs:function(r){for(var e,t=0,i=0;9>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t%=11,t>9&&(t=0),e=+r.slice(9,10),t===e},rules:{multipliers:[6,5,7,2,3,4,5,6,7],regex:/^(PL)(\d{10})$/}},u.portugal={calcs:function(r){for(var e,t=0,i=0;8>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t=11-t%11,t>9&&(t=0),e=+r.slice(8,9),t===e},rules:{multipliers:[9,8,7,6,5,4,3,2],regex:/^(PT)(\d{9})$/}},u.romania={calcs:function(r){for(var e,t=0,i=r.length,s=this.rules.multipliers.slice(10-i),l=0;l<r.length-1;l++)t+=+r.charAt(l)*s[l];return t=10*t%11,10===t&&(t=0),e=+r.slice(r.length-1,r.length),t===e},rules:{multipliers:[7,5,3,2,1,7,5,3,2],regex:/^(RO)([1-9]\d{1,9})$/}},u.russia=function(){function r(r,e){var t=0;if(10===r.length){for(var i=0;10>i;i++)t+=+r.charAt(i)*e.multipliers.m_1[i];t%=11,t>9&&(t%=10);var s=+r.slice(9,10);return t===s}return!1}function e(r,e){var t=0,i=0;if(12===r.length){for(var s=0;11>s;s++)t+=+r.charAt(s)*e.multipliers.m_2[s];t%=11,t>9&&(t%=10);for(var l=0;11>l;l++)i+=+r.charAt(l)*e.multipliers.m_3[l];i%=11,i>9&&(i%=10);var u=t===+r.slice(10,11),n=i===+r.slice(11,12);return u&&n}return!1}return{calcs:function(t){return r(t,this.rules)||e(t,this.rules)},rules:{multipliers:{m_1:[2,4,10,3,5,9,4,6,8,0],m_2:[7,2,4,10,3,5,9,4,6,8,0],m_3:[3,7,2,4,10,3,5,9,4,6,8,0]},regex:/^(RU)(\d{10}|\d{12})$/}}}(),u.serbia={calcs:function(r){for(var e,t=10,i=0,s=0;8>s;s++)i=(+r.charAt(s)+t)%10,0===i&&(i=10),t=2*i%11;var l=1;return e=(t+ +r.slice(8,9))%10,e===l},rules:{regex:/^(RS)(\d{9})$/}},u.slovakia_republic={calcs:function(r){var e=0,t=r%11;return t===e},rules:{regex:/^(SK)([1-9]\d[2346-9]\d{7})$/}},u.slovenia={calcs:function(r){for(var e,t=0,i=0;7>i;i++)t+=+r.charAt(i)*this.rules.multipliers[i];return t=11-t%11,10===t&&(t=0),e=+r.slice(7,8),!(11===t||t!==e)},rules:{multipliers:[8,7,6,5,4,3,2],regex:/^(SI)([1-9]\d{7})$/}},u.spain={calcs:function(r){var e,t,i=0,s=0;if(this.rules.additional[0].test(r)){for(i=0;7>i;i++)e=r.charAt(i+1)*this.rules.multipliers[i],s+=e>9?Math.floor(e/10)+e%10:e;return s=10-s%10,10===s&&(s=0),t=+r.slice(8,9),s===t}if(this.rules.additional[1].test(r)){for(i=0;7>i;i++)e=r.charAt(i+1)*this.rules.multipliers[i],s+=e>9?Math.floor(e/10)+e%10:e;return s=10-s%10,s=String.fromCharCode(s+64),t=r.slice(8,9),s===t}if(this.rules.additional[2].test(r)){var l=r;return"Y"===l.substring(0,1)&&(l=l.replace(/Y/,"1")),"Z"===l.substring(0,1)&&(l=l.replace(/Z/,"2")),t="TRWAGMYFPDXBNJZSQVHLCKE".charAt(+l.substring(0,8)%23),l.charAt(8)===t}return this.rules.additional[3].test(r)?(t="TRWAGMYFPDXBNJZSQVHLCKE".charAt(+r.substring(1,8)%23),r.charAt(8)===t):!1},rules:{multipliers:[2,1,2,1,2,1,2],regex:[/^(ES)([A-Z]\d{8})$/,/^(ES)([A-HN-SW]\d{7}[A-J])$/,/^(ES)([0-9YZ]\d{7}[A-Z])$/,/^(ES)([KLMX]\d{7}[A-Z])$/],additional:[/^[A-H|J|U|V]\d{8}$/,/^[A-H|N-S|W]\d{7}[A-J]$/,/^[0-9|Y|Z]\d{7}[A-Z]$/,/^[K|L|M|X]\d{7}[A-Z]$/]}},u.sweden={calcs:function(r){for(var e,t,i=0,s=0;9>s;s+=2)t=+r.charAt(s),i+=Math.floor(t/5)+2*t%10;for(var l=0,u=1;9>u;u+=2)l+=+r.charAt(u);var n=(10-(i+l)%10)%10;return e=+r.slice(9,10),n===e},rules:{regex:/^(SE)(\d{10}01)$/}},u.switzerland={calcs:function(r){for(var e=0,t=0;8>t;t++)e+=+r.charAt(t)*this.rules.multipliers[t];if(e=11-e%11,10===e)return!1;11===e&&(e=0);var i=+r.substr(8,1);return e===i},rules:{multipliers:[5,4,3,2,7,6,5,4],regex:/^(CHE)(\d{9})(MWST)?$/}},u.united_kingdom={calcs:function(r){var e,t=0;if("GD"===r.substr(0,2))return e=500,r.substr(2,3)<e;if("HA"===r.substr(0,2))return e=499,r.substr(2,3)>e;if(0===+r.slice(0))return!1;for(var i=+r.slice(0,7),s=0;7>s;s++)t+=+r.charAt(s)*this.rules.multipliers[s];for(var l=t;l>0;)l-=97;return l=Math.abs(l),l===+r.slice(7,9)&&9990001>i&&(1e5>i||i>999999)&&(9490001>i||i>97e5)?!0:(l>=55?l-=55:l+=42,e=+r.slice(7,9),!!(l===e&&i>1e6))},rules:{multipliers:[8,7,6,5,4,3,2],regex:[/^(GB)?(\d{9})$/,/^(GB)?(\d{12})$/,/^(GB)?(GD\d{3})$/,/^(GB)?(HA\d{3})$/]}},"object"==typeof module&&module.exports&&(module.exports=n),n}();
//# sourceMappingURL=jsvat.min.js.map
'use strict';
var gulp = require('gulp'), rename, uglify, sourcemaps, jshint, size, buddyjs, todo;
var gulp = require('gulp');
var config = require('./build/config.js');
var requireDir = require('require-dir');
requireDir('./build', { recurse: true });
var src = {
jsDir: [
'src/**/*.js'
]
};
var dest = {
dist: 'dist'
};
gulp.task('lint', function () {
jshint = jshint || require('gulp-jshint');
return gulp.src(src.jsDir)
.pipe(jshint({
globalstrict: true,
strict: false,
globals: {
angular: true,
localStorage: true,
console: true
}
}))
.pipe(jshint.reporter('jshint-stylish'));
gulp.task('default', function () {
gulp.start('make');
gulp.start('watch');
});
gulp.task('webstandards', function () {
var webstandards = require('gulp-webstandards');
return gulp.src(src.jsDir)
.pipe(webstandards());
});
gulp.task('magic_numbers', function () {
buddyjs = buddyjs || require('gulp-buddy.js');
return gulp.src(src.jsDir)
.pipe(buddyjs({
ignore: [0, 1, 2],
reporter: 'detailed'
}));
});
gulp.task('sizes', function () {
size = size || require('gulp-size');
return gulp.src([
'dist/**/*.js',
'dist/**/*.css',
'dist/**/*.gz'
]).pipe(size({showFiles: true, showTotal: true}));
});
gulp.task('js', function () {
sourcemaps = sourcemaps || require('gulp-sourcemaps');
uglify = uglify || require('gulp-uglify');
rename = rename || require('gulp-rename');
return gulp.src(src.jsDir)
.pipe(gulp.dest(dest.dist))
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(rename({basename: 'jsvat.min'}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dest.dist))
;
});
gulp.task('todo', function () {
todo = require('gulp-todo');
gulp.src('src/**/*.*')
.pipe(todo())
.pipe(gulp.dest('./'));
});
gulp.task('watch', function () {
var watch = require('gulp-watch');
gulp.watch(src.jsDir, ['js', 'todo']);
});
gulp.task('build', function () {
gulp.start('js');
gulp.start('todo');
});
gulp.task('default', function () {
gulp.start('build');
gulp.start('watch');
});
gulp.watch(config.js.src, ['js', 'todo']);
});
{
"name": "jsvat",
"version": "0.6.1",
"version": "0.9.0",
"description": "Check the validity of the format of an EU VAT number",
"main": "./dist/jsvat.js",
"scripts": {
"test": "mocha"
"test": "mocha \"test/acceptance/test_cases.js\""
},

@@ -41,4 +41,9 @@ "license": "MIT",

"chai": "^3.5.0",
"gulp-beautify": "^2.0.0",
"gulp-buddy.js": "^1.0.0",
"gulp-concat": "^2.6.0",
"gulp-gzip": "^1.2.0",
"gulp-jshint": "^2.0.0",
"gulp-notify": "^2.2.0",
"gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",

@@ -54,4 +59,6 @@ "gulp-size": "^2.1.0",

"jshint-stylish": "^2.1.0",
"mocha": "^2.4.5"
"mocha": "^2.4.5",
"require-dir": "^0.3.0",
"run-sequence": "^1.1.5"
}
}
### TODOs
| Filename | line # | TODO
|:------|:------:|:------
| jsvat.js | 207 | (S.Panfilov) this is not cross-browser check
| jsvat.js | 589 | (S.Panfilov) wtf?
| main.js | 27 | (S.Panfilov) this is not cross-browser check

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc