Socket
Socket
Sign inDemoInstall

angular-jsvat

Package Overview
Dependencies
0
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.6.1-1 to 1.1.0

.idea/watcherTasks.xml

16

bower.json
{
"name": "angular-jsvat",
"version": "0.6.1-1",
"version": "1.1.0",
"description": "Check the validity of the format of an EU VAT number",
"main": "./dist/angular-jsvat.js",
"scripts": {
},
"scripts": {},
"license": "MIT",

@@ -16,4 +15,7 @@ "repository": {

},
"ignore": {},
"ignore": [
".lib/"
],
"keywords": [
"angular",
"jsvat",

@@ -38,3 +40,7 @@ "angular-jsvat",

"author": "S.Panfilov <se-panfilov@ya.ru> (https://se-panfilov.github.io)",
"private": false
"private": false,
"dependencies": {},
"devDependencies": {
"jsvat": "1.1.0"
}
}

@@ -1,1115 +0,1655 @@

angular.module('jsvat', [])
.factory('JsVatFactory', function () {
var jsvat = (function () {
'use strict';
angular.module('angular-jsvat', ['angular-jsvat-input'])
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})$/
]
.factory('JsVatFactory', function() {
},
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})$/
]
var jsvat = (function() {
},
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])$/
]
'use strict';
},
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)$/
}
};
var COUNTRIES = {};
function _validateRegex(vat, regex) {
return regex.test(vat);
return regex.test(vat);
}
function _validateRules(vat, regex, countryName) {
var parsedNum = regex.exec(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);
}
function _validate(vat, regex, countryName) {
var result = false;
if (_validateRegex(vat, regex)) {
result = _validateRules(vat, regex, countryName);
}
return result;
var result = false;
if (_validateRegex(vat, regex)) {
result = _validateRules(vat, regex, countryName);
}
return result;
}
function _getPureVAT(vat) {
vat = vat || '';
return vat.toString().toUpperCase().replace(/(\s|-|\.)+/g, '');
}
function _isCountryBlocked(config, countryName) {
if (!config || config.length === 0) return false;
return config.indexOf(countryName) === -1;
}
function checkValidity(vat, countryName) {
var regexArr = COUNTRIES[countryName].rules.regex;
for (var i = 0; i < regexArr.length; i++) {
var isValid = _validate(vat, regexArr[i], countryName);
if (isValid) return isValid && !_isCountryBlocked(exports.config, countryName);
}
return false;
}
var exports = {
checkVAT: function (vat) {
if (!vat) return false;
vat = vat.toString().toUpperCase().replace(/(\s|-|\.)+/g, '');
config: [],
checkVAT: function(vat) {
var result = {
value: _getPureVAT(vat),
isValid: false,
country: null
};
for (var countryName in CONDITIONS) {
if (CONDITIONS.hasOwnProperty(countryName)) {
var regex = CONDITIONS[countryName].regex;
if (!vat) return result;
//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;
}
} else {
if (_validate(vat, regex, countryName)) return true;
}
}
for (var countryName in COUNTRIES) {
if (COUNTRIES.hasOwnProperty(countryName)) {
result.isValid = checkValidity(result.value, countryName);
if (result.isValid) {
result.country = countryName;
return result;
}
return false;
}
}
return result;
}
};
COUNTRIES.austria = {
calcs: function(vat) {
var total = 0;
var temp;
for (var i = 0; i < 7; i++) {
temp = vat.charAt(i) * this.rules.multipliers[i];
if (temp > 9) {
total += Math.floor(temp / 10) + temp % 10;
} else {
total += temp;
}
}
total = 10 - (total + 4) % 10;
if (total === 10) total = 0;
return total === +vat.slice(7, 8);
},
rules: {
multipliers: [
1,
2,
1,
2,
1,
2,
1
],
regex: [/^(AT)U(\d{8})$/]
}
};
COUNTRIES.belgium = {
calcs: function(vat) {
if (vat.length === 9) {
vat = '0' + vat;
}
var expect;
var temp;
if (+vat.slice(1, 2) === 0) return false;
var _checks = {
austria: function (vat, countryName) {
var total = 0;
for (var i = 0; i < 7; i++) {
temp = vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
if (temp > 9)
total += Math.floor(temp / 10) + temp % 10;
else
total += temp;
}
var check = (97 - +vat.slice(0, 8) % 97);
return check === +vat.slice(8, 10);
},
rules: {
regex: [/^(BE)(0?\d{9})$/]
}
};
COUNTRIES.bulgaria = (function() {
total = 10 - (total + 4) % 10;
if (total === 10) total = 0;
function _checkNineLengthVat(vat) {
var total;
var temp = 0;
var expect = +vat.slice(8);
expect = +vat.slice(7, 8);
for (var i = 0; i < 8; i++) {
temp += +vat.charAt(i) * (i + 1);
}
return total === expect;
},
belgium: function (vat) {
if (vat.length === 9) {
vat = '0' + vat;
total = temp % 11;
if (total !== 10) {
return total === expect;
}
temp = 0;
for (var j = 0; j < 8; j++) {
temp += +vat.charAt(j) * (j + 3);
}
total = temp % 11;
if (total === 10) total = 0;
return total === expect;
}
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;
if (+vat.slice(1, 2) === 0) return false;
// 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;
}
}
var check = (97 - +vat.slice(0, 8) % 97);
expect = +vat.slice(8, 10);
return check === expect;
return false;
}
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];
}
// 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;
}
}
function _miscellaneousVAT(vat, rules) {
var total = 0;
// 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];
}
// 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(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);
}
},
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: {
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;
total = temp % 11;
if (total !== 10) {
expect = +vat.slice(8);
return total === 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;
},
rules: {
regex: [/^(HR)(\d{11})$/]
}
};
COUNTRIES.cyprus = {
calcs: function(vat) {
var total = 0;
var expect;
// Not allowed to start with '12'
if (+vat.slice(0, 2) === 12) return false;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
var temp = +vat.charAt(i);
if (i % 2 === 0) {
switch (temp) {
case 0:
temp = 1;
break;
case 1:
temp = 0;
for (var j = 0; j < 8; j++) {
temp += +vat.charAt(j) * (j + 3);
}
break;
case 2:
temp = 5;
break;
case 3:
temp = 7;
break;
case 4:
temp = 9;
break;
default:
temp = temp * 2 + 3;
}
}
total += temp;
}
total = temp % 11;
if (total === 10) total = 0;
expect = +vat.slice(8);
// Establish check digit using modulus 26, and translate to char. equivalent.
total = total % 26;
total = String.fromCharCode(total + 65);
return total === expect;
};
// Check to see if the check digit given is correct
expect = vat.substr(8, 1);
return total === expect;
},
rules: {
regex: [/^(CY)([0-59]\d{7}[A-Z])$/]
}
};
COUNTRIES.czech_republic = (function() {
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)) {
function _isLegalEntities(vat, rules) {
var total = 0;
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;
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) * rules.multipliers[i];
}
// 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;
}
}
// Establish check digit.
total = 11 - total % 11;
if (total === 10) total = 0;
if (total === 11) total = 1;
return false;
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
var expect = +vat.slice(7, 8);
return total === expect;
}
};
return false;
}
// 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];
}
function _isIndividualType2(vat, rules) {
var total = 0;
// 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;
}
};
if (rules.additional[2].test(vat)) {
var miscellaneousVAT = function () {
var total = 0;
// Finally, if not yet identified, see if it conforms to a miscellaneous VAT number
// Extract the next digit and multiply by the counter.
for (var j = 0; j < 7; j++) {
total += +vat.charAt(j + 1) * rules.multipliers[j];
}
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) total = 0;
if (total === 11) total = 1;
// Establish check digit.
total = 11 - total % 11;
if (total === 10) return false;
if (total === 11) total = 0;
// Convert calculated check digit according to a lookup table;
var expect = +vat.slice(8, 9);
return rules.lookup[total - 1] === expect;
}
// 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;
};
return false;
}
if (vat.length === 9) {
return checkNineLengthVat();
} else {
return isPhysicalPerson() || isForeigner() || miscellaneousVAT();
}
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);
var expect = +vat % 11 === 0;
return !!(temp % 11 === 0 && expect);
}
},
switzerland: function (vat, countryName) {
var total = 0;
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
return false;
}
// Establish check digit.
total = 11 - total % 11;
if (total === 10) return false;
if (total === 11) total = 0;
return {
calcs: function(vat) {
// 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);
return total === expect;
if (_isLegalEntities(vat, this.rules)) return true;
if (_isIndividualType2(vat, this.rules)) return true;
if (_isIndividualType3(vat, this.rules)) return true;
return false;
},
cyprus: function (vat) {
var total = 0;
// Not allowed to start with '12'
if (+vat.slice(0, 2) === 12) 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;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
for (var i = 0; i < 8; i++) {
var temp = +vat.charAt(i);
if (i % 2 === 0) {
switch (temp) {
case 0:
temp = 1;
break;
case 1:
temp = 0;
break;
case 2:
temp = 5;
break;
case 3:
temp = 7;
break;
case 4:
temp = 9;
break;
default:
temp = temp * 2 + 3;
}
}
total += temp;
}
return total % 11 === 0;
},
rules: {
multipliers: [
2,
7,
6,
5,
4,
3,
2,
1
],
regex: [/^(DK)(\d{8})$/]
}
};
COUNTRIES.estonia = {
calcs: function(vat) {
var total = 0;
var expect;
// Establish check digit using modulus 26, and translate to char. equivalent.
total = total % 26;
total = String.fromCharCode(total + 65);
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// Check to see if the check digit given is correct
expect = vat.substr(8, 1);
return total === expect;
},
czech_republic: function (vat, countryName) {
var total = 0;
// Establish check digits using modulus 10.
total = 10 - total % 10;
if (total === 10) total = 0;
// Legal entities
if (CONDITIONS[countryName].additional[0].test(vat)) {
// 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;
},
rules: {
multipliers: [
3,
7,
1,
3,
7,
1,
3,
7
],
regex: [/^(EE)(10\d{7})$/]
}
};
COUNTRIES.europe = {
calcs: function() {
// We know little about EU numbers apart from the fact that the first 3 digits represent the
// country, and that there are nine digits in total.
return true;
},
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];
}
// 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 digit.
total = 11 - total % 11;
if (total === 10) total = 0;
if (total === 11) total = 1;
// Establish check digit.
total = 11 - 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(7, 8);
return total === expect;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(7, 8);
return total === expect;
},
rules: {
multipliers: [
7,
9,
10,
5,
8,
4,
2
],
regex: [/^(FI)(\d{8})$/]
}
};
COUNTRIES.france = {
calcs: function(vat) {
var total;
var expect;
// Individuals type 2
else if (CONDITIONS[countryName].additional[2].test(vat)) {
// Checks the check digits of a French VAT number.
if (!(/^\d{11}$/).test(vat)) {
return true;
}
// 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];
}
// Extract the last nine digits as an integer.
total = +vat.substring(2);
// Establish check digit.
total = 11 - total % 11;
if (total === 10) total = 0;
if (total === 11) total = 1;
// Establish check digit.
total = (total * 100 + 12) % 97;
// Convert calculated check digit according to a lookup table;
expect = +vat.slice(8, 9);
return CONDITIONS[countryName].lookup[total - 1] === expect;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(0, 2);
return total === 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;
// Individuals type 3
else if (CONDITIONS[countryName].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;
return !!(temp % 11 === 0 && expect);
}
for (var i = 0; i < 8; i++) {
// else error
return false;
},
germany: function (vat) {
// Extract the next digit and implement peculiar algorithm!.
sum = (+vat.charAt(i) + product) % 10;
if (sum === 0) {
sum = 10;
}
product = (2 * sum) % 11;
}
// Establish check digit.
if (11 - product === 10) {
checkDigit = 0;
} else {
checkDigit = 11 - product;
}
// Checks the check digits of a German VAT number.
// 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;
},
rules: {
regex: [/^(DE)([1-9]\d{8})$/]
}
};
COUNTRIES.greece = {
calcs: function(vat) {
var total = 0;
var expect;
var product = 10;
var sum = 0;
var checkDigit = 0;
for (var i = 0; i < 8; i++) {
//eight character numbers should be prefixed with an 0.
if (vat.length === 8) {
vat = '0' + vat;
}
// Extract the next digit and implement peculiar algorithm!.
sum = (+vat.charAt(i) + product) % 10;
if (sum === 0) {
sum = 10;
}
product = (2 * sum) % 11;
}
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// Establish check digit.
if (11 - product === 10) {
checkDigit = 0;
} else {
checkDigit = 11 - product;
}
// Establish check digit.
total = total % 11;
if (total > 9) {
total = 0;
}
// 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];
}
// 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;
},
rules: {
multipliers: [
256,
128,
64,
32,
16,
8,
4,
2
],
regex: [/^(EL)(\d{9})$/]
}
};
COUNTRIES.hungary = {
calcs: function(vat) {
var total = 0;
var expect;
return total % 11 === 0;
},
estonia: function (vat, countryName) {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
// 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 10.
total = 10 - total % 10;
if (total === 10) total = 0;
// Establish check digit.
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;
},
greece: function (vat, countryName) {
var total = 0;
//eight character numbers should be prefixed with an 0.
if (vat.length === 8) {
vat = '0' + vat;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(7, 8);
return total === expect;
},
rules: {
multipliers: [
9,
7,
3,
1,
9,
7,
3
],
regex: [/^(HU)(\d{8})$/]
}
};
COUNTRIES.ireland = {
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];
}
// If the code is type 1 format, we need to convert it to the new before performing the validation.
if (this.rules.typeFormats.first.test(vat)) {
vat = '0' + vat.substring(2, 7) + vat.substring(0, 1) + vat.substring(7, 8);
}
// Establish check digit.
total = total % 11;
if (total > 9) {
total = 0;
}
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// 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;
// If the number is type 3 then we need to include the trailing A or H in the calculation
if (this.rules.typeFormats.third.test(vat)) {
// Add in a multiplier for the character A (1*9=9) or H (8*9=72)
if (vat.charAt(8) === 'H') {
total += 72;
} else {
total += 9;
}
}
// Establish check digit using modulus 23, and translate to char. equivalent.
total = total % 23;
if (total === 0) {
total = 'W';
} else {
total = String.fromCharCode(total + 64);
}
// Compare it with the eighth character of the VAT number. If it's the same, then it's valid.
expect = vat.slice(7, 8);
return total === expect;
},
rules: {
multipliers: [
8,
7,
6,
5,
4,
3,
2
],
typeFormats: {
first: /^\d[A-Z\*\+]/,
third: /^\d{7}[A-Z][AH]$/
},
spain: function (vat, countryName) {
var i = 0;
var total = 0;
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;
// National juridical entities
if (CONDITIONS[countryName].additional[0].test(vat)) {
// The last three digits are the issuing office, and cannot exceed more 201, unless 999 or 888
if (+vat.slice(0, 7) === 0) {
return false;
}
// 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;
}
temp = +vat.slice(7, 10);
if ((temp < 1) || (temp > 201) && temp !== 999 && temp !== 888) {
return false;
}
// 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;
}
// Extract the next digit and multiply by the appropriate
for (var i = 0; i < 10; i++) {
temp = +vat.charAt(i) * this.rules.multipliers[i];
if (temp > 9)
total += Math.floor(temp / 10) + temp % 10;
else
total += temp;
}
// Juridical entities other than national ones
else if (CONDITIONS[countryName].additional[1].test(vat)) {
// Establish check digit.
total = 10 - total % 10;
if (total > 9) {
total = 0;
}
// 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;
}
// 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: [
1,
2,
1,
2,
1,
2,
1,
2,
1,
2
],
regex: [/^(IT)(\d{11})$/]
}
};
COUNTRIES.latvia = {
calcs: function(vat) {
var total = 0;
var expect;
// Now calculate the check digit itself.
total = 10 - total % 10;
total = String.fromCharCode(total + 64);
// 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 {
// 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;
}
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 10; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// 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;
}
// Establish check digits by getting modulus 11.
if (total % 11 === 4 && vat[0] === 9) total = total - 45;
// 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;
}
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;
}
else return false;
},
europe: function () {
//TODO (S.Panfilov) wtf?
// We know little about EU numbers apart from the fact that the first 3 digits represent the
// country, and that there are nine digits in total.
return true;
},
finland: function (vat, countryName) {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
// 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() {
// Establish check digit.
total = 11 - total % 11;
if (total > 9) {
total = 0;
}
function _extractDigit(vat, multiplier, key) {
return +vat.charAt(key) * multiplier[key];
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(7, 8);
return total === expect;
},
france: function (vat) {
var total;
// Checks the check digits of a French VAT number.
if (!(/^\d{11}$/).test(vat)) {
return true;
}
// Extract the last nine digits as an integer.
total = +vat.substring(2);
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);
}
}
// Establish check digit.
total = (total * 100 + 12) % 97;
return total;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(0, 2);
return total === expect;
},
united_kingdom: function (vat, countryName) {
var total = 0;
// Government departments
if (vat.substr(0, 2) === 'GD') {
expect = 500;
return vat.substr(2, 3) < expect;
}
function extractDigit(vat, total) {
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * (i + 1);
}
return total;
}
// Health authorities
if (vat.substr(0, 2) === 'HA') {
expect = 499;
return vat.substr(2, 3) > expect;
}
function checkDigit(total) {
total = total % 11;
if (total === 10) {
total = 0;
}
// Standard and commercial numbers
return total;
}
function _check9DigitVat(vat, rules) {
// 9 character VAT numbers are for legal persons
var total = 0;
if (vat.length === 9) {
// 0 VAT numbers disallowed!
if (+vat.slice(0) === 0) return false;
// 8th character must be one
if (!(/^\d{7}1/).test(vat)) 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+1.
total = extractDigit(vat, total);
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
// Can have a double check digit calculation!
total = _doubleCheckCalculation(vat, total, rules);
// 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 digit.
total = checkDigit(total);
// Establish check digits by subtracting 97 from total until negative.
var checkDigit = total;
while (checkDigit > 0) {
checkDigit = checkDigit - 97;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
var expect = +vat.slice(8, 9);
return total === expect;
}
return false;
}
// 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;
function extractDigit12(vat, total, rules) {
for (var k = 0; k < 11; k++) {
total += _extractDigit(vat, rules.multipliers.med, k);
}
return total;
}
// 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);
},
croatia: function (vat) {
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;
}
// Checks the check digits of a Croatian VAT number using ISO 7064, MOD 11-10 for check digit.
function _check12DigitVat(vat, rules) {
var total = 0;
var product = 10;
var sum = 0;
// 12 character VAT numbers are for temporarily registered taxpayers
if (vat.length === 12) {
for (var i = 0; i < 10; i++) {
// 11th character must be one
if (!(rules.check).test(vat)) return false;
// Extract the next digit and implement the algorithm
sum = (+vat.charAt(i) + product) % 10;
if (sum === 0) {
sum = 10;
}
// Extract the next digit and multiply by the counter+1.
total = extractDigit12(vat, total, rules);
product = (2 * sum) % 11;
}
// Can have a double check digit calculation!
total = _doubleCheckCalculation12(vat, total, rules);
// Now check that we have the right check digit
expect = +vat.slice(10, 11);
return (product + expect) % 10 === 1;
},
hungary: function (vat, countryName) {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
// Establish check digit.
total = checkDigit(total);
// Establish check digit.
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.
var expect = +vat.slice(11, 12);
return total === expect;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(7, 8);
return total === expect;
return false;
}
return {
calcs: function(vat) {
return _check9DigitVat(vat, this.rules) || _check12DigitVat(vat, this.rules);
},
ireland: function (vat, countryName) {
var total = 0;
// 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)) {
vat = '0' + vat.substring(2, 7) + vat.substring(0, 1) + vat.substring(7, 8);
}
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);
var checkDigit = +vat.slice(0, 6) % 89;
// Checks the check digits of a Luxembourg VAT number.
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
return checkDigit === expect;
},
rules: {
regex: [/^(LU)(\d{8})$/]
}
};
COUNTRIES.malta = {
calcs: function(vat) {
var total = 0;
var expect;
// 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)) {
// Add in a multiplier for the character A (1*9=9) or H (8*9=72)
if (vat.charAt(8) === 'H') {
total += 72;
} else {
total += 9;
}
}
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 6; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// Establish check digit using modulus 23, and translate to char. equivalent.
total = total % 23;
if (total === 0) {
total = 'W';
} else {
total = String.fromCharCode(total + 64);
}
// Establish check digits by getting modulus 37.
total = 37 - total % 37;
// Compare it with the eighth character of the VAT number. If it's the same, then it's valid.
expect = vat.slice(7, 8);
return total === expect;
},
italy: function (vat, countryName) {
var total = 0;
// The last three digits are the issuing office, and cannot exceed more 201, unless 999 or 888
if (+vat.slice(0, 7) === 0) {
return false;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(6, 8);
return total === expect;
},
rules: {
multipliers: [
3,
4,
6,
7,
8,
9
],
regex: [/^(MT)([1-9]\d{7})$/]
}
};
COUNTRIES.netherlands = {
calcs: function(vat) {
var total = 0;
var expect;
temp = +vat.slice(7, 10);
if ((temp < 1) || (temp > 201) && temp !== 999 && temp !== 888) {
return false;
}
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// Extract the next digit and multiply by the appropriate
for (var i = 0; i < 10; i++) {
temp = +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
if (temp > 9)
total += Math.floor(temp / 10) + temp % 10;
else
total += temp;
}
// Establish check digits by getting modulus 11.
total = total % 11;
if (total > 9) {
total = 0;
}
// Establish check digit.
total = 10 - total % 10;
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;
},
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
// 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;
},
lithunia: function (vat, countryName) {
var total = 0;
// 9 character VAT numbers are for legal persons
if (vat.length === 9) {
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// 8th character must be one
if (!(/^\d{7}1/).test(vat)) return false;
// Establish check digits by getting modulus 11. Check digits > 9 are invalid
total = 11 - total % 11;
// 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);
}
if (total === 11) {
total = 0;
}
// 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];
}
}
if (total < 10) {
// 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;
}
},
rules: {
multipliers: [
3,
2,
7,
6,
5,
4,
3,
2
],
regex: [/^(NO)(\d{9})$/]
}
};
COUNTRIES.poland = {
calcs: function(vat) {
var total = 0;
var expect;
// Establish check digit.
total = total % 11;
if (total === 10) {
total = 0;
}
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 9; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// 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;
}
// Establish check digits subtracting modulus 11 from 11.
total = total % 11;
if (total > 9) {
total = 0;
}
// 12 character VAT numbers are for temporarily registered taxpayers
else {
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(9, 10);
return total === expect;
},
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;
// 11th character must be one
if (!(/^\d{10}1/).test(vat)) return false;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// 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];
}
// Establish check digits subtracting modulus 11 from 11.
total = 11 - total % 11;
if (total > 9) {
total = 0;
}
// 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];
}
}
// 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;
},
rules: {
multipliers: [
9,
8,
7,
6,
5,
4,
3,
2
],
regex: [/^(PT)(\d{9})$/]
}
};
COUNTRIES.romania = {
calcs: function(vat) {
var total = 0;
var expect;
// Establish check digit.
total = total % 11;
if (total === 10) {
total = 0;
}
// Extract the next digit and multiply by the counter.
var vatLength = vat.length;
var multipliers = this.rules.multipliers.slice(10 - vatLength);
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(11, 12);
return total === expect;
}
},
luxembourg: function (vat) {
var expect = +vat.slice(6, 8);
var checkDigit = +vat.slice(0, 6) % 89;
// Checks the check digits of a Luxembourg VAT number.
for (var i = 0; i < vat.length - 1; i++) {
total += +vat.charAt(i) * multipliers[i];
}
return checkDigit === expect;
},
latvia: function (vat, countryName) {
var total = 0;
// Establish check digits by getting modulus 11.
total = (10 * total) % 11;
if (total === 10) total = 0;
// 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 {
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(vat.length - 1, vat.length);
return total === expect;
},
rules: {
multipliers: [
7,
5,
3,
2,
1,
7,
5,
3,
2
],
regex: [/^(RO)([1-9]\d{1,9})$/]
}
};
COUNTRIES.russia = (function() {
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 10; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
function _check10DigitINN(vat, rules) {
var total = 0;
// 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;
if (vat.length === 10) {
// 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];
}
for (var i = 0; i < 10; i++) {
total += +vat.charAt(i) * rules.multipliers.m_1[i];
}
// Establish check digits by getting modulus 37.
total = 37 - total % 37;
total = total % 11;
if (total > 9) {
total = total % 10;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(6, 8);
return total === expect;
},
netherlands: function (vat, countryName) {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
// Compare it with the last character of the VAT number. If it is the same, then it's valid
var expect = +vat.slice(9, 10);
return total === expect;
}
// Establish check digits by getting modulus 11.
total = total % 11;
if (total > 9) {
total = 0;
}
return false;
}
// 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;
},
norway: function (vat, countryName) {
var total = 0;
// See http://www.brreg.no/english/coordination/number.html
function _check12DigitINN(vat, rules) {
var total1 = 0;
var total2 = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
if (vat.length === 12) {
// Establish check digits by getting modulus 11. Check digits > 9 are invalid
total = 11 - total % 11;
if (total === 11) {
total = 0;
}
if (total < 10) {
for (var j = 0; j < 11; j++) {
total1 += +vat.charAt(j) * rules.multipliers.m_2[j];
}
// 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;
}
},
poland: function (vat, countryName) {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 9; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
total1 = total1 % 11;
// Establish check digits subtracting modulus 11 from 11.
total = total % 11;
if (total > 9) {
total = 0;
}
if (total1 > 9) {
total1 = total1 % 10;
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(9, 10);
return total === expect;
},
portugal: function (vat, countryName) {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 8; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
for (var k = 0; k < 11; k++) {
total2 += +vat.charAt(k) * rules.multipliers.m_3[k];
}
// Establish check digits subtracting modulus 11 from 11.
total = 11 - total % 11;
if (total > 9) {
total = 0;
}
total2 = total2 % 11;
if (total2 > 9) {
total2 = total2 % 10;
}
// 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;
},
romania: function (vat, countryName) {
var total = 0;
// Extract the next digit and multiply by the counter.
var vatLength = vat.length;
var multipliers = CONDITIONS[countryName].multipliers.slice(10 - vatLength);
// Compare the first check with the 11th character and the second check with the 12th and last
// character of the VAT number. If they're both the same, then it's valid
var expect = (total1 === +vat.slice(10, 11));
var expect2 = (total2 === +vat.slice(11, 12));
return (expect) && (expect2);
}
for (var i = 0; i < vat.length - 1; i++) {
total += +vat.charAt(i) * multipliers[i];
}
return false;
}
// Establish check digits by getting modulus 11.
total = (10 * total) % 11;
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(vat.length - 1, vat.length);
return total === expect;
return {
calcs: function(vat) {
// See http://russianpartner.biz/test_inn.html for algorithm
return _check10DigitINN(vat, this.rules) || _check12DigitINN(vat, this.rules);
},
serbia: function (vat) {
// Checks the check digits of a Serbian VAT number using ISO 7064, MOD 11-10 for check digit.
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;
var product = 10;
var sum = 0;
var checkDigit;
for (var i = 0; i < 8; i++) {
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;
}
// 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) {
var total = 0;
var expect2;
// Now check that we have the right check digit
var expect = 1;
checkDigit = (product + (+vat.slice(8, 9))) % 10;
return checkDigit === expect;
},
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;
// Checks the check digits of a Russian INN number
// See http://russianpartner.biz/test_inn.html for algorithm
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * this.rules.multipliers[i];
}
// 10 digit INN numbers
if (vat.length === 10) {
// Establish check digits using modulus 11
total = 11 - total % 11;
if (total === 10) {
total = 0;
}
for (var i = 0; i < 10; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers.m_1[i];
}
// 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;
total = total % 11;
if (total > 9) {
total = total % 10;
}
// National juridical entities
if (this.rules.additional[0].test(vat)) {
// Compare it with the last character of the VAT number. If it is the same, then it's valid
expect = +vat.slice(9, 10);
return total === expect;
// 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;
}
// 12 digit INN numbers
} else if (vat.length === 12) {
var total1 = 0;
var total2 = 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;
}
for (var j = 0; j < 11; j++) {
total1 += +vat.charAt(j) * CONDITIONS[countryName].multipliers.m_2[j];
}
// Juridical entities other than national ones
else if (this.rules.additional[1].test(vat)) {
total1 = total1 % 11;
if (total1 > 9) {
total1 = total1 % 10;
}
// 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;
}
for (var k = 0; k < 11; k++) {
total2 += +vat.charAt(k) * CONDITIONS[countryName].multipliers.m_3[k];
}
// Now calculate the check digit itself.
total = 10 - total % 10;
total = String.fromCharCode(total + 64);
total2 = total2 % 11;
if (total2 > 9) {
total2 = total2 % 10;
}
// 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;
}
// Compare the first check with the 11th character and the second check with the 12th and last
// 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));
return (expect) && (expect2);
}
},
sweden: function (vat) {
// Calculate R where R = R1 + R3 + R5 + R7 + R9, and Ri = INT(Ci/5) + (Ci*2) modulo 10
var R = 0;
var digit;
for (var i = 0; i < 9; i = i + 2) {
digit = +vat.charAt(i);
R += Math.floor(digit / 5) + ((digit * 2) % 10);
}
// 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;
}
// Calculate S where S = C2 + C4 + C6 + C8
var S = 0;
for (var j = 1; j < 9; j = j + 2) {
S += +vat.charAt(j);
}
// 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;
var checkDigit = (10 - (R + S) % 10) % 10;
// Calculate R where R = R1 + R3 + R5 + R7 + R9, and Ri = INT(Ci/5) + (Ci*2) modulo 10
var R = 0;
var digit;
for (var i = 0; i < 9; i = i + 2) {
digit = +vat.charAt(i);
R += Math.floor(digit / 5) + ((digit * 2) % 10);
}
// Compare it with the last character of the VAT number. If it's the same, then it's valid.
expect = +vat.slice(9, 10);
// Calculate S where S = C2 + C4 + C6 + C8
var S = 0;
for (var j = 1; j < 9; j = j + 2) {
S += +vat.charAt(j);
}
return checkDigit === expect;
},
slovenia: function (vat, countryName) {
var total = 0;
// Extract the next digit and multiply by the counter.
for (var i = 0; i < 7; i++) {
total += +vat.charAt(i) * CONDITIONS[countryName].multipliers[i];
}
var checkDigit = (10 - (R + S) % 10) % 10;
// Establish check digits using modulus 11
total = 11 - total % 11;
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(9, 10);
// 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);
},
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;
return checkDigit === expect;
},
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) * this.rules.multipliers[i];
}
// 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;
}
// 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);
},
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;
})();
return jsvat;});
})();
return jsvat;
});
'use strict';
angular.module('angular-jsvat-input', [])
.directive('jsvat', ['JsVatFactory', function (JsVatFactory) {
return {
restrict: 'A',
scope: {
jsvat: '=?'
},
require: 'ngModel',
link: function (scope, element) {
function makeObj(name) {
if (!angular.isObject(scope[name])) {
var value = scope[name];
scope[name] = {
value: value
}
}
}
makeObj('jsvat');
var invalid = '-jsvat-invalid';
var valid = '-jsvat-valid';
function setValidity(isValid) {
if (isValid) {
element.addClass(valid);
element.removeClass(invalid);
} else {
element.addClass(invalid);
element.removeClass(valid);
}
modelController.$setValidity('vat', isValid);
}
var modelController = element.controller('ngModel');
scope.checkVAT = function (vat) {
scope.jsvat = JsVatFactory.checkVAT(vat);
var isEmpty = scope.jsvat.value === '' || (!scope.jsvat.value && scope.jsvat.value !== '0');
setValidity(scope.jsvat.isValid || isEmpty);
//setValidity(scope.jsvat.isValid);
};
scope.$watch(function () {
return modelController.$modelValue;
}, function (val) {
scope.checkVAT(val);
});
}
}
}])
;

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

