From 5830a0d8f995f7306296282dcb581ffa6918a048 Mon Sep 17 00:00:00 2001 From: Juan Date: Tue, 27 Feb 2018 10:00:43 +0100 Subject: [PATCH] Bug #94 - FI validation --- .../common/validations/validateDni.js | 154 ++++++++---------- 1 file changed, 66 insertions(+), 88 deletions(-) diff --git a/services/loopback/common/validations/validateDni.js b/services/loopback/common/validations/validateDni.js index 4f8a3089be..8c2060eba1 100644 --- a/services/loopback/common/validations/validateDni.js +++ b/services/loopback/common/validations/validateDni.js @@ -1,97 +1,75 @@ module.exports = fi => { - if (fi === undefined || fi === null) { + if (fiWithCountry == null) return true; - } - let dni = fi; - let getLetterDni = dni => { - const regExpDni = 'TRWAGMYFPDXBNJZSQVHLCKE'; - const letterDni = dni.toUpperCase().substring(0, 1); - let positionLetter = parseInt(dni) % 23; - let getLetter = regExpDni.substring(positionLetter + 1, positionLetter); - switch (letterDni) { - case 'X': case 'Y': case 'Z': - positionLetter = parseInt(dni.replace(letterDni, letterDni.charCodeAt(0) - 88)) % 23; - getLetter = regExpDni.substring(positionLetter + 1, positionLetter); + + fiWithCountry = fiWithCountry.toUpperCase(); + + if (!/^[A-Z]{2}/.test(fiWithCountry)) + fiWithCountry = `ES${fiWithCountry}`; + + let country = fiWithCountry.substring(0, 2).toLowerCase(); + let fi = fiWithCountry.substring(2); + let len = fi.length; + + let validators = { + es: { + regExp: /^ES[A-Z0-9]\d{7}[A-Z0-9]$/, + validate: () => { + let isCif = /[A-W]/.test(fi.charAt(0)); + let lastDigit = fi.charAt(len - 1); + let computedDigit; + + if (isCif) { + let numbers = fi.substring(1, 8) + .split('') + .map(x => parseInt(x)); + + let pairSum = numbers + .filter((_, i) => i % 2 != 0) + .reduce((a, x) => a + x); + + let oddSum = numbers + .filter((_, i) => i % 2 == 0) + .map(x => x * 2) + .join('') + .split('') + .map(x => parseInt(x)) + .reduce((a, x) => a + x); + + let sum = (pairSum + oddSum).toString(); + let units = parseInt(sum.charAt(sum.length - 1)); + let control = units != 0 ? 10 - units : 0; + let index = 'JABCDEFGHI'.indexOf(lastDigit); + computedDigit = index == -1 ? control.toString() : index; + } else { + // Foreign NIF + let index = 'XYZ'.indexOf(fi.charAt(0)); + let nif = index == -1 ? fi : index.toString() + fi.substring(1); + + let number = parseInt(nif.substring(0, 8)); + let rest = number % 23; + computedDigit = 'TRWAGMYFPDXBNJZSQVHLCKE'.charAt(rest); + } + + return computedDigit == lastDigit; + } + }, + pt: { + regExp: /^PT\d{9}$/ + }, + fr: { + regExp: /^FR[A-Z0-9]{2}\d{9}$/ + }, + it: { + regExp: /^IT\d{11}$/ } - return getLetter; }; - let getDniSpain = (dniNumeric, dniLetter) => { - let returnValue = false; - switch (dni.length) { - case 9: - if (dniLetter === getLetterDni(dni)) - returnValue = true; - } - return returnValue; - }; + let validator = validators[country]; - let getDniForeign = (dniNumeric, dniLetter) => { - let returnValue = false; - switch (dni.length) { - case 9: - if (dniLetter === getLetterDni(dni)) - returnValue = true; - } - return returnValue; - }; - - let getDniBusiness = () => { - if (dni.length == 9) - return true; + if (!validator) return false; - }; - let getDniFrance = dniLetterCountry => { - let returnValue = false; - switch (dni.length) { - case 13: - if (dniLetter === 'R') - returnValue = true; - } - return returnValue; - }; - - let getDniItaly = dniLetterCountry => { - let returnValue = false; - switch (dni.length) { - case 13: - if (dniLetter === 'T') - returnValue = true; - } - return returnValue; - }; - - let getDni = () => { - const dniNumeric = dni.substring(0, 8); - const dniLetter = dni.substring(8, 9); - const dniLetterCountry = dni.substring(0, 1); - const dniLetterAscii = parseInt(dniLetterCountry.charCodeAt(0)); - let dniValue = false; - switch (true) { - case (dni.length === 9 && !isNaN(dni)): // dni Portugal (9 digitos) - dniValue = true; - break; - case (dniLetterAscii >= 88 && dniLetterAscii <= 90): // X-Z - dniValue = getDniForeign(dniNumeric, dniLetter); - break; - case (dniLetterAscii === 66): // B - dniValue = getDniBusiness(); - break; - case (dniLetterAscii === 70): // F - dniValue = getDniFrance(dniLetterCountry); - break; - case (dniLetterAscii === 73): // I - dniValue = getDniItaly(dniLetterCountry); - break; - case (dni.length === 9 && dniLetterAscii >= 48 && dniLetterAscii <= 57): // 0- 9 - dniValue = getDniSpain(dniNumeric, dniLetter); - break; - default: - dniValue = true; - } - return dniValue; - }; - - return getDni(); + return validator.regExp.test(fiWithCountry) + && (!validator.validate || validator.validate()); };