Skip to content

Commit

Permalink
Added NIF, NIE and CIF Spanish documents numbers validation
Browse files Browse the repository at this point in the history
* Added some translations to /localization
* Added test suite
Fixes gh-830
  • Loading branch information
Alfonso Martín authored and nschonni committed Aug 22, 2013
1 parent 519bbc6 commit 317c20f
Show file tree
Hide file tree
Showing 11 changed files with 241 additions and 6 deletions.
62 changes: 62 additions & 0 deletions src/additional/cifES.js
@@ -0,0 +1,62 @@
/*
* Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities
* Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
*/
jQuery.validator.addMethod( "cifES", function ( value, element ) {
"use strict";

var sum,
num = [],
controlDigit;

value = value.toUpperCase();

// Quick format test
if ( !value.match( '((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)' ) ) {
return false;
}

for ( var i = 0; i < 9; i++ ) {
num[ i ] = parseInt( value.charAt( i ), 10 );
}

// Algorithm for checking CIF codes
sum = num[ 2 ] + num[ 4 ] + num[ 6 ];
for ( var count = 1; count < 8; count += 2 ) {
var tmp = ( 2 * num[ count ] ).toString(),
secondDigit = tmp.charAt( 1 );

sum += parseInt( tmp.charAt( 0 ), 10 ) + ( secondDigit === '' ? 0 : parseInt( secondDigit, 10 ) );
}

/* The first (position 1) is a letter following the following criteria:
* A. Corporations
* B. LLCs
* C. General partnerships
* D. Companies limited partnerships
* E. Communities of goods
* F. Cooperative Societies
* G. Associations
* H. Communities of homeowners in horizontal property regime
* J. Civil Societies
* K. Old format
* L. Old format
* M. Old format
* N. Nonresident entities
* P. Local authorities
* Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions
* R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)
* S. Organs of State Administration and regions
* V. Agrarian Transformation
* W. Permanent establishments of non-resident in Spain
*/
if ( /^[ABCDEFGHJNPQRSUVW]{1}/.test( value ) ) {
sum += '';
controlDigit = 10 - parseInt( sum.charAt( sum.length - 1 ), 10 );
value += controlDigit;
return ( num[ 8 ].toString() === String.fromCharCode( 64 + controlDigit ) || num[ 8 ].toString() === value.charAt( value.length - 1 ) );
}

return false;

}, "Please specify a valid CIF number." );
35 changes: 35 additions & 0 deletions src/additional/nieES.js
@@ -0,0 +1,35 @@
/*
* The número de identidad de extranjero ( NIE )is a code used to identify the non-nationals in Spain
*/
jQuery.validator.addMethod( "nieES", function ( value, element ) {
"use strict";

value = value.toUpperCase();

// Basic format test
if ( !value.match( '((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)' ) ) {
return false;
}

// Test NIE
//T
if ( /^[T]{1}/.test( value ) ) {
return ( value[ 8 ] === /^[T]{1}[A-Z0-9]{8}$/.test( value ) );
}

//XYZ
if ( /^[XYZ]{1}/.test( value ) ) {
return (
value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt(
value.replace( 'X', '0' )
.replace( 'Y', '1' )
.replace( 'Z', '2' )
.substring( 0, 8 ) % 23
)
);
}

return false;

}, "Please specify a valid NIE number." );