angular.module("jsvat",[]).factory("JsVatFactory",function(){var r=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}();return r});
angular.module("angular-jsvat",["angular-jsvat-input"]).factory("JsVatFactory",function(){var r=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=r||"",r.toString().toUpperCase().replace(/(\s|-|\.)+/g,"")}function s(r,e){return r&&0!==r.length?-1===r.indexOf(e):!1}function l(r,e){for(var i=u[e].rules.regex,l=0;l<i.length;l++){var a=t(r,i[l],e);if(a)return a&&!s(n.config,e)}return!1}var u={},n={config:[],checkVAT:function(r){var e={value:i(r),isValid:!1,country:null};if(!r)return e;for(var t in u)if(u.hasOwnProperty(t)&&(e.isValid=l(e.value,t),e.isValid))return e.country=t,e;return e}};return u.austria={calcs:function(r){for(var e,t=0,i=0;7>i;i++)e=r.charAt(i)*this.rules.multipliers[i],t+=e>9?Math.floor(e/10)+e%10:e;return t=10-(t+4)%10,10===t&&(t=0),t===+r.slice(7,8)},rules:{multipliers:[1,2,1,2,1,2,1],regex:[/^(AT)U(\d{8})$/]}},u.belgium={calcs: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 e===+r.slice(8,10)},rules:{regex:[/^(BE)(0?\d{9})$/]}},u.bulgaria=function(){function r(r){for(var e,t=0,i=+r.slice(8),s=0;8>s;s++)t+=+r.charAt(s)*(s+1);if(e=t%11,10!==e)return e===i;t=0;for(var l=0;8>l;l++)t+=+r.charAt(l)*(l+3);return e=t%11,10===e&&(e=0),e===i}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)?!0:!1},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(){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}();return r}),angular.module("angular-jsvat-input",[]).directive("jsvat",["JsVatFactory",function(r){return{restrict:"A",scope:{jsvat:"=?"},require:"ngModel",link:function(e,t){function i(r){if(!angular.isObject(e[r])){var t=e[r];e[r]={value:t}}}function s(r){r?(t.addClass(u),t.removeClass(l)):(t.addClass(l),t.removeClass(u)),n.$setValidity("vat",r)}i("jsvat");var l="-jsvat-invalid",u="-jsvat-valid",n=t.controller("ngModel");e.checkVAT=function(t){e.jsvat=r.checkVAT(t);var i=""===e.jsvat.value||!e.jsvat.value&&"0"!==e.jsvat.value;s(e.jsvat.isValid||i)},e.$watch(function(){return n.$modelValue},function(r){e.checkVAT(r)})}}}]);
//# sourceMappingURL=angular-jsvat.min.js.map
'use strict';
var gulp = require('gulp'), rename, uglify, sourcemaps, jshint, size, ngAnnotate, todo, wrap;
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('sizes_dist', function () {
size = size || require('gulp-filesize');
return gulp.src([
'dist/**/*.js',
'dist/**/*.css',
'dist/**/*.gz'
]).pipe(size());
});
gulp.task('ng', function () {
sourcemaps = sourcemaps || require('gulp-sourcemaps');
uglify = uglify || require('gulp-uglify');
rename = rename || require('gulp-rename');
ngAnnotate = ngAnnotate || require('gulp-ng-annotate');
wrap = wrap || require('gulp-wrap');
var ngWrap =
'angular.module(\'jsvat\', [])' +
'\n\r .factory(\'JsVatFactory\', function () {' +
'\n\r<%= contents %>' +
'\n\r return jsvat;'+
'});';
return gulp.src(src.jsDir)
.pipe(wrap(ngWrap))
.pipe(ngAnnotate({remove: true, add: true, single_quotes: true}))
.pipe(rename({basename: 'angular-jsvat'}))
.pipe(gulp.dest(dest.dist))
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(rename({basename: 'angular-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');
var watch = require('gulp-watch');
gulp.watch(src.jsDir, ['js', 'todo']);
});
gulp.task('build', function () {
gulp.start('ng');
gulp.start('todo');
});
gulp.task('default', function () {
gulp.start('build');
gulp.start('watch');
});
gulp.watch(config.jade.src, ['js', 'todo']);
gulp.watch(config.js.src, ['js', 'todo']);
});
{
"name": "angular-jsvat",
"version": "0.6.1-1",
"version": "1.1.0",
"description": "Check the validity of the format of an EU VAT number specified",

@@ -16,2 +16,3 @@ "main": "./dist/angular-jsvat.js",

"keywords": [
"angular",
"jsvat",

@@ -40,16 +41,17 @@ "angular-jsvat",

"devDependencies": {
"chai": "^3.5.0",
"gulp-filesize": "0.0.6",
"gulp-jshint": "^2.0.0",
"event-stream": "^3.3.2",
"gulp-beautify": "^2.0.0",
"gulp-buddy.js": "^1.0.0",
"gulp-concat": "^2.6.0",
"gulp-gzip": "^1.2.0",
"gulp-ng-annotate": "^2.0.0",
"gulp-notify": "^2.2.0",
"gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-sourcemaps": "^1.6.0",
"gulp-size": "^2.1.0",
"gulp-todo": "^4.1.0",
"gulp-uglify": "^1.5.3",
"gulp-watch": "^4.3.5",
"gulp-wrap": "^0.11.0",
"jshint": "^2.9.1",
"jshint-stylish": "^2.1.0",
"mocha": "^2.4.5"
"require-dir": "^0.3.0",
"run-sequence": "^1.1.5"
}
}

@@ -0,3 +1,13 @@

[![Codacy Badge](https://api.codacy.com/project/badge/grade/6e444e53a23c4b32aeaff09864446989)](https://www.codacy.com/app/se-panfilov/angular-jsvat)
[![bitHound Overall Score](https://www.bithound.io/github/se-panfilov/jsvat/badges/score.svg)](https://www.bithound.io/github/se-panfilov/angular-jsvat) [![bitHound Code](https://www.bithound.io/github/se-panfilov/jsvat/badges/code.svg)](https://www.bithound.io/github/se-panfilov/angular-jsvat)
[![Code Climate](https://codeclimate.com/github/se-panfilov/angular-jsvat/badges/gpa.svg)](https://codeclimate.com/github/se-panfilov/angular-jsvat)
[![Bower version](https://badge.fury.io/bo/angular-jsvat.svg)](http://badge.fury.io/bo/angular-jsvat)
[![npm version](https://badge.fury.io/js/angular-jsvat.svg)](http://badge.fury.io/js/angular-jsvat)
[![devDependency Status](https://david-dm.org/se-panfilov/angular-jsvat/dev-status.svg)](https://david-dm.org/se-panfilov/angular-jsvat#info=devDependencies)
[![GitHub license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/se-panfilov/angular-jsvat/blob/master/LICENSE)
[![NPM](https://nodei.co/npm/angular-jsvat.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/angular-jsvat/)
angular-jsvat

@@ -7,11 +17,10 @@ -------

Check the validity of the format of an EU VAT number. No dependencies (except angularjs of course).
Check the validity of the format of an EU VAT number. No dependencies.(except angularjs of course).
What is it?
--------
Angular-js wrapper for [jsvat][1]
Angular-js wrapper for [jsvat][2] (jsvat it's a core-logic for vat validation)
jsvat is a small library to check validity of European (and few non-eu) VAT number. ([learn more][1] about VAT)
angular-jsvat is a small library to check validity of European (and few non-eu) VAT number. ([learn more][1] about VAT)
jsvat use 2-step check (see below) and didn't make any request for external resources.

@@ -21,2 +30,34 @@

For more details check [jsvat][2] repo.
What angular-jsvat do?
--------
1. Provide `JsVatFactory` fcatory (just an angularjs wrapper for [jsvat][2])
Just check is VAT number valid or not and which country this VAT is:
```
JsVatFactory.checkVAT('BG131134023'); // {isValid: true, country: 'bulgaria', value: 'BG131134023'}
JsVatFactory.checkVAT('BG0433170001'); //{isValid: false, country: null, value: 'BG0433170001'}
JsVatFactory.checkVAT('atu5-150-7409'); //{isValid: true, country: 'austria', value: 'ATU51507409'}
JsVatFactory.checkVAT('aTU 5 804 4146'); //{isValid: true, country: 'austria', value: 'ATU58044146'}
```
You can specify list of allowed countries
```
JsVatFactory.config = ['austria', 'belgium']; //All countries except 'austria' and 'belgium' would return false
JsVatFactory.checkVAT('BG131134023'); //valid VAT, but result would be 'false'
```
To reset config just do `JsVatFactory.config = [];`
2. Provide `jsvat` directive (for inputs).
Directive take a ngModel and return the result to the result object
```
<input jsvat="result" type="text" ng-model="model">
```
Installation

@@ -37,5 +78,15 @@ ----------

After that, just include `angular-jsvat` as a dependency
```
angular.module('app', ['angular-jsvat'])
```
(no dependencies required, angular-jsvat is standalone app)
How does jsvat check the validity?
---------
It use [jsvat][2] core functionality:
There is 2-step check:

@@ -54,18 +105,2 @@

Source of inspiration:
---------
Based on this great work: http://www.braemoor.co.uk/software/vat.shtml
At the moment the code was in public access without any license information.
I'm totally rewrite all the code.
Browsers Supports
---------
...
(unknown yet, but modern browsers should support it as well)
List of supported Countries:

@@ -107,3 +142,7 @@ ---------

Browsers Supports
---------
Support all browsers down to IE9 (including IE9).
LICENSE

@@ -118,2 +157,2 @@ -------

[4]: https://github.com/se-panfilov/angular-jsvat/releases
[5]: https://github.com/se-panfilov/jsvat
[5]: https://github.com/se-panfilov/jsvat
### TODOs
| Filename | line # | TODO
|:------|:------:|:------
| jsvat.js | 207 | (S.Panfilov) this is not cross-browser check
| jsvat.js | 589 | (S.Panfilov) wtf?
|:------|:------:|:------

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

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc