mirror of
https://github.com/danog/CodiceFiscaleJS.git
synced 2024-11-26 20:14:55 +01:00
Fixed new Date => new Date(Date.UTC(....))
Improved test Dependency clean up
This commit is contained in:
parent
5eb6f3c3c8
commit
6db085e308
8
.babelrc
Normal file
8
.babelrc
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
"debug": true,
|
||||
"modules": "cjs"
|
||||
}]
|
||||
]
|
||||
}
|
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
|
||||
[*.{.json,js}]
|
||||
indent_size = 2
|
||||
|
||||
[*.ts]
|
||||
indent_size = 4
|
19
.vscode/launch.json
vendored
Normal file
19
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Debug Jest Tests",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeArgs": [
|
||||
"--inspect-brk",
|
||||
"${workspaceRoot}/node_modules/jest/bin/jest.js",
|
||||
"--runInBand"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"port": 9229
|
||||
}
|
||||
]
|
||||
}
|
28
bower.json
28
bower.json
@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "codice-fiscale-js",
|
||||
"description": "Calcolo del codice fiscale",
|
||||
"main": "dist/codice.fiscale.js",
|
||||
"authors": [
|
||||
"Luca Vandro",
|
||||
"Walter Barbagallo"
|
||||
],
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"codice",
|
||||
"fiscale",
|
||||
"italian",
|
||||
"social",
|
||||
"security",
|
||||
"number"
|
||||
],
|
||||
"homepage": "https://github.com/lucavandro/CodiceFiscaleJS",
|
||||
"moduleType": [],
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"lib",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
2
dist/codice.fiscale.amd.js
vendored
2
dist/codice.fiscale.amd.js
vendored
File diff suppressed because one or more lines are too long
2
dist/codice.fiscale.commonjs2.js
vendored
2
dist/codice.fiscale.commonjs2.js
vendored
File diff suppressed because one or more lines are too long
2
dist/codice.fiscale.umd.js
vendored
2
dist/codice.fiscale.umd.js
vendored
File diff suppressed because one or more lines are too long
2
dist/codice.fiscale.var.js
vendored
2
dist/codice.fiscale.var.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -18,9 +18,6 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">Codice Fiscale JS</a>
|
||||
</nav>
|
||||
<div class="jumbotron jumbotron-fluid text-center">
|
||||
<div class="container">
|
||||
<h1 class="display-4 text-success">Codice Fiscale JS</h1>
|
||||
|
289
lib/codice-fiscale.js
Normal file
289
lib/codice-fiscale.js
Normal file
@ -0,0 +1,289 @@
|
||||
"use strict";
|
||||
|
||||
var _comune = require("./comune");
|
||||
|
||||
var _constants = require("./constants");
|
||||
|
||||
var _utils = require("./utils");
|
||||
|
||||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
||||
|
||||
var CodiceFiscale =
|
||||
/*#__PURE__*/
|
||||
function () {
|
||||
_createClass(CodiceFiscale, [{
|
||||
key: "day",
|
||||
get: function get() {
|
||||
return this.birthday.getDate();
|
||||
},
|
||||
set: function set(d) {
|
||||
this.birthday.setDate(d);
|
||||
}
|
||||
}, {
|
||||
key: "month",
|
||||
get: function get() {
|
||||
return this.birthday.getMonth() + 1;
|
||||
},
|
||||
set: function set(m) {
|
||||
this.birthday.setMonth(m - 1);
|
||||
}
|
||||
}, {
|
||||
key: "year",
|
||||
get: function get() {
|
||||
return this.birthday.getFullYear();
|
||||
},
|
||||
set: function set(y) {
|
||||
this.birthday.setFullYear(y);
|
||||
}
|
||||
}, {
|
||||
key: "cf",
|
||||
get: function get() {
|
||||
return this.code;
|
||||
}
|
||||
}, {
|
||||
key: "nameCode",
|
||||
get: function get() {
|
||||
return this.code.substr(3, 3);
|
||||
}
|
||||
}, {
|
||||
key: "surnameCode",
|
||||
get: function get() {
|
||||
return this.code.substr(0, 3);
|
||||
}
|
||||
}, {
|
||||
key: "checkCode",
|
||||
get: function get() {
|
||||
return this.code.substr(15, 1);
|
||||
}
|
||||
}]);
|
||||
|
||||
function CodiceFiscale(data) {
|
||||
_classCallCheck(this, CodiceFiscale);
|
||||
|
||||
if (typeof data === 'string') {
|
||||
if (CodiceFiscale.check(data)) {
|
||||
this.code = data;
|
||||
this.reverse();
|
||||
} else {
|
||||
throw new Error('Provided input is not a valid Codice Fiscale');
|
||||
}
|
||||
} else if (_typeof(data) === 'object') {
|
||||
var cfData = data;
|
||||
this.name = cfData.name;
|
||||
this.surname = cfData.surname;
|
||||
this.gender = this.checkGender(cfData.gender);
|
||||
this.birthday = cfData.birthday ? (0, _utils.getValidDate)(cfData.birthday) : (0, _utils.getValidDate)(cfData.day, cfData.month, cfData.year);
|
||||
this.birthplace = new _comune.Comune(cfData.birthplace, cfData.birthplaceProvincia);
|
||||
this.compute();
|
||||
} else {
|
||||
throw new Error('Comune constructor accept either a string or a plain object. Check the documentation');
|
||||
}
|
||||
}
|
||||
|
||||
_createClass(CodiceFiscale, [{
|
||||
key: "toString",
|
||||
value: function toString() {
|
||||
return this.code;
|
||||
}
|
||||
}, {
|
||||
key: "toJSON",
|
||||
value: function toJSON() {
|
||||
return {
|
||||
name: this.name,
|
||||
surname: this.surname,
|
||||
gender: this.gender,
|
||||
birthday: this.birthday.getFullYear() + '-' + ('00' + this.birthday.getMonth()).slice(-2) + '-' + ('00' + this.birthday.getDate()).slice(-2),
|
||||
birthplace: this.birthplace.nome,
|
||||
birthplaceProvincia: this.birthplace.prov,
|
||||
cf: this.code
|
||||
};
|
||||
}
|
||||
}, {
|
||||
key: "isValid",
|
||||
value: function isValid() {
|
||||
if (typeof this.code !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.code = this.code.toUpperCase();
|
||||
|
||||
if (this.code.length !== 16) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var expectedCheckCode = this.code.charAt(15);
|
||||
var cf = this.code.slice(0, 15);
|
||||
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode;
|
||||
}
|
||||
}, {
|
||||
key: "omocodie",
|
||||
value: function omocodie() {
|
||||
var results = [];
|
||||
var lastOmocode = this.code = this.code.slice(0, 15);
|
||||
|
||||
for (var i = this.code.length - 1; i >= 0; i = i - 1) {
|
||||
var char = this.code[i];
|
||||
|
||||
if (char.match(/\d/) !== null) {
|
||||
lastOmocode = "".concat(lastOmocode.substr(0, i)).concat(_constants.OMOCODIA_TABLE[char]).concat(lastOmocode.substr(i + 1));
|
||||
results.push(lastOmocode + CodiceFiscale.getCheckCode(lastOmocode));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}, {
|
||||
key: "compute",
|
||||
value: function compute() {
|
||||
var code = this.getSurnameCode();
|
||||
code += this.getNameCode();
|
||||
code += this.dateCode();
|
||||
code += this.birthplace.cc;
|
||||
code += CodiceFiscale.getCheckCode(code);
|
||||
this.code = code;
|
||||
}
|
||||
}, {
|
||||
key: "reverse",
|
||||
value: function reverse() {
|
||||
this.name = this.code.substr(3, 3);
|
||||
this.surname = this.code.substr(0, 3);
|
||||
var yearCode = this.code.substr(6, 2);
|
||||
var year19XX = parseInt("19".concat(yearCode), 10);
|
||||
var year20XX = parseInt("20".concat(yearCode), 10);
|
||||
var currentYear20XX = new Date().getFullYear();
|
||||
var year = year20XX > currentYear20XX ? year19XX : year20XX;
|
||||
var monthChar = this.code.substr(8, 1);
|
||||
|
||||
var month = _constants.MONTH_CODES.indexOf(monthChar);
|
||||
|
||||
this.gender = 'M';
|
||||
var day = parseInt(this.code.substr(9, 2), 10);
|
||||
|
||||
if (day > 31) {
|
||||
this.gender = 'F';
|
||||
day = day - 40;
|
||||
}
|
||||
|
||||
this.birthday = new Date(Date.UTC(year, month, day, 0, 0, 0, 0));
|
||||
var cc = this.code.substr(11, 4);
|
||||
this.birthplace = _comune.Comune.GetByCC(cc);
|
||||
return this.toJSON();
|
||||
}
|
||||
}, {
|
||||
key: "checkGender",
|
||||
value: function checkGender(gender) {
|
||||
this.gender = gender !== undefined ? gender.toUpperCase() : this.gender.toUpperCase();
|
||||
|
||||
if (typeof this.gender !== 'string') {
|
||||
throw new Error('Gender must be a string');
|
||||
}
|
||||
|
||||
if (this.gender !== 'M' && this.gender !== 'F') {
|
||||
throw new Error('Gender must be either \'M\' or \'F\'');
|
||||
}
|
||||
|
||||
return gender;
|
||||
}
|
||||
}, {
|
||||
key: "getSurnameCode",
|
||||
value: function getSurnameCode() {
|
||||
var codeSurname = "".concat((0, _utils.extractConsonants)(this.surname)).concat((0, _utils.extractVowels)(this.surname), "XXX");
|
||||
return codeSurname.substr(0, 3).toUpperCase();
|
||||
}
|
||||
}, {
|
||||
key: "getNameCode",
|
||||
value: function getNameCode() {
|
||||
var codNome = (0, _utils.extractConsonants)(this.name);
|
||||
|
||||
if (codNome.length >= 4) {
|
||||
codNome = codNome.charAt(0) + codNome.charAt(2) + codNome.charAt(3);
|
||||
} else {
|
||||
codNome += "".concat((0, _utils.extractVowels)(this.name), "XXX");
|
||||
codNome = codNome.substr(0, 3);
|
||||
}
|
||||
|
||||
return codNome.toUpperCase();
|
||||
}
|
||||
}, {
|
||||
key: "dateCode",
|
||||
value: function dateCode() {
|
||||
var year = "0".concat(this.birthday.getFullYear());
|
||||
year = year.substr(year.length - 2, 2);
|
||||
|
||||
var month = _constants.MONTH_CODES[this.birthday.getMonth()];
|
||||
|
||||
var day = this.birthday.getDate();
|
||||
|
||||
if (this.gender.toUpperCase() === 'F') {
|
||||
day += 40;
|
||||
}
|
||||
|
||||
var dayStr = "0".concat(day);
|
||||
dayStr = dayStr.substr(dayStr.length - 2, 2);
|
||||
return String(year + month + dayStr);
|
||||
}
|
||||
}], [{
|
||||
key: "getCheckCode",
|
||||
value: function getCheckCode(codiceFiscale) {
|
||||
var val = 0;
|
||||
|
||||
for (var i = 0; i < 15; i = i + 1) {
|
||||
var c = codiceFiscale[i];
|
||||
val += i % 2 !== 0 ? _constants.CHECK_CODE_EVEN[c] : _constants.CHECK_CODE_ODD[c];
|
||||
}
|
||||
|
||||
val = val % 26;
|
||||
return _constants.CHECK_CODE_CHARS.charAt(val);
|
||||
}
|
||||
}, {
|
||||
key: "findLocationCode",
|
||||
value: function findLocationCode(name, prov) {
|
||||
return new _comune.Comune(name, prov).cc;
|
||||
}
|
||||
}, {
|
||||
key: "computeInverse",
|
||||
value: function computeInverse(codiceFiscale) {
|
||||
return new CodiceFiscale(codiceFiscale).toJSON();
|
||||
}
|
||||
}, {
|
||||
key: "compute",
|
||||
value: function compute(obj) {
|
||||
return new CodiceFiscale(obj).toString();
|
||||
}
|
||||
}, {
|
||||
key: "check",
|
||||
value: function check(codiceFiscale) {
|
||||
if (typeof codiceFiscale !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
var cf = codiceFiscale.toUpperCase();
|
||||
|
||||
if (cf.length !== 16) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var expectedCheckCode = codiceFiscale.charAt(15);
|
||||
cf = codiceFiscale.slice(0, 15);
|
||||
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode;
|
||||
}
|
||||
}, {
|
||||
key: "getOmocodie",
|
||||
value: function getOmocodie(cf) {
|
||||
return new CodiceFiscale(cf).omocodie();
|
||||
}
|
||||
}]);
|
||||
|
||||
return CodiceFiscale;
|
||||
}();
|
||||
|
||||
CodiceFiscale.utils = {
|
||||
birthplaceFields: _utils.birthplaceFields
|
||||
};
|
||||
module.exports = CodiceFiscale;
|
205
lib/comune.js
Normal file
205
lib/comune.js
Normal file
@ -0,0 +1,205 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.Comune = void 0;
|
||||
|
||||
var _geoData = require("./geo-data");
|
||||
|
||||
var _utils = require("./utils");
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
||||
|
||||
var Comune =
|
||||
/*#__PURE__*/
|
||||
function () {
|
||||
_createClass(Comune, [{
|
||||
key: "nomeNorm",
|
||||
get: function get() {
|
||||
return (0, _utils.normalizeString)(this.nome);
|
||||
}
|
||||
}]);
|
||||
|
||||
function Comune(nome, prov, cc) {
|
||||
var check = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
|
||||
|
||||
_classCallCheck(this, Comune);
|
||||
|
||||
if (check || cc === undefined || prov === undefined) {
|
||||
var comune;
|
||||
comune = prov !== undefined ? this.searchByNameAndProvince(nome, prov) : this.searchByName(nome);
|
||||
|
||||
if (comune === undefined && nome.length === 4) {
|
||||
comune = this.searchByCC(nome);
|
||||
}
|
||||
|
||||
if (comune === undefined) {
|
||||
throw new Error("Comune with name ".concat(nome, " doesn't exist"));
|
||||
} else if (cc !== undefined && comune.cc !== cc) {
|
||||
throw new Error("Comune with cc ".concat(cc, " doesn't exist"));
|
||||
} else {
|
||||
this.nome = comune.nome;
|
||||
this.prov = comune.prov;
|
||||
this.cc = comune.cc;
|
||||
}
|
||||
} else {
|
||||
this.nome = nome;
|
||||
this.prov = prov;
|
||||
this.cc = cc;
|
||||
}
|
||||
}
|
||||
|
||||
_createClass(Comune, [{
|
||||
key: "searchByCC",
|
||||
value: function searchByCC(cc) {
|
||||
var result;
|
||||
|
||||
try {
|
||||
result = Comune.GetByCC(cc);
|
||||
} catch (e) {}
|
||||
|
||||
if (result !== undefined) {
|
||||
return result.toJSON();
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "searchByName",
|
||||
value: function searchByName(nome) {
|
||||
var query = (0, _utils.normalizeString)(nome);
|
||||
var left = 0;
|
||||
var right = _geoData.COMUNI.length - 1;
|
||||
var result = [];
|
||||
|
||||
while (left <= right) {
|
||||
var middle = Math.floor((left + right) / 2);
|
||||
var currentItem = _geoData.COMUNI[middle];
|
||||
|
||||
if (query === currentItem[2]) {
|
||||
result.push(currentItem);
|
||||
|
||||
if (middle > 0 && _geoData.COMUNI[middle - 1][2] === query) {
|
||||
result.push(_geoData.COMUNI[middle - 1]);
|
||||
} else if (middle < _geoData.COMUNI.length - 1 && _geoData.COMUNI[middle + 1][2] === query) {
|
||||
result.push(_geoData.COMUNI[middle + 1]);
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (query < currentItem[2]) {
|
||||
right = middle - 1;
|
||||
} else {
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.length === 1) {
|
||||
return {
|
||||
cc: result[0][0],
|
||||
prov: result[0][1],
|
||||
nome: result[0][2]
|
||||
};
|
||||
} else if (result.length > 1) {
|
||||
throw new Error("Comune with name of ".concat(nome, " is found in more than one province. Please specify the province code"));
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "searchByNameAndProvince",
|
||||
value: function searchByNameAndProvince(nome, prov) {
|
||||
var query = (0, _utils.normalizeString)(nome);
|
||||
var left = 0;
|
||||
var right = _geoData.COMUNI.length - 1;
|
||||
var result;
|
||||
|
||||
while (left <= right) {
|
||||
var middle = Math.floor((left + right) / 2);
|
||||
var currentItem = _geoData.COMUNI[middle];
|
||||
|
||||
if (query === currentItem[2]) {
|
||||
if (prov === currentItem[1]) {
|
||||
result = currentItem;
|
||||
} else if (middle > 0 && _geoData.COMUNI[middle - 1][2] === query && prov === _geoData.COMUNI[middle - 1][1]) {
|
||||
result = _geoData.COMUNI[middle - 1];
|
||||
} else if (middle < _geoData.COMUNI.length - 1 && _geoData.COMUNI[middle + 1][2] === query && prov === _geoData.COMUNI[middle + 1][1]) {
|
||||
result = _geoData.COMUNI[middle + 1];
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (query < currentItem[2]) {
|
||||
right = middle - 1;
|
||||
} else {
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (result !== undefined) {
|
||||
return {
|
||||
cc: result[0],
|
||||
prov: result[1],
|
||||
nome: result[2]
|
||||
};
|
||||
} else {
|
||||
throw new Error("Comune with name of ".concat(nome, " and prov ").concat(prov, " doesn't exists"));
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "toJSON",
|
||||
value: function toJSON() {
|
||||
return {
|
||||
cc: this.cc,
|
||||
nome: this.nome,
|
||||
prov: this.prov
|
||||
};
|
||||
}
|
||||
}], [{
|
||||
key: "GetByName",
|
||||
value: function GetByName(name, prov) {
|
||||
return new Comune(name, prov);
|
||||
}
|
||||
}, {
|
||||
key: "GetByCC",
|
||||
value: function GetByCC(cc) {
|
||||
var result;
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = _geoData.COMUNI[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var item = _step.value;
|
||||
|
||||
if (item[0] === cc) {
|
||||
result = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result !== undefined) {
|
||||
return new Comune(result[2], result[1], result[0], false);
|
||||
}
|
||||
|
||||
throw new Error("Comune with cc ".concat(cc, " doesn't exist"));
|
||||
}
|
||||
}]);
|
||||
|
||||
return Comune;
|
||||
}();
|
||||
|
||||
exports.Comune = Comune;
|
101
lib/constants.js
Normal file
101
lib/constants.js
Normal file
@ -0,0 +1,101 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.CHECK_CODE_CHARS = exports.OMOCODIA_TABLE = exports.CHECK_CODE_EVEN = exports.CHECK_CODE_ODD = exports.MONTH_CODES = void 0;
|
||||
var MONTH_CODES = ['A', 'B', 'C', 'D', 'E', 'H', 'L', 'M', 'P', 'R', 'S', 'T'];
|
||||
exports.MONTH_CODES = MONTH_CODES;
|
||||
var CHECK_CODE_ODD = {
|
||||
0: 1,
|
||||
1: 0,
|
||||
2: 5,
|
||||
3: 7,
|
||||
4: 9,
|
||||
5: 13,
|
||||
6: 15,
|
||||
7: 17,
|
||||
8: 19,
|
||||
9: 21,
|
||||
A: 1,
|
||||
B: 0,
|
||||
C: 5,
|
||||
D: 7,
|
||||
E: 9,
|
||||
F: 13,
|
||||
G: 15,
|
||||
H: 17,
|
||||
I: 19,
|
||||
J: 21,
|
||||
K: 2,
|
||||
L: 4,
|
||||
M: 18,
|
||||
N: 20,
|
||||
O: 11,
|
||||
P: 3,
|
||||
Q: 6,
|
||||
R: 8,
|
||||
S: 12,
|
||||
T: 14,
|
||||
U: 16,
|
||||
V: 10,
|
||||
W: 22,
|
||||
X: 25,
|
||||
Y: 24,
|
||||
Z: 23
|
||||
};
|
||||
exports.CHECK_CODE_ODD = CHECK_CODE_ODD;
|
||||
var CHECK_CODE_EVEN = {
|
||||
0: 0,
|
||||
1: 1,
|
||||
2: 2,
|
||||
3: 3,
|
||||
4: 4,
|
||||
5: 5,
|
||||
6: 6,
|
||||
7: 7,
|
||||
8: 8,
|
||||
9: 9,
|
||||
A: 0,
|
||||
B: 1,
|
||||
C: 2,
|
||||
D: 3,
|
||||
E: 4,
|
||||
F: 5,
|
||||
G: 6,
|
||||
H: 7,
|
||||
I: 8,
|
||||
J: 9,
|
||||
K: 10,
|
||||
L: 11,
|
||||
M: 12,
|
||||
N: 13,
|
||||
O: 14,
|
||||
P: 15,
|
||||
Q: 16,
|
||||
R: 17,
|
||||
S: 18,
|
||||
T: 19,
|
||||
U: 20,
|
||||
V: 21,
|
||||
W: 22,
|
||||
X: 23,
|
||||
Y: 24,
|
||||
Z: 25
|
||||
};
|
||||
exports.CHECK_CODE_EVEN = CHECK_CODE_EVEN;
|
||||
var OMOCODIA_TABLE = {
|
||||
0: 'L',
|
||||
1: 'M',
|
||||
2: 'N',
|
||||
3: 'P',
|
||||
4: 'Q',
|
||||
5: 'R',
|
||||
6: 'S',
|
||||
7: 'T',
|
||||
8: 'U',
|
||||
9: 'V'
|
||||
};
|
||||
exports.OMOCODIA_TABLE = OMOCODIA_TABLE;
|
||||
var CHECK_CODE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
exports.CHECK_CODE_CHARS = CHECK_CODE_CHARS;
|
122
lib/geo-data.js
Normal file
122
lib/geo-data.js
Normal file
File diff suppressed because one or more lines are too long
117
lib/utils.js
Normal file
117
lib/utils.js
Normal file
@ -0,0 +1,117 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.normalizeString = normalizeString;
|
||||
exports.daysInMonth = daysInMonth;
|
||||
exports.isValidDate = isValidDate;
|
||||
exports.getValidDate = getValidDate;
|
||||
exports.extractVowels = extractVowels;
|
||||
exports.extractConsonants = extractConsonants;
|
||||
exports.pad = pad;
|
||||
exports.birthplaceFields = birthplaceFields;
|
||||
|
||||
var _geoData = require("./geo-data");
|
||||
|
||||
function normalizeString(str) {
|
||||
return str.trim().replace(new RegExp(/[àá]/g), 'a\'').replace(new RegExp(/[èé]/g), 'e\'').replace(new RegExp(/[ìí]/g), 'i\'').replace(new RegExp(/[òó]/g), 'o\'').replace(new RegExp(/[ùú]/g), 'u\'').toUpperCase();
|
||||
}
|
||||
|
||||
function daysInMonth(m, y) {
|
||||
switch (m) {
|
||||
case 1:
|
||||
return y % 4 === 0 && y % 100 !== 0 || y % 400 === 0 ? 29 : 28;
|
||||
|
||||
case 8:
|
||||
case 3:
|
||||
case 5:
|
||||
case 10:
|
||||
return 30;
|
||||
|
||||
default:
|
||||
return 31;
|
||||
}
|
||||
}
|
||||
|
||||
function isValidDate(d, m, y) {
|
||||
var month = m - 1;
|
||||
return month >= 0 && month < 12 && d > 0 && d <= daysInMonth(month, y);
|
||||
}
|
||||
|
||||
function getValidDate(d, m, y) {
|
||||
if (typeof d === 'string' && m === undefined && y === undefined) {
|
||||
return new Date(d);
|
||||
} else if (isValidDate(d, m, y)) {
|
||||
return new Date(y, m - 1, d, 0, 0, 0, 0);
|
||||
} else {
|
||||
throw new Error("The date ".concat(y, "/").concat(m, "/").concat(d, " is not a valid date"));
|
||||
}
|
||||
}
|
||||
|
||||
function extractVowels(str) {
|
||||
return str.replace(/[^AEIOU]/gi, '');
|
||||
}
|
||||
|
||||
function extractConsonants(str) {
|
||||
return str.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/gi, '');
|
||||
}
|
||||
|
||||
function pad(n) {
|
||||
var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
|
||||
var s = String(n);
|
||||
|
||||
while (s.length < size) {
|
||||
s = "0".concat(s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
function birthplaceFields(provinceSelector, birthplaceSelector) {
|
||||
var provinceSelect = document.querySelector(provinceSelector);
|
||||
var birthplaceSelect = document.querySelector(birthplaceSelector);
|
||||
var optGroupProv = document.createElement('optgroup');
|
||||
var optGroupEE = document.createElement('optgroup');
|
||||
optGroupEE.label = '-----------';
|
||||
provinceSelect.appendChild(optGroupProv);
|
||||
provinceSelect.appendChild(optGroupEE);
|
||||
Object.keys(_geoData.PROVINCE).forEach(function (code, i) {
|
||||
var name = _geoData.PROVINCE[code];
|
||||
var option = document.createElement('option');
|
||||
option.value = code;
|
||||
option.textContent = name;
|
||||
|
||||
if (code === 'EE') {
|
||||
optGroupEE.appendChild(option);
|
||||
} else {
|
||||
optGroupProv.appendChild(option);
|
||||
}
|
||||
});
|
||||
|
||||
provinceSelect.onchange = function (e) {
|
||||
var province = provinceSelect.value;
|
||||
|
||||
while (birthplaceSelect.firstChild) {
|
||||
birthplaceSelect.removeChild(birthplaceSelect.firstChild);
|
||||
}
|
||||
|
||||
_geoData.COMUNI.forEach(function (comune) {
|
||||
var cc = comune[0];
|
||||
var nome = comune[2];
|
||||
var prov = comune[1];
|
||||
|
||||
if (prov === province) {
|
||||
var option = document.createElement('option');
|
||||
option.value = cc;
|
||||
option.textContent = nome.toLowerCase().replace(/\b\w/g, function (l) {
|
||||
return l.toUpperCase();
|
||||
});
|
||||
birthplaceSelect.appendChild(option);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
provinceSelect.selectedIndex = '0';
|
||||
provinceSelect.onchange();
|
||||
}
|
8349
package-lock.json
generated
8349
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
40
package.json
40
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "codice-fiscale-js",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"description": "The Italian Tax Code Library for Javascript and Typescript",
|
||||
"main": "dist/codice.fiscale.umd.js",
|
||||
"repository": {
|
||||
@ -11,34 +11,40 @@
|
||||
"test": "tests"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-jest": "^22.0.1",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"eslint": "^3.0.0",
|
||||
"jest": "^22.0.1",
|
||||
"parallel-webpack": "^2.2.0",
|
||||
"regenerator-runtime": "^0.11.1",
|
||||
"request": "^2.88.0",
|
||||
"standard": "^10.0.3",
|
||||
"webpack": "^4.20.2"
|
||||
"@babel/cli": "^7.2.3",
|
||||
"@babel/core": "^7.4.0",
|
||||
"@babel/preset-env": "^7.4.2",
|
||||
"babel-jest": "^24.5.0",
|
||||
"babel-loader": "^8.0.5",
|
||||
"jest": "^24.5.0",
|
||||
"parallel-webpack": "^2.3.0",
|
||||
"standard": "^12.0.1",
|
||||
"webpack": "^4.29.6",
|
||||
"webpack-cli": "^3.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack && cp ./dist/codice.fiscale.var.js ./example/",
|
||||
"build": "webpack",
|
||||
"clean": "rm ./example/codice.fiscale.var.js",
|
||||
"pretest": "npm run build",
|
||||
"test": "standard && jest",
|
||||
"fix": "standard --fix"
|
||||
"test": "jest --debug",
|
||||
"fix": "standard --fix",
|
||||
"standard": "standard"
|
||||
},
|
||||
"author": "Luca Vandro <lucavandro@gmail.com>",
|
||||
"contributors": [
|
||||
"Walter Barbagallo <brb.walter@gmail.com>",
|
||||
"Marco Pesani <marco.pesani@gmail.com>"
|
||||
"Marco Pesani <marco.pesani@gmail.com>",
|
||||
"Arsenio Siani <arsenio.siani@gmail.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"dist/"
|
||||
]
|
||||
},
|
||||
"jest": {
|
||||
"moduleDirectories": [
|
||||
"node_modules",
|
||||
"./src"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -1,204 +1,210 @@
|
||||
import { Comune } from './comune';
|
||||
import { CHECK_CODE_CHARS, CHECK_CODE_EVEN, CHECK_CODE_ODD, MONTH_CODES, OMOCODIA_TABLE } from './constants';
|
||||
import { extractConsonants, extractVowels, getValidDate, birthplaceFields } from './utils';
|
||||
import { Comune } from './comune'
|
||||
import { CHECK_CODE_CHARS, CHECK_CODE_EVEN, CHECK_CODE_ODD, MONTH_CODES, OMOCODIA_TABLE } from './constants'
|
||||
import { extractConsonants, extractVowels, getValidDate, birthplaceFields } from './utils'
|
||||
|
||||
class CodiceFiscale {
|
||||
get day() {
|
||||
return this.birthday.getDate();
|
||||
get day () {
|
||||
return this.birthday.getDate()
|
||||
}
|
||||
set day (d) {
|
||||
this.birthday.setDate(d)
|
||||
}
|
||||
get month () {
|
||||
return this.birthday.getMonth() + 1
|
||||
}
|
||||
set month (m) {
|
||||
this.birthday.setMonth(m - 1)
|
||||
}
|
||||
get year () {
|
||||
return this.birthday.getFullYear()
|
||||
}
|
||||
set year (y) {
|
||||
this.birthday.setFullYear(y)
|
||||
}
|
||||
get cf () {
|
||||
return this.code
|
||||
}
|
||||
get nameCode () {
|
||||
return this.code.substr(3, 3)
|
||||
}
|
||||
get surnameCode () {
|
||||
return this.code.substr(0, 3)
|
||||
}
|
||||
get checkCode () {
|
||||
return this.code.substr(15, 1)
|
||||
}
|
||||
constructor (data) {
|
||||
if (typeof data === 'string') {
|
||||
if (CodiceFiscale.check(data)) {
|
||||
this.code = data
|
||||
this.reverse()
|
||||
} else {
|
||||
throw new Error('Provided input is not a valid Codice Fiscale')
|
||||
}
|
||||
} else if (typeof data === 'object') {
|
||||
const cfData = data
|
||||
this.name = cfData.name
|
||||
this.surname = cfData.surname
|
||||
this.gender = this.checkGender(cfData.gender)
|
||||
this.birthday = cfData.birthday ? getValidDate(cfData.birthday) : getValidDate(cfData.day, cfData.month, cfData.year)
|
||||
this.birthplace = new Comune(cfData.birthplace, cfData.birthplaceProvincia)
|
||||
this.compute()
|
||||
} else {
|
||||
throw new Error('Comune constructor accept either a valid string or a plain object. Check the documentation')
|
||||
}
|
||||
set day(d) {
|
||||
this.birthday.setDate(d);
|
||||
}
|
||||
static getCheckCode (codiceFiscale) {
|
||||
let val = 0
|
||||
for (let i = 0; i < 15; i = i + 1) {
|
||||
const c = codiceFiscale[i]
|
||||
val += i % 2 !== 0 ? CHECK_CODE_EVEN[c] : CHECK_CODE_ODD[c]
|
||||
}
|
||||
get month() {
|
||||
return this.birthday.getMonth() + 1;
|
||||
val = val % 26
|
||||
return CHECK_CODE_CHARS.charAt(val)
|
||||
}
|
||||
static findLocationCode (name, prov) {
|
||||
return new Comune(name, prov).cc
|
||||
}
|
||||
static computeInverse (codiceFiscale) {
|
||||
return new CodiceFiscale(codiceFiscale).toJSON()
|
||||
}
|
||||
static compute (obj) {
|
||||
return new CodiceFiscale(obj).toString()
|
||||
}
|
||||
static check (codiceFiscale) {
|
||||
if (typeof codiceFiscale !== 'string') {
|
||||
return false
|
||||
}
|
||||
set month(m) {
|
||||
this.birthday.setMonth(m - 1);
|
||||
let cf = codiceFiscale.toUpperCase()
|
||||
if (cf.length !== 16) {
|
||||
return false
|
||||
}
|
||||
get year() {
|
||||
return this.birthday.getFullYear();
|
||||
const expectedCheckCode = codiceFiscale.charAt(15)
|
||||
cf = codiceFiscale.slice(0, 15)
|
||||
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode
|
||||
}
|
||||
static getOmocodie (cf) {
|
||||
return new CodiceFiscale(cf).omocodie()
|
||||
}
|
||||
static surnameCode(surname){
|
||||
const codeSurname = `${extractConsonants(surname)}${extractVowels(surname)}XXX`
|
||||
return codeSurname.substr(0, 3).toUpperCase()
|
||||
}
|
||||
static nameCode(name){
|
||||
let codNome = extractConsonants(name)
|
||||
if (codNome.length >= 4) {
|
||||
codNome = codNome.charAt(0) + codNome.charAt(2) + codNome.charAt(3)
|
||||
} else {
|
||||
codNome += `${extractVowels(name)}XXX`
|
||||
codNome = codNome.substr(0, 3)
|
||||
}
|
||||
set year(y) {
|
||||
this.birthday.setFullYear(y);
|
||||
return codNome.toUpperCase()
|
||||
}
|
||||
static dateCode(day, month, year, gender){
|
||||
year = `0${year}`
|
||||
year = year.substr(year.length - 2, 2)
|
||||
month = MONTH_CODES[month-1];
|
||||
if (gender.toUpperCase() === 'F') {
|
||||
day += 40
|
||||
}
|
||||
get cf() {
|
||||
return this.code;
|
||||
day = `0${day}`
|
||||
day = day.substr(day.length - 2, 2)
|
||||
return `${year}${month}${day}`
|
||||
}
|
||||
toString () {
|
||||
return this.code
|
||||
}
|
||||
toJSON () {
|
||||
return {
|
||||
name: this.name,
|
||||
surname: this.surname,
|
||||
gender: this.gender,
|
||||
day : this.birthday.getDate(),
|
||||
year: this.birthday.getFullYear(),
|
||||
month: this.birthday.getMonth()+1,
|
||||
birthday: this.birthday.getFullYear() + '-' + (('00' + this.birthday.getMonth()+1).slice(-2)) + '-' + (('00' + this.birthday.getDate()).slice(-2)),
|
||||
birthplace: this.birthplace.nome,
|
||||
birthplaceProvincia: this.birthplace.prov,
|
||||
cf: this.code
|
||||
}
|
||||
get nameCode() {
|
||||
return this.code.substr(3, 3);
|
||||
}
|
||||
isValid () {
|
||||
if (typeof this.code !== 'string') {
|
||||
return false
|
||||
}
|
||||
get surnameCode() {
|
||||
return this.code.substr(0, 3);
|
||||
this.code = this.code.toUpperCase()
|
||||
if (this.code.length !== 16) {
|
||||
return false
|
||||
}
|
||||
get checkCode() {
|
||||
return this.code.substr(15, 1);
|
||||
const expectedCheckCode = this.code.charAt(15)
|
||||
const cf = this.code.slice(0, 15)
|
||||
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode
|
||||
}
|
||||
omocodie () {
|
||||
const results = []
|
||||
let lastOmocode = (this.code = this.code.slice(0, 15))
|
||||
for (let i = this.code.length - 1; i >= 0; i = i - 1) {
|
||||
const char = this.code[i]
|
||||
if (char.match(/\d/) !== null) {
|
||||
lastOmocode = `${lastOmocode.substr(0, i)}${OMOCODIA_TABLE[char]}${lastOmocode.substr(i + 1)}`
|
||||
results.push(lastOmocode + CodiceFiscale.getCheckCode(lastOmocode))
|
||||
}
|
||||
}
|
||||
constructor(data) {
|
||||
if (typeof data === 'string') {
|
||||
if (CodiceFiscale.check(data)) {
|
||||
this.code = data;
|
||||
this.reverse();
|
||||
}
|
||||
else {
|
||||
throw new Error('Provided input is not a valid Codice Fiscale');
|
||||
}
|
||||
}
|
||||
else if (typeof data === 'object') {
|
||||
const cfData = data;
|
||||
this.name = cfData.name;
|
||||
this.surname = cfData.surname;
|
||||
this.gender = this.checkGender(cfData.gender);
|
||||
this.birthday = cfData.birthday ? getValidDate(cfData.birthday) : getValidDate(cfData.day, cfData.month, cfData.year);
|
||||
this.birthplace = new Comune(cfData.birthplace, cfData.birthplaceProvincia);
|
||||
this.compute();
|
||||
}
|
||||
else {
|
||||
throw new Error('Comune constructor accept either a string or a plain object. Check the documentation');
|
||||
}
|
||||
return results
|
||||
}
|
||||
compute () {
|
||||
let code = this.getSurnameCode()
|
||||
code += this.getNameCode()
|
||||
code += this.dateCode()
|
||||
code += this.birthplace.cc
|
||||
code += CodiceFiscale.getCheckCode(code)
|
||||
this.code = code
|
||||
}
|
||||
reverse () {
|
||||
this.name = this.code.substr(3, 3)
|
||||
this.surname = this.code.substr(0, 3)
|
||||
|
||||
const yearCode = this.code.substr(6, 2)
|
||||
const year19XX = parseInt(`19${yearCode}`, 10)
|
||||
const year20XX = parseInt(`20${yearCode}`, 10)
|
||||
const currentYear20XX = new Date().getFullYear()
|
||||
const year = year20XX > currentYear20XX ? year19XX : year20XX
|
||||
const monthChar = this.code.substr(8, 1)
|
||||
const month = MONTH_CODES.indexOf(monthChar)
|
||||
this.gender = 'M'
|
||||
let day = parseInt(this.code.substr(9, 2), 10)
|
||||
if (day > 31) {
|
||||
this.gender = 'F'
|
||||
day = day - 40
|
||||
}
|
||||
static getCheckCode(codiceFiscale) {
|
||||
let val = 0;
|
||||
for (let i = 0; i < 15; i = i + 1) {
|
||||
const c = codiceFiscale[i];
|
||||
val += i % 2 !== 0 ? CHECK_CODE_EVEN[c] : CHECK_CODE_ODD[c];
|
||||
}
|
||||
val = val % 26;
|
||||
return CHECK_CODE_CHARS.charAt(val);
|
||||
this.birthday = new Date(Date.UTC(year, month, day, 0, 0, 0, 0))
|
||||
const cc = this.code.substr(11, 4)
|
||||
this.birthplace = Comune.GetByCC(cc)
|
||||
return this.toJSON()
|
||||
}
|
||||
checkGender (gender) {
|
||||
this.gender = gender !== undefined ? gender.toUpperCase() : this.gender.toUpperCase()
|
||||
if (typeof this.gender !== 'string') {
|
||||
throw new Error('Gender must be a string')
|
||||
}
|
||||
static findLocationCode(name, prov) {
|
||||
return new Comune(name, prov).cc;
|
||||
}
|
||||
static computeInverse(codiceFiscale) {
|
||||
return new CodiceFiscale(codiceFiscale).toJSON();
|
||||
}
|
||||
static compute(obj) {
|
||||
return new CodiceFiscale(obj).toString();
|
||||
}
|
||||
static check(codiceFiscale) {
|
||||
if (typeof codiceFiscale !== 'string') {
|
||||
return false;
|
||||
}
|
||||
let cf = codiceFiscale.toUpperCase();
|
||||
if (cf.length !== 16) {
|
||||
return false;
|
||||
}
|
||||
const expectedCheckCode = codiceFiscale.charAt(15);
|
||||
cf = codiceFiscale.slice(0, 15);
|
||||
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode;
|
||||
}
|
||||
static getOmocodie(cf) {
|
||||
return new CodiceFiscale(cf).omocodie();
|
||||
}
|
||||
toString() {
|
||||
return this.code;
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
name: this.name,
|
||||
surname: this.surname,
|
||||
gender: this.gender,
|
||||
birthday: this.birthday.getFullYear()+"-"+(("00" + this.birthday.getMonth()).slice(-2))+"-"+(("00" + this.birthday.getDate()).slice(-2)),
|
||||
birthplace: this.birthplace.nome,
|
||||
birthplaceProvincia: this.birthplace.prov,
|
||||
cf: this.code,
|
||||
};
|
||||
}
|
||||
isValid() {
|
||||
if (typeof this.code !== 'string') {
|
||||
return false;
|
||||
}
|
||||
this.code = this.code.toUpperCase();
|
||||
if (this.code.length !== 16) {
|
||||
return false;
|
||||
}
|
||||
const expectedCheckCode = this.code.charAt(15);
|
||||
const cf = this.code.slice(0, 15);
|
||||
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode;
|
||||
}
|
||||
omocodie() {
|
||||
const results = [];
|
||||
let lastOmocode = (this.code = this.code.slice(0, 15));
|
||||
for (let i = this.code.length - 1; i >= 0; i = i - 1) {
|
||||
const char = this.code[i];
|
||||
if (char.match(/\d/) !== null) {
|
||||
lastOmocode = `${lastOmocode.substr(0, i)}${OMOCODIA_TABLE[char]}${lastOmocode.substr(i + 1)}`;
|
||||
results.push(lastOmocode + CodiceFiscale.getCheckCode(lastOmocode));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
compute() {
|
||||
let code = this.getSurnameCode();
|
||||
code += this.getNameCode();
|
||||
code += this.dateCode();
|
||||
code += this.birthplace.cc;
|
||||
code += CodiceFiscale.getCheckCode(code);
|
||||
this.code = code;
|
||||
}
|
||||
reverse() {
|
||||
|
||||
this.name = this.code.substr(3, 3);
|
||||
this.surname = this.code.substr(0, 3);
|
||||
|
||||
const yearCode = this.code.substr(6, 2);
|
||||
const year19XX = parseInt(`19${yearCode}`, 10);
|
||||
const year20XX = parseInt(`20${yearCode}`, 10);
|
||||
const currentYear20XX = new Date().getFullYear();
|
||||
const year = year20XX > currentYear20XX ? year19XX : year20XX;
|
||||
const monthChar = this.code.substr(8, 1);
|
||||
const month = MONTH_CODES.indexOf(monthChar);
|
||||
this.gender = 'M';
|
||||
let day = parseInt(this.code.substr(9, 2), 10);
|
||||
if (day > 31) {
|
||||
this.gender = 'F';
|
||||
day = day - 40;
|
||||
}
|
||||
this.birthday = new Date(year, month, day, 0, 0, 0, 0);
|
||||
const cc = this.code.substr(11, 4);
|
||||
this.birthplace = Comune.GetByCC(cc);
|
||||
return this.toJSON();
|
||||
}
|
||||
checkGender(gender) {
|
||||
this.gender = gender !== undefined ? gender.toUpperCase() : this.gender.toUpperCase();
|
||||
if (typeof this.gender !== 'string') {
|
||||
throw new Error('Gender must be a string');
|
||||
}
|
||||
if (this.gender !== 'M' && this.gender !== 'F') {
|
||||
throw new Error('Gender must be either \'M\' or \'F\'');
|
||||
}
|
||||
return gender;
|
||||
}
|
||||
getSurnameCode() {
|
||||
const codeSurname = `${extractConsonants(this.surname)}${extractVowels(this.surname)}XXX`;
|
||||
return codeSurname.substr(0, 3).toUpperCase();
|
||||
}
|
||||
getNameCode() {
|
||||
let codNome = extractConsonants(this.name);
|
||||
if (codNome.length >= 4) {
|
||||
codNome = codNome.charAt(0) + codNome.charAt(2) + codNome.charAt(3);
|
||||
}
|
||||
else {
|
||||
codNome += `${extractVowels(this.name)}XXX`;
|
||||
codNome = codNome.substr(0, 3);
|
||||
}
|
||||
return codNome.toUpperCase();
|
||||
}
|
||||
dateCode() {
|
||||
let year = `0${this.birthday.getFullYear()}`;
|
||||
year = year.substr(year.length - 2, 2);
|
||||
const month = MONTH_CODES[this.birthday.getMonth()];
|
||||
let day = this.birthday.getDate();
|
||||
if (this.gender.toUpperCase() === 'F') {
|
||||
day += 40;
|
||||
}
|
||||
let dayStr = `0${day}`;
|
||||
dayStr = dayStr.substr(dayStr.length - 2, 2);
|
||||
return String(year + month + dayStr);
|
||||
if (this.gender !== 'M' && this.gender !== 'F') {
|
||||
throw new Error('Gender must be either \'M\' or \'F\'')
|
||||
}
|
||||
return gender
|
||||
}
|
||||
getSurnameCode () {
|
||||
return CodiceFiscale.surnameCode(this.surname);
|
||||
}
|
||||
getNameCode () {
|
||||
return CodiceFiscale.nameCode(this.name);
|
||||
}
|
||||
dateCode () {
|
||||
return CodiceFiscale.dateCode(this.birthday.getDate(), this.birthday.getMonth() + 1, this.birthday.getFullYear(), this.gender);
|
||||
}
|
||||
}
|
||||
|
||||
CodiceFiscale.utils = {
|
||||
birthplaceFields : birthplaceFields
|
||||
birthplaceFields: birthplaceFields
|
||||
}
|
||||
|
||||
module.exports = CodiceFiscale
|
||||
|
229
src/comune.js
229
src/comune.js
@ -1,134 +1,121 @@
|
||||
import { COMUNI } from './geo-data';
|
||||
import { normalizeString } from './utils';
|
||||
import { COMUNI } from './geo-data'
|
||||
import { normalizeString } from './utils'
|
||||
export class Comune {
|
||||
get nomeNorm() {
|
||||
return normalizeString(this.nome);
|
||||
}
|
||||
constructor(nome, prov, cc, check = true) {
|
||||
|
||||
if (check || cc === undefined || prov === undefined) {
|
||||
let comune;
|
||||
comune = prov !== undefined ? this.searchByNameAndProvince(nome, prov) : this.searchByName(nome);
|
||||
if (comune === undefined && nome.length === 4) {
|
||||
comune = this.searchByCC(nome);
|
||||
}
|
||||
get nomeNorm () {
|
||||
return normalizeString(this.nome)
|
||||
}
|
||||
constructor (nome, prov, cc, check = true) {
|
||||
if (check || cc === undefined || prov === undefined) {
|
||||
let comune
|
||||
comune = prov !== undefined ? this.searchByNameAndProvince(nome, prov) : this.searchByName(nome)
|
||||
if (comune === undefined && nome.length === 4) {
|
||||
comune = this.searchByCC(nome)
|
||||
}
|
||||
|
||||
if (comune === undefined) {
|
||||
throw new Error(`Comune with name ${nome} doesn't exist`);
|
||||
}
|
||||
else if (cc !== undefined && comune.cc !== cc) {
|
||||
throw new Error(`Comune with cc ${cc} doesn't exist`);
|
||||
}
|
||||
else {
|
||||
this.nome = comune.nome;
|
||||
this.prov = comune.prov;
|
||||
this.cc = comune.cc;
|
||||
}
|
||||
} else {
|
||||
this.nome = nome;
|
||||
this.prov = prov;
|
||||
this.cc = cc;
|
||||
}
|
||||
if (comune === undefined) {
|
||||
throw new Error(`Comune with name ${nome} doesn't exist`)
|
||||
} else if (cc !== undefined && comune.cc !== cc) {
|
||||
throw new Error(`Comune with cc ${cc} doesn't exist`)
|
||||
} else {
|
||||
this.nome = comune.nome
|
||||
this.prov = comune.prov
|
||||
this.cc = comune.cc
|
||||
}
|
||||
} else {
|
||||
this.nome = nome
|
||||
this.prov = prov
|
||||
this.cc = cc
|
||||
}
|
||||
static GetByName(name, prov) {
|
||||
return new Comune(name, prov);
|
||||
}
|
||||
static GetByName (name, prov) {
|
||||
return new Comune(name, prov)
|
||||
}
|
||||
static GetByCC (cc) {
|
||||
let result
|
||||
for (const item of COMUNI) {
|
||||
if (item[0] === cc) {
|
||||
result = item
|
||||
break
|
||||
}
|
||||
}
|
||||
static GetByCC(cc) {
|
||||
let result;
|
||||
for (const item of COMUNI) {
|
||||
if (item[0] === cc) {
|
||||
result = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result !== undefined) {
|
||||
return new Comune(result[2], result[1], result[0], false);
|
||||
}
|
||||
throw new Error(`Comune with cc ${cc} doesn't exist`);
|
||||
if (result !== undefined) {
|
||||
return new Comune(result[2], result[1], result[0], false)
|
||||
}
|
||||
throw new Error(`Comune with cc ${cc} doesn't exist`)
|
||||
}
|
||||
|
||||
searchByCC(cc) {
|
||||
let result;
|
||||
try{
|
||||
result = Comune.GetByCC(cc);
|
||||
}catch(e){}
|
||||
if (result !== undefined) {
|
||||
return result.toJSON();
|
||||
}
|
||||
searchByCC (cc) {
|
||||
let result
|
||||
try {
|
||||
result = Comune.GetByCC(cc)
|
||||
} catch (e) { }
|
||||
if (result !== undefined) {
|
||||
return result.toJSON()
|
||||
}
|
||||
searchByName(nome) {
|
||||
const query = normalizeString(nome);
|
||||
let left = 0;
|
||||
let right = COMUNI.length - 1;
|
||||
const result = [];
|
||||
while (left <= right) {
|
||||
const middle = Math.floor((left + right) / 2);
|
||||
const currentItem = COMUNI[middle];
|
||||
if (query === currentItem[2]) {
|
||||
result.push(currentItem);
|
||||
if (middle > 0 && COMUNI[middle - 1][2] === query) {
|
||||
result.push(COMUNI[middle - 1]);
|
||||
}
|
||||
else if (middle < COMUNI.length - 1 && COMUNI[middle + 1][2] === query) {
|
||||
result.push(COMUNI[middle + 1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (query < currentItem[2]) {
|
||||
right = middle - 1;
|
||||
}
|
||||
else {
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
if (result.length === 1) {
|
||||
return { cc: result[0][0], prov: result[0][1], nome: result[0][2] };
|
||||
}
|
||||
else if (result.length > 1) {
|
||||
throw new Error(`Comune with name of ${nome} is found in more than one province. Please specify the province code`);
|
||||
}
|
||||
searchByName (nome) {
|
||||
const query = normalizeString(nome)
|
||||
let left = 0
|
||||
let right = COMUNI.length - 1
|
||||
const result = []
|
||||
while (left <= right) {
|
||||
const middle = Math.floor((left + right) / 2)
|
||||
const currentItem = COMUNI[middle]
|
||||
if (query === currentItem[2]) {
|
||||
result.push(currentItem)
|
||||
if (middle > 0 && COMUNI[middle - 1][2] === query) {
|
||||
result.push(COMUNI[middle - 1])
|
||||
} else if (middle < COMUNI.length - 1 && COMUNI[middle + 1][2] === query) {
|
||||
result.push(COMUNI[middle + 1])
|
||||
}
|
||||
break
|
||||
} else if (query < currentItem[2]) {
|
||||
right = middle - 1
|
||||
} else {
|
||||
left = middle + 1
|
||||
}
|
||||
}
|
||||
searchByNameAndProvince(nome, prov) {
|
||||
const query = normalizeString(nome);
|
||||
let left = 0;
|
||||
let right = COMUNI.length - 1;
|
||||
let result;
|
||||
while (left <= right) {
|
||||
const middle = Math.floor((left + right) / 2);
|
||||
const currentItem = COMUNI[middle];
|
||||
if (query === currentItem[2]) {
|
||||
if (prov === currentItem[1]) {
|
||||
result = currentItem;
|
||||
}
|
||||
else if (middle > 0 && COMUNI[middle - 1][2] === query && prov === COMUNI[middle - 1][1]) {
|
||||
result = COMUNI[middle - 1];
|
||||
}
|
||||
else if (middle < COMUNI.length - 1 && COMUNI[middle + 1][2] === query && prov === COMUNI[middle + 1][1]) {
|
||||
result = COMUNI[middle + 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (query < currentItem[2]) {
|
||||
right = middle - 1;
|
||||
}
|
||||
else {
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
if (result !== undefined) {
|
||||
return { cc: result[0], prov: result[1], nome: result[2] };
|
||||
}
|
||||
else {
|
||||
throw new Error(`Comune with name of ${nome} and prov ${prov} doesn't exists`);
|
||||
}
|
||||
if (result.length === 1) {
|
||||
return { cc: result[0][0], prov: result[0][1], nome: result[0][2] }
|
||||
} else if (result.length > 1) {
|
||||
throw new Error(`Comune with name of ${nome} is found in more than one province. Please specify the province code`)
|
||||
}
|
||||
}
|
||||
searchByNameAndProvince (nome, prov) {
|
||||
const query = normalizeString(nome)
|
||||
let left = 0
|
||||
let right = COMUNI.length - 1
|
||||
let result
|
||||
while (left <= right) {
|
||||
const middle = Math.floor((left + right) / 2)
|
||||
const currentItem = COMUNI[middle]
|
||||
if (query === currentItem[2]) {
|
||||
if (prov === currentItem[1]) {
|
||||
result = currentItem
|
||||
} else if (middle > 0 && COMUNI[middle - 1][2] === query && prov === COMUNI[middle - 1][1]) {
|
||||
result = COMUNI[middle - 1]
|
||||
} else if (middle < COMUNI.length - 1 && COMUNI[middle + 1][2] === query && prov === COMUNI[middle + 1][1]) {
|
||||
result = COMUNI[middle + 1]
|
||||
}
|
||||
break
|
||||
} else if (query < currentItem[2]) {
|
||||
right = middle - 1
|
||||
} else {
|
||||
left = middle + 1
|
||||
}
|
||||
}
|
||||
if (result !== undefined) {
|
||||
return { cc: result[0], prov: result[1], nome: result[2] }
|
||||
} else {
|
||||
throw new Error(`Comune with name of ${nome} and prov ${prov} doesn't exists`)
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(){
|
||||
return {
|
||||
cc : this.cc,
|
||||
nome : this.nome,
|
||||
prov : this.prov
|
||||
}
|
||||
toJSON () {
|
||||
return {
|
||||
cc: this.cc,
|
||||
nome: this.nome,
|
||||
prov: this.prov
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
17128
src/geo-data.js
17128
src/geo-data.js
File diff suppressed because it is too large
Load Diff
160
src/utils.js
160
src/utils.js
@ -1,91 +1,91 @@
|
||||
import { PROVINCE, COMUNI } from './geo-data';
|
||||
import { PROVINCE, COMUNI } from './geo-data'
|
||||
|
||||
export function normalizeString(str) {
|
||||
return str.trim()
|
||||
.replace(new RegExp(/[àá]/g), 'a\'')
|
||||
.replace(new RegExp(/[èé]/g), 'e\'')
|
||||
.replace(new RegExp(/[ìí]/g), 'i\'')
|
||||
.replace(new RegExp(/[òó]/g), 'o\'')
|
||||
.replace(new RegExp(/[ùú]/g), 'u\'')
|
||||
.toUpperCase();
|
||||
export function normalizeString (str) {
|
||||
return str.trim()
|
||||
.replace(new RegExp(/[àá]/g), 'a\'')
|
||||
.replace(new RegExp(/[èé]/g), 'e\'')
|
||||
.replace(new RegExp(/[ìí]/g), 'i\'')
|
||||
.replace(new RegExp(/[òó]/g), 'o\'')
|
||||
.replace(new RegExp(/[ùú]/g), 'u\'')
|
||||
.toUpperCase()
|
||||
}
|
||||
export function daysInMonth(m, y) {
|
||||
switch (m) {
|
||||
case 1:
|
||||
return (y % 4 === 0 && y % 100 !== 0) || (y % 400 === 0) ? 29 : 28;
|
||||
case 8:
|
||||
case 3:
|
||||
case 5:
|
||||
case 10:
|
||||
return 30;
|
||||
default:
|
||||
return 31;
|
||||
}
|
||||
export function daysInMonth (m, y) {
|
||||
switch (m) {
|
||||
case 1:
|
||||
return (y % 4 === 0 && y % 100 !== 0) || (y % 400 === 0) ? 29 : 28
|
||||
case 8:
|
||||
case 3:
|
||||
case 5:
|
||||
case 10:
|
||||
return 30
|
||||
default:
|
||||
return 31
|
||||
}
|
||||
}
|
||||
export function isValidDate(d, m, y) {
|
||||
const month = m - 1;
|
||||
return month >= 0 && month < 12 && d > 0 && d <= daysInMonth(month, y);
|
||||
export function isValidDate (d, m, y) {
|
||||
const month = m - 1
|
||||
return month >= 0 && month < 12 && d > 0 && d <= daysInMonth(month, y)
|
||||
}
|
||||
export function getValidDate(d, m, y) {
|
||||
if(typeof d === 'string' && m === undefined && y === undefined){
|
||||
return new Date(d);
|
||||
}else if (isValidDate(d, m, y)) {
|
||||
return new Date(y, m - 1, d, 0, 0, 0, 0);
|
||||
}
|
||||
else {
|
||||
throw new Error(`The date ${y}/${m}/${d} is not a valid date`);
|
||||
}
|
||||
export function getValidDate (d, m, y) {
|
||||
if (typeof d === 'string' && m === undefined && y === undefined) {
|
||||
return new Date(d)
|
||||
} else if (isValidDate(d, m, y)) {
|
||||
return new Date(y, m - 1, d, 0, 0, 0, 0)
|
||||
} else {
|
||||
throw new Error(`The date ${y}/${m}/${d} is not a valid date`)
|
||||
}
|
||||
}
|
||||
export function extractVowels(str) {
|
||||
return str.replace(/[^AEIOU]/gi, '');
|
||||
export function extractVowels (str) {
|
||||
return str.replace(/[^AEIOU]/gi, '')
|
||||
}
|
||||
export function extractConsonants(str) {
|
||||
return str.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/gi, '');
|
||||
export function extractConsonants (str) {
|
||||
return str.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/gi, '')
|
||||
}
|
||||
export function pad(n, size = 2) {
|
||||
let s = String(n);
|
||||
while (s.length < size) {
|
||||
s = `0${s}`;
|
||||
}
|
||||
return s;
|
||||
export function pad (n, size = 2) {
|
||||
let s = String(n)
|
||||
while (s.length < size) {
|
||||
s = `0${s}`
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
export function birthplaceFields(provinceSelector, birthplaceSelector) {
|
||||
const provinceSelect = document.querySelector(provinceSelector);
|
||||
const birthplaceSelect = document.querySelector(birthplaceSelector);
|
||||
const optGroupProv = document.createElement('optgroup');
|
||||
const optGroupEE = document.createElement('optgroup');
|
||||
optGroupEE.label = "-----------";
|
||||
provinceSelect.appendChild(optGroupProv);
|
||||
provinceSelect.appendChild(optGroupEE);
|
||||
Object.keys(PROVINCE).forEach((code, i) => {
|
||||
const name = PROVINCE[code];
|
||||
const option = document.createElement('option');
|
||||
option.value = code;
|
||||
option.textContent = name;
|
||||
if(code === 'EE'){
|
||||
optGroupEE.appendChild(option);
|
||||
} else {
|
||||
optGroupProv.appendChild(option);
|
||||
}
|
||||
});
|
||||
|
||||
provinceSelect.onchange = (e)=>{
|
||||
let province = provinceSelect.value;
|
||||
while (birthplaceSelect.firstChild) {
|
||||
birthplaceSelect.removeChild(birthplaceSelect.firstChild);
|
||||
}
|
||||
COMUNI.forEach((comune)=>{
|
||||
let cc = comune[0], nome = comune[2], prov = comune[1];
|
||||
if(prov === province){
|
||||
let option = document.createElement('option');
|
||||
option.value = cc;
|
||||
option.textContent = nome.toLowerCase().replace(/\b\w/g, l => l.toUpperCase());
|
||||
birthplaceSelect.appendChild(option);
|
||||
}
|
||||
});
|
||||
export function birthplaceFields (provinceSelector, birthplaceSelector) {
|
||||
const provinceSelect = document.querySelector(provinceSelector)
|
||||
const birthplaceSelect = document.querySelector(birthplaceSelector)
|
||||
const optGroupProv = document.createElement('optgroup')
|
||||
const optGroupEE = document.createElement('optgroup')
|
||||
optGroupEE.label = '-----------'
|
||||
provinceSelect.appendChild(optGroupProv)
|
||||
provinceSelect.appendChild(optGroupEE)
|
||||
Object.keys(PROVINCE).forEach((code, i) => {
|
||||
const name = PROVINCE[code]
|
||||
const option = document.createElement('option')
|
||||
option.value = code
|
||||
option.textContent = name
|
||||
if (code === 'EE') {
|
||||
optGroupEE.appendChild(option)
|
||||
} else {
|
||||
optGroupProv.appendChild(option)
|
||||
}
|
||||
})
|
||||
|
||||
provinceSelect.selectedIndex = "0";
|
||||
provinceSelect.onchange();
|
||||
}
|
||||
provinceSelect.onchange = (e) => {
|
||||
let province = provinceSelect.value
|
||||
while (birthplaceSelect.firstChild) {
|
||||
birthplaceSelect.removeChild(birthplaceSelect.firstChild)
|
||||
}
|
||||
COMUNI.forEach((comune) => {
|
||||
let cc = comune[0]
|
||||
let nome = comune[2]
|
||||
let prov = comune[1]
|
||||
if (prov === province) {
|
||||
let option = document.createElement('option')
|
||||
option.value = cc
|
||||
option.textContent = nome.toLowerCase().replace(/\b\w/g, l => l.toUpperCase())
|
||||
birthplaceSelect.appendChild(option)
|
||||
}
|
||||
})
|
||||
}
|
||||
provinceSelect.selectedIndex = '0'
|
||||
provinceSelect.onchange()
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
import CodiceFiscale from '../src/index'
|
||||
import CodiceFiscale from '../src/codice-fiscale.js';
|
||||
import { exists } from 'fs';
|
||||
|
||||
let { describe, test, expect } = global
|
||||
|
||||
describe('Codice Fiscale', () => {
|
||||
test('esiste un oggetto chiamato CodiceFiscale', () => {
|
||||
expect(CodiceFiscale).not.toBe(undefined)
|
||||
expect(CodiceFiscale).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('CodiceFiscale.surnameCode', () => {
|
||||
test('è definito', () => {
|
||||
expect(CodiceFiscale.surnameCode).not.toBe(undefined)
|
||||
expect(CodiceFiscale.surnameCode).toBeDefined()
|
||||
})
|
||||
|
||||
test('restituisce il corretto risultato in caso di sufficienti consonanti', () => {
|
||||
@ -23,7 +25,7 @@ describe('CodiceFiscale.surnameCode', () => {
|
||||
|
||||
describe('CodiceFiscale.nameCode', () => {
|
||||
test('è definito', () => {
|
||||
expect(CodiceFiscale.nameCode).not.toBe(undefined)
|
||||
expect(CodiceFiscale.nameCode).toBeDefined()
|
||||
})
|
||||
|
||||
test('restituisce il corretto risultato in caso di sufficienti consonanti', () => {
|
||||
@ -37,7 +39,7 @@ describe('CodiceFiscale.nameCode', () => {
|
||||
|
||||
describe('CodiceFiscale.dateCode', () => {
|
||||
test('è definito', () => {
|
||||
expect(CodiceFiscale.dateCode).not.toBe(undefined)
|
||||
expect(CodiceFiscale.dateCode).toBeDefined()
|
||||
})
|
||||
|
||||
test('restituisce il corretto risultato', () => {
|
||||
@ -47,7 +49,7 @@ describe('CodiceFiscale.dateCode', () => {
|
||||
|
||||
describe('CodiceFiscale.getCheckCode', () => {
|
||||
test('è definito', () => {
|
||||
expect(CodiceFiscale.getCheckCode).not.toBe(undefined)
|
||||
expect(CodiceFiscale.getCheckCode).toBeDefined()
|
||||
})
|
||||
|
||||
test('restituisce il corretto risultato', () => {
|
||||
@ -57,7 +59,7 @@ describe('CodiceFiscale.getCheckCode', () => {
|
||||
|
||||
describe('CodiceFiscale.compute', () => {
|
||||
test('è definito', () => {
|
||||
expect(CodiceFiscale.compute).not.toBe(undefined)
|
||||
expect(CodiceFiscale.compute).toBeDefined()
|
||||
})
|
||||
|
||||
test('calcola il codice fiscale', () => {
|
||||
@ -101,13 +103,13 @@ describe('CodiceFiscale.compute', () => {
|
||||
birthplaceProvincia: 'EE'
|
||||
})
|
||||
}
|
||||
expect(comuneInventato).toThrowError('Location not found')
|
||||
expect(comuneInventato).toThrowError('Comune with name of Foo and prov EE doesn\'t exists')
|
||||
})
|
||||
})
|
||||
|
||||
describe('CodiceFiscale.findLocationCode', () => {
|
||||
test('è definito', () => {
|
||||
expect(CodiceFiscale.findLocationCode).not.toBe(undefined)
|
||||
expect(CodiceFiscale.findLocationCode).toBeDefined()
|
||||
})
|
||||
|
||||
test('trova il codice del comune', () => {
|
||||
@ -126,20 +128,20 @@ describe('CodiceFiscale.findLocationCode', () => {
|
||||
var comuneInventato = function () {
|
||||
CodiceFiscale.findLocationCode('Foo', 'Bar')
|
||||
}
|
||||
expect(comuneInventato).toThrowError('Area code not found')
|
||||
expect(comuneInventato).toThrowError('Comune with name of Foo and prov Bar doesn\'t exists')
|
||||
})
|
||||
|
||||
test('se il comune non esiste lancia un eccezione', () => {
|
||||
var comuneInventato = function () {
|
||||
CodiceFiscale.findLocationCode('Foo', 'RM')
|
||||
}
|
||||
expect(comuneInventato).toThrowError('Location not found')
|
||||
expect(comuneInventato).toThrowError('Comune with name of Foo and prov RM doesn\'t exists')
|
||||
})
|
||||
})
|
||||
|
||||
describe('CodiceFiscale.check', () => {
|
||||
test('è definito', () => {
|
||||
expect(CodiceFiscale.check).not.toBe(undefined)
|
||||
expect(CodiceFiscale.check).toBeDefined()
|
||||
})
|
||||
|
||||
test('controlla se il codice fiscale è valido', () => {
|
||||
@ -166,7 +168,7 @@ describe('CodiceFiscale.check', () => {
|
||||
|
||||
describe('CodiceFiscale.getOmocodie', () => {
|
||||
test('è definito', () => {
|
||||
expect(CodiceFiscale.getOmocodie).not.toBe(undefined)
|
||||
expect(CodiceFiscale.getOmocodie).toBeDefined()
|
||||
})
|
||||
|
||||
test('calcola le omocodie dato un codice fiscale', () => {
|
||||
@ -177,36 +179,62 @@ describe('CodiceFiscale.getOmocodie', () => {
|
||||
|
||||
describe('Calcolo codice fiscale inverso -> metodo .computeInverse', () => {
|
||||
test('è definito', () => {
|
||||
expect(CodiceFiscale.computeInverse).not.toBe(undefined)
|
||||
expect(CodiceFiscale.computeInverse).toBeDefined()
|
||||
})
|
||||
|
||||
test("se l'input non è una stringa lancia un eccezione", () => {
|
||||
var notAString = function () {
|
||||
CodiceFiscale.computeInverse(0)
|
||||
}
|
||||
expect(notAString).toThrowError('Provided input is not a valid Codice Fiscale')
|
||||
expect(notAString).toThrowError("Comune constructor accept either a valid string or a plain object. Check the documentation")
|
||||
})
|
||||
|
||||
test("restituisce falso se l'input è stringa formattata male", () => {
|
||||
var notValid = function () {
|
||||
CodiceFiscale.computeInverse('BNZVCN32SC0E573Z')
|
||||
}
|
||||
expect(notValid).toThrowError('Provided input is not a valid Codice Fiscale')
|
||||
expect(notValid).toThrowError("Provided input is not a valid Codice Fiscale")
|
||||
})
|
||||
|
||||
|
||||
/* Nome: MARIO
|
||||
* Cognome: ROSSI
|
||||
* Nato a : ROMA (RM)
|
||||
* Giorno : 23
|
||||
* Mese : Giugno (6)
|
||||
* Anno : 1980
|
||||
* Sesso : M
|
||||
*/
|
||||
let mario_rossi_cf = "RSSMRA80H23H501T";
|
||||
|
||||
test('restituisce il genere corretto', () => {
|
||||
expect(CodiceFiscale.computeInverse('MRNLCU00A01H501J').gender).toEqual('M')
|
||||
expect(CodiceFiscale.computeInverse(mario_rossi_cf).gender).toEqual('M')
|
||||
})
|
||||
|
||||
test('restituisce la città natale corretta', () => {
|
||||
expect(CodiceFiscale.computeInverse('MRNLCU00A01H501J').birthplace).toEqual('ROMA')
|
||||
expect(CodiceFiscale.computeInverse(mario_rossi_cf).birthplace).toEqual('ROMA')
|
||||
})
|
||||
|
||||
test('restituisce la provincia della città natale corretta', () => {
|
||||
expect(CodiceFiscale.computeInverse('MRNLCU00A01H501J').birthplaceProvincia).toEqual('RM')
|
||||
expect(CodiceFiscale.computeInverse(mario_rossi_cf).birthplaceProvincia).toEqual('RM')
|
||||
})
|
||||
|
||||
test('restituisce il giorno di nascita come numero compreso tra 1 e 31', () => {
|
||||
expect(CodiceFiscale.computeInverse('MRNLCU00A01H501J').day >= 1 && CodiceFiscale.computeInverse('MRNLCU00A01H501J').day <= 31).toBe(true)
|
||||
let day = CodiceFiscale.computeInverse(mario_rossi_cf).day
|
||||
expect(day >= 1 && day <= 31).toBe(true)
|
||||
})
|
||||
|
||||
test('restituisce il giorno corretto', () => {
|
||||
expect(CodiceFiscale.computeInverse(mario_rossi_cf).day).toBe(23)
|
||||
})
|
||||
|
||||
test('restituisce il mese corretto', () => {
|
||||
expect(CodiceFiscale.computeInverse(mario_rossi_cf).month).toBe(6);
|
||||
})
|
||||
|
||||
test('restituisce anno corretto', () => {
|
||||
expect(CodiceFiscale.computeInverse(mario_rossi_cf).year).toBe(1980);
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
@ -4,6 +4,7 @@ const createVariants = require('parallel-webpack').createVariants
|
||||
|
||||
function createConfig (options) {
|
||||
return {
|
||||
mode: "production",
|
||||
entry: {
|
||||
'codice.fiscale': './src/codice-fiscale.js'
|
||||
},
|
||||
@ -22,19 +23,14 @@ function createConfig (options) {
|
||||
test: /\.js$/,
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['babel-preset-env']
|
||||
}
|
||||
loader: 'babel-loader'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack
|
||||
.optimize
|
||||
.UglifyJsPlugin()
|
||||
]
|
||||
optimization: {
|
||||
minimize: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user