angular-jsvat
Advanced tools
Comparing version 0.6.1-1 to 1.1.0
{ | ||
"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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
32
1
153
177656
14
1764
1