Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,37 @@ Viene validato:
* checksum
* compatibile con omocodie

Ho aggiunto:

```javascript
var isCf = require('codice_fiscale_validator');
//ritorna false quando non ci sono errori nel cf,
//o la stringa di errore. Senza lanciare eccezioni.

var r= isInvalidCF( codiceFiscale )

if( r=== false )
console.log( "nessun errore" )
else
console.log( "msg errore:",r )

//ratio: trovo scomodo chiamare una funzione di test che lancia eccezioni
//perche il codice diventa piu complicato del necessario.


//le dichiarazione delle funzioni vengono esportate tramite module.export se questo esiste,
//in modo che il codice sia utilizzabile senza modifiche in node.js e nel browser
//senza librerie esterne (k.i.s.s.)

//possiamo utilizzarla ad esempio in node tramite
var Cf = require('codice_fiscale');
var r= Cf.isInvalidCF( codiceFiscale )

//ed utilizzare la funzione isCf (che lancia eccezioni quando incontra cf errati)
//senza modificare il codice esistente

//valido
try{
isCf('LLEGNN86P23F205T'); //-> true
Cf.isCf('LLEGNN86P23F205T'); //-> true
}
catch(err){
//err === null
Expand All @@ -28,3 +53,5 @@ Viene validato:
//err instanceof Error
}
```

app.html mostra una direttiva che usa questo libreria per validare il cf
131 changes: 131 additions & 0 deletions app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<!DOCTYPE html>
<html>
<head>
<title>angular custom directive for italian fiscale code</title>


<script src= "codice_fiscale.js"></script>
<script src= "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>



<script>
var app = angular.module('app', [])


app.service('cfService', function ()
{

this.isInvalidCF= isInvalidCF //function(cf){ return isInvalidCF(cf) }
this.getOmocodiaProgressiveNumber= getOmocodiaProgressiveNumber

})





app.directive('italianFiscalCode', function()
{
var controller= [ '$scope','cfService' ,function ($scope,cfService)
{
function setup()
{
$scope.validate()
}


$scope.$watch('model' ,function()
{
console.log( "watch: model" )
$scope.validate()
});


$scope.validate = function ()
{
if( cfService.isInvalidCF( $scope.model ) )
$scope.color= "red"
else
$scope.color= "green"

$scope.counter= getOmocodiaProgressiveNumber( $scope.model )
if( $scope.counter>0 )
$scope.omocodiacolor='orange'
else
$scope.omocodiacolor='green'
}

setup()
}]

return {
restrict: 'ACME',
replace: 'true',

templateUrl: 'cf.html',

scope:
{
model: '@',
color: '@'
,counter:'@'
}

,controller: controller
};

})






app.controller('CtrlA', function($scope)
{
});




</script>
</head>

<body ng-app="app" >
<div ng-controller="CtrlA">

<pre>
Custom directive with autocheck fiscal code, and multyplicity of code called "omocodia"
Stricly the Agenzia Entrate is the authority that could check the data inside the code,
and it provides a tool (behind captha) to validate the fiscal code.
https://telematici.agenziaentrate.gov.it/VerificaCF/Scegli.do?parameter=verificaCf

according to the tax bureau the nations today are Z001 a Z907,
this directive validate aggressively so a nation Z940 is considered not valid.
the drawback is that shoud be keeped aligned to the list of nations.
http://www.agenziaentrate.gov.it/wps/content/Nsilib/Nsi/Strumenti/Codici+attivita+e+tributo/Codici+territorio/Comuni+italia+esteri/

the Agenzia delle Entrate when two or more codes point to the same string beacuse of its data
change the code progressively replacing number with letter, because there are 7 letter,
and each one could be replaced or not, the maximum multiplicity of the same code is 128!.

some nice descriptions of this hash function (in italian):
https://it.wikipedia.org/wiki/Codice_fiscale#Omocodie
http://www.paginainizio.com/service/strutturacodicefiscale.htm
http://www.dotnethell.it/articles/CalcoloCodiceFiscale.aspx
</pre>
<hr>

<div data-italian-fiscal-code model="MLLSNT82P65Z404U"></div>
<div data-italian-fiscal-code ></div>
<br>

<div data-italian-fiscal-code model="MRTMTT25Dp9F205Z"></div>
<div data-italian-fiscal-code model="MRTMTT25D09F205Z"></div>


</div>

</body>
</html>
10 changes: 10 additions & 0 deletions cf.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div >
<label class="ng-binding" for="{{chiave}}" style="background-color:{{color}}">
&nbsp;cf&nbsp;
</label>
<input type="text" ng-model="model" maxlength="16" placeholder="cf">
<label class="ng-binding" for="omocodia" style="background-color:{{omocodiacolor}}">
omocodia: {{counter}}&nbsp;
</label>
<input type="hidden" ng-model="omocodia">
</div>
122 changes: 111 additions & 11 deletions codice_fiscale.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,24 @@ var listCtrlCode = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',

var listError = { 0 : 'Empty code', 1 : 'Len error', 2 : 'Code with wrong char', 3 : 'Code with wrong char in omocodia', 4 : 'Wrong code'};