25 changes: 25 additions & 0 deletions src/additional/nifES.js
@@ -0,0 +1,25 @@
/*
* The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals
*/
jQuery.validator.addMethod( "nifES", function ( value, element ) {
"use strict";

value = value.toUpperCase();

// Basic format test
if ( !value.match('((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)') ) {
return false;
}

// Test NIF
if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {
return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );
}
// Test specials NIF (starts with K, L or M)
if ( /^[KLM]{1}/.test( value ) ) {
return ( value[ 8 ] === String.fromCharCode( 64 ) );
}

return false;

}, "Please specify a valid NIF number." );
5 changes: 4 additions & 1 deletion src/localization/messages_es.js
Expand Up @@ -20,6 +20,9 @@
rangelength: $.validator.format("Por favor, escribe un valor entre {0} y {1} caracteres."),
range: $.validator.format("Por favor, escribe un valor entre {0} y {1}."),
max: $.validator.format("Por favor, escribe un valor menor o igual a {0}."),
min: $.validator.format("Por favor, escribe un valor mayor o igual a {0}.")
min: $.validator.format("Por favor, escribe un valor mayor o igual a {0}."),
nifES: "Por favor, escribe un NIF válido.",
nieES: "Por favor, escribe un NIE válido.",
cifES: "Por favor, escribe un CIF válido."
});
}(jQuery));
5 changes: 4 additions & 1 deletion src/localization/messages_es_AR.js
Expand Up @@ -21,6 +21,9 @@
rangelength: $.validator.format("Por favor, escribí un valor entre {0} y {1} caracteres."),
range: $.validator.format("Por favor, escribí un valor entre {0} y {1}."),
max: $.validator.format("Por favor, escribí un valor menor o igual a {0}."),
min: $.validator.format("Por favor, escribí un valor mayor o igual a {0}.")
min: $.validator.format("Por favor, escribí un valor mayor o igual a {0}."),
nifES: "Por favor, escribí un NIF válido.",
nieES: "Por favor, escribí un NIE válido.",
cifES: "Por favor, escribí un CIF válido."
});
}(jQuery));
5 changes: 4 additions & 1 deletion src/localization/messages_fr.js
Expand Up @@ -42,6 +42,9 @@
creditcardtypes: "Veuillez fournir un numéro de carte de crédit valide.",
ipv4: "Veuillez fournir une adresse IP v4 valide.",
ipv6: "Veuillez fournir une adresse IP v6 valide.",
require_from_group: "Veuillez fournir au moins {0} de ces champs."
require_from_group: "Veuillez fournir au moins {0} de ces champs.",
nifES: "Veuillez fournir un numéro NIF valide.",
nieES: "Veuillez fournir un numéro NIE valide.",
cifES: "Veuillez fournir un numéro CIF valide."
});
}(jQuery));
5 changes: 4 additions & 1 deletion src/localization/messages_it.js
Expand Up @@ -20,6 +20,9 @@
rangelength: $.validator.format("Inserisci un valore compreso tra {0} e {1} caratteri."),
range: $.validator.format("Inserisci un valore compreso tra {0} e {1}."),
max: $.validator.format("Inserisci un valore minore o uguale a {0}."),
min: $.validator.format("Inserisci un valore maggiore o uguale a {0}.")
min: $.validator.format("Inserisci un valore maggiore o uguale a {0}."),
nifES: "Inserisci un NIF valido.",
nieES: "Inserisci un NIE valido.",
cifES: "Inserisci un CIF valido."
});
}(jQuery));
5 changes: 4 additions & 1 deletion src/localization/messages_pt_BR.js
Expand Up @@ -21,6 +21,9 @@
rangelength: $.validator.format("Por favor, forne&ccedil;a um valor entre {0} e {1} caracteres de comprimento."),
range: $.validator.format("Por favor, forne&ccedil;a um valor entre {0} e {1}."),
max: $.validator.format("Por favor, forne&ccedil;a um valor menor ou igual a {0}."),
min: $.validator.format("Por favor, forne&ccedil;a um valor maior ou igual a {0}.")
min: $.validator.format("Por favor, forne&ccedil;a um valor maior ou igual a {0}."),
nifES: "Por favor, forne&ccedil;a um NIF v&aacute;lido.",
nieES: "Por favor, forne&ccedil;a um NIE v&aacute;lido.",
cifEE: "Por favor, forne&ccedil;a um CIF v&aacute;lido."
});
}(jQuery));
5 changes: 4 additions & 1 deletion src/localization/messages_pt_PT.js
Expand Up @@ -21,6 +21,9 @@
rangelength: $.validator.format("Por favor, introduza entre {0} e {1} caracteres."),
range: $.validator.format("Por favor, introduza um valor entre {0} e {1}."),
max: $.validator.format("Por favor, introduza um valor menor ou igual a {0}."),
min: $.validator.format("Por favor, introduza um valor maior ou igual a {0}.")
min: $.validator.format("Por favor, introduza um valor maior ou igual a {0}."),
nifES: "Por favor, introduza um NIF v&aacute;lido.",
nieES: "Por favor, introduza um NIE v&aacute;lido.",
cifES: "Por favor, introduza um CIF v&aacute;lido."
});
}(jQuery));
1 change: 1 addition & 0 deletions test/index.html
@@ -1,6 +1,7 @@
<!DOCTYPE html>
<html id="html">
<head>
<meta charset="utf8" />
<title>jQuery - Validation Test Suite</title>
<link rel="stylesheet" href="qunit/qunit.css" />
<script src="jquery.js"></script>
Expand Down
94 changes: 94 additions & 0 deletions test/methods.js
Expand Up @@ -1028,4 +1028,98 @@ test("zipcodeUS", function() {
ok(!method( "123456-7890" ), "Invalid zip" );
});

test("nifES", function() {
var method = methodTest("nifES");
ok( method( "11441059P" ), "NIF valid" );
ok( method( "80054306T" ), "NIF valid" );
ok( method( "76048581R" ), "NIF valid" );
ok( method( "28950849J" ), "NIF valid" );
ok( method( "34048598L" ), "NIF valid" );
ok( method( "28311529R" ), "NIF valid" );
ok( method( "34673804Q" ), "NIF valid" );
ok( method( "92133247P" ), "NIF valid" );
ok( method( "77149717N" ), "NIF valid" );
ok( method( "15762034L" ), "NIF valid" );
ok( method( "05122654W" ), "NIF valid" );
ok( method( "05122654w" ), "NIF valid: lower case" );
ok(!method( "1144105R" ), "NIF invalid: less than 8 digits without zero" );
ok(!method( "11441059 R" ), "NIF invalid: white space" );
ok(!method( "11441059" ), "NIF invalid: no letter" );
ok(!method( "11441059PR" ), "NIF invalid: two letters" );
ok(!method( "11440059R" ), "NIF invalid: wrong number" );
ok(!method( "11441059S" ), "NIF invalid: wrong letter" );
ok(!method( "114410598R" ), "NIF invalid: > 8 digits" );
ok(!method( "11441059-R" ), "NIF invalid: dash" );
ok(!method( "asdasdasd" ), "NIF invalid: all letters" );
ok(!method( "11.144.059R" ), "NIF invalid: two dots" );
ok(!method( "05.122.654R" ), "NIF invalid: starts with 0 and dots" );
ok(!method( "5.122.654-R" ), "NIF invalid: dots and dash" );
ok(!method( "05.122.654-R" ), "NIF invalid: starts with zero and dot and dash" );
});

test("nieES", function() {
var method = methodTest("nieES");
ok( method( "X0093999K" ), "NIE valid" );
ok( method( "X1923000Q" ), "NIE valid" );
ok( method( "Z9669587R" ), "NIE valid" );
ok( method( "Z8945005B" ), "NIE valid" );
ok( method( "Z6663465W" ), "NIE valid" );
ok( method( "Y7875935J" ), "NIE valid" );
ok( method( "X3390130E" ), "NIE valid" );
ok( method( "Y7699182S" ), "NIE valid" );
ok( method( "Y1524243R" ), "NIE valid" );
ok( method( "X3744072V" ), "NIE valid" );
ok( method( "X7436800A" ), "NIE valid" );
ok( method( "y7875935j" ), "NIE valid: lower case" );
ok(!method( "X0093999 K" ), "NIE inválido: white space" );
ok(!method( "X 0093999 K" ), "NIE inválido: white space" );
ok(!method( "11441059" ), "NIE inválido: no letter" );
ok(!method( "11441059PR" ), "NIE inválido: two letters" );
ok(!method( "11440059R" ), "NIE inválido: wrong number" );
ok(!method( "11441059S" ), "NIE inválido: wrong letter" );
ok(!method( "114410598R" ), "NIE inválido: > 8 digits" );
ok(!method( "11441059-R" ), "NIE inválido: dash" );
ok(!method( "asdasdasd" ), "NIE inválido: all letters" );
ok(!method( "11.144.059R" ), "NIE inválido: two dots" );
ok(!method( "05.122.654R" ), "NIE inválido: starts with 0 and dots" );
ok(!method( "5.122.654-R" ), "NIE inválido: dots and dash" );
ok(!method( "05.122.654-R" ), "NIE inválido: starts with zero and dot and dash" );
});

test("cifES", function() {
var method = methodTest("cifES");
ok( method( "A79082244" ), "CIF valid" );
ok( method( "A60917978" ), "CIF valid" );
ok( method( "A39000013" ), "CIF valid" );
ok( method( "B43522192" ), "CIF valid" );
ok( method( "B38624334" ), "CIF valid" );
ok( method( "G72102064" ), "CIF valid" );
ok( method( "F41190612" ), "CIF valid" );
ok( method( "J85081081" ), "CIF valid" );
ok( method( "S98038813" ), "CIF valid" );
ok( method( "G32937757" ), "CIF valid" );
ok( method( "B46125746" ), "CIF valid" );
ok( method( "C27827559" ), "CIF valid" );
ok( method( "E48911572" ), "CIF valid" );
ok( method( "s98038813" ), "CIF valid: lower case" );
ok(!method( "K48911572" ), "CIF invalid: starts with K" );
ok(!method( "L48911572" ), "CIF invalid: starts with L" );
ok(!method( "M48911572" ), "CIF invalid: starts with M" );
ok(!method( "X48911572" ), "CIF invalid: starts with X" );
ok(!method( "Y48911572" ), "CIF invalid: starts with Y" );
ok(!method( "Z48911572" ), "CIF invalid: starts with Z" );
ok(!method( "M15661515" ), "CIF invalid" );
ok(!method( "Z98038813" ), "CIF invalid: wrong letter" );
ok(!method( "B 43522192" ), "CIF invalid: white spaces" );
ok(!method( "43522192" ), "CIF invalid: missing letter" );
ok(!method( "BB43522192" ), "CIF invalid: two letters" );
ok(!method( "B53522192" ), "CIF invalid: wrong number" );
ok(!method( "B433522192" ), "CIF invalid: > 8 digits" );
ok(!method( "B3522192" ), "CIF invalid: < 8 digits" );
ok(!method( "B-43522192" ), "CIF invalid: dash" );
ok(!method( "Basdasdas" ), "CIF invalid: all letters" );
ok(!method( "B43.522.192" ), "CIF invalid: dots" );
ok(!method( "B-43.522.192" ), "CIF invalid: dots and dash" );
});

})(jQuery);

0 comments on commit 317c20f

Please sign in to comment.