module.exports = function checkCf(codiceFiscale){
/*
return the error description of cf, or false if the codiceFiscale is correct
*/
//module.exports.isInvalidCF = function (codiceFiscale){

function isInvalidCF(codiceFiscale){

if(!codiceFiscale){

throw new Error(listError[0]);
if(!codiceFiscale){
return listError[0];
}

if(codiceFiscale.length !== 16){

throw new Error(listError[1]);
return listError[1];
}

if(! codiceFiscale.match(REGEX_CODICEFISCALE) ){

throw new Error(listError[2]);
if(!codiceFiscale.match(REGEX_CODICEFISCALE)){
return listError[2];
}

var cfCharList = codiceFiscale.toUpperCase().split('');
Expand All @@ -45,7 +47,7 @@ module.exports = function checkCf(codiceFiscale){

if ( isNaN(charAtIndex) && listDecOmocodia[charAtIndex] ==='!'){

throw new Error(listError[3]);
return listError[3];
}
});

Expand All @@ -63,8 +65,106 @@ module.exports = function checkCf(codiceFiscale){

if( checksum !== cfCharList[15] ){

throw new Error(listError[4]);
return listError[4];
}

return true;
return false;
};


//for backward compatibility
//it raise error on wrong codes
//and return true on rigth one
function checkCf(codiceFiscale)
{
var r= isInvalidCF(codiceFiscale);

if( r=== false )
return true;

throw new Error( r );
}



/*
check for identify an omocodia,
is possible detece the progressive number identifing a fiscal code
for each code could be one strigth fiscal code with no omocodia,
and at maximum 128 code rimapped encoding the number in the fiscal code with string

this function return an integer, 0 mean no omocodia,
4 mean that this code is 4omocodic fiscal code (pointing to the straigth version)
and so on
*/

//module.exports.getOmocodiaProgressiveNumber = function ( sCf )

function getOmocodiaProgressiveNumber( sCf )
{
if( !sCf )
return 0

var reOmocode = /[lmnpqrstuv]/ig;

var tmp

var iOmocodia= 0;
var aOmocodiaPosition=[ 14,13,12,10,9,7,6 ]

/*if the cf is shorter than expected we would calculate anyway
if the cf sound omocodic*/
var iMax=sCf.length
var tmp=[]
var i
for( i=0; i<aOmocodiaPosition.length; i++ )
{
if(aOmocodiaPosition[i]<iMax)
tmp.push( aOmocodiaPosition[i] )
}
aOmocodiaPosition= tmp;

/*
There is an omocodia when a fiscal code is not unique
in other words there are distinct people with the the same fiscal code,
In computer slang we could say that when we call "omocodia" when there is a the fiscal hash collapse.
to solve this condition the italian tax bureau
must replace the numbers with letter (from left to right).
Because there are 7 numbers that can be replaced with a corrispondent number
this is the map of the encoding with omocodia:
0->L 5->R
1->M 6->S
2->N 7->T
3->P 8->U
4->Q 9->V

there could be 2^7 combination of the same fiscal code.
Omocodia a rare, but on average year there are ~1400 new omocodia.
*/
for( var i=0; i<aOmocodiaPosition.length; i++ )
{
//tmp= sCf[ aOmocodiaPosition[i] ]
//if( reOmocode.test( tmp ) )
if( reOmocode.test( sCf[ aOmocodiaPosition[i] ] ) )
{
iOmocodia+= Math.pow(2,i)
}
}

return iOmocodia;
}

//for backward compatibilty with node module export
try{
if(module)
{

module.exports.isInvalidCF = isInvalidCF
module.exports.getOmocodiaProgressiveNumber = getOmocodiaProgressiveNumber
module.exports.checkCf= checkCf
}
}
catch(e)
{
console.log( "error",e )
}
22 changes: 0 additions & 22 deletions codice_fiscale.test.js

This file was deleted.

32 changes: 32 additions & 0 deletions codice_fiscale.test.kiss.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

var cfLib = require('./codice_fiscaleB.js');

// a simple test function:
// callbacke with parameter agaiunst it's expected value
// not external dependecy,
function kissTest( describeTest ,callback, parameter ,expectedReturnValue ){
var returnedValue

try
{
returnedValue= callback(parameter)
if( returnedValue === expectedReturnValue )
console.log( describeTest, "passed" )
else
console.log( describeTest, "Error:",expectedReturnValue ,"<>" ,returnedValue )
}
catch(e)
{
console.log( describeTest,e )
}
}


kissTest( 'cf test isInvalidCF on good cf',cfLib.isInvalidCF,'LLEGNN86P23F205T',false )
kissTest( 'cf test isInvalidCF on good cf',cfLib.isInvalidCF,'MLLSNT82P65Z404U',false )
kissTest( 'cf test isInvalidCF on good cf',cfLib.isInvalidCF,'MRTMTT25D09F205Z',false )

kissTest( 'cf test omocodia 0 ',cfLib.getOmocodiaProgressiveNumber,'MLLSNT82P65Z404U',0 )
kissTest( 'cf test omocodia 0 ',cfLib.getOmocodiaProgressiveNumber,'MRTMTT25D09F205Z',0 )
kissTest( 'cf test omocodia 64',cfLib.getOmocodiaProgressiveNumber,'MLLSNTU2P65Z404U',64 )