PDA

Ver la Versión Completa : Nuevos dígitos en CIF y NIF españoles


apicito
15-09-2008, 11:02:06
Llevo días buscando información sobre como actualizar las rutinas de validación de Nif Y Cif españoles con las nuevas letras que aceptan ahora: I,J para las personas jurídicas y para los NIE de extranjeros: YZ.
Aguien sabe algo del tema?.

Casimiro Notevi
16-09-2008, 09:04:30
http://www.seg-social.es/stpri00/groups/public/documents/binario/108732.pdf


Como consecuencia de la entrada en vigor el pasado 1 de julio, del Real Decreto 1065/2007 de 27 de julio de 2007, y de la Orden EHA/451/2008 de 20 de febrero de 2008, se han creado nuevas letras del NIF de las entidades jurídicas (CIF), código que es asignado por la Agencia Estatal de Administración Tributaria.
El NIF de las entidades jurídicas es un código de identificación de 9 caracteres –una letra, siete dígitos numéricos y un carácter de control-. Hasta ahora los valores posibles en la primera posición eran A,B,C,D,E,F,G,H,N,P,Q,S.
A partir de la entrada en vigor de la Orden EHA/0451/2008 se crean los valores J,U,V,W,R, destinados a identificar, respectivamente, a las sociedades civiles, con o sin personalidad jurídica; a las uniones temporales de empresa; a otros tipos de entidades jurídicas nacionales no definidos en el resto de claves; a establecimiento permanente de entidad no residente en territorio español; y a congregaciones e instituciones religiosas.
Respecto al resto de caracteres no se observa ninguna modificación con respecto a la configuración actual.
Por otra parte, también se han producido modificaciones en la configuración del Número de Identificación de Extranjeros (NIE)
Dicho identificador siempre tiene 9 caracteres de longitud –una letra, siete dígitos numéricos y un carácter de control alfabético-.
Dado que se ha agotado la capacidad de numeración de los siete dígitos, y para no modificar la longitud de dicho identificador, se han creado dos nuevas letras para la posición inicial (hasta ahora sólo se admitía la ‘X’ en esa posición): Y, Z.
En los tres supuestos –X,Y,Z- el tipo de identificador de persona física seguirá siendo el “6”.
Ambas modificaciones han sido implementadas en todas las aplicaciones del Sistema RED.

apicito
17-09-2008, 11:41:14
Perdona por no contestarte antes...
Mi pregunta es: ¿Como afecta esto a las rutinas de validación existentes?
Solo se le añaden las nuevas letras y ya está?

apicito
17-09-2008, 11:56:42
Lo he resuelto así.
Pero ojo!!!! No tengo suficientes CIF's y NIF's para hacer la comprobación, por lo que puede ser que falle en algún caso.
Es unha modificación sobre unas funciones que no recuerdo de donde las saqué, quizás de trucomania.
{----------------------------------------------------------EsCif---------------}
{ Validar si un CIF introducido es correcto}
function TDatos.EsCif(Cif : String) : Boolean;
var
Suma, Control : Integer;
n : Byte;
begin
Result := False;

{Se pasa todo a mayúsculas limpio de espacios y de caracteres especiales}
Cif := UpperCase(Trim(Cif));

{Se limpia de los caracteres '-' y '/'. }
Cif := CadCambioCar(Cif,'-','');
Cif := CadCambioCar(Cif,'/','');

{El cif debe ser de 9 cifras}
if Length(Cif) = 9 then
begin
{Comprobamos que sea un NIF}
if (pos(Cif[1],'0123456789'))>0 then
Result := EsNif(Cif)
else
begin
{Se comprueba que la letra que designa el tipo de cif sea correcta}
if (Pos(Cif[1], 'ABCDEFGHPQSKLMXYZJUVWR') = 0) then
Result := False
else
{Se comprueba si es un extranjero,
en ese caso se calcula el nif, cambiando la X,Y,Z, por 0}
if (Pos(Cif[1], 'XYZ') = 1) then
// if Cif[1] = 'X' then
Result := EsNif('0'+Copy(Cif,2,8))
else
begin
Suma:= StrToInt(Cif[3])+StrToInt(Cif[5])+StrToInt(Cif[7]);
for n := 1 to 4 do
Suma := Suma +
((2*StrToInt(Cif[2*n])) mod 10)+((2*StrToInt(Cif[2*n])) div 10);
Control := 10 - (Suma mod 10);
{Se comprueba si es de tipo 'P' o 'S', es decir,
Corporaciones Locales (Ayuntamientos, etc.)
y Organismos públicos.}
if Pos(Cif[1],'PSQ')<>0 then
{Control tipo letra}
Result := (Cif[9] = Chr(64+Control))
else
{Resto de tipos de CIF}
begin
{Control tipo número}
if Control = 10 then
Control := 0;
Result:= ( StrToInt(Cif[9]) = Control);
end;
end;
end;
end;
end;
{----------------------------------------------------------EsNif---------------}
function TDatos.EsNif(Cif:String): Boolean;
var a:string;
Dni:String;
Letra:String;
begin
Dni:=copy(cif,1,8);
a:=Copy('TRWAGMYFPDXBNJZSQVHLCKET',StrToInt( Dni ) mod 23 + 1, 1 );
Letra:=Copy(cif,9,1);
if a = letra then
result:=True
else
result:=False;
end;

apicito
18-09-2008, 07:42:11
Las modificaciones no sirven. Siento haberlas publicado. Si el administrador quiere eliminar mi post anterior...

Casimiro Notevi
18-09-2008, 07:49:26
Creo entender que las letras esas no son las que hay que calcular, sino las que se añaden según el tipo de empresa, por ejemplo, las sociedades anónimas empiezan por 'A', las limitadas por 'B', etc. y esas nuevas letras serán para definir también el tipo de sociedad.
Por eso dice: ...se han creado nuevas letras del NIF de las entidades jurídicas (CIF), código que es asignado por la Agencia Estatal de Administración Tributaria.
O sea, que no son las letras que calculamos según el número de DNI.

Al menos, eso es lo que entiendo.

apicito
19-09-2008, 11:08:16
Yo entiendo que en el caso de las sociedades solo tenemos que añadir las nuevas letras para que las acepte. Eso creo que funciona en las modificacones que hice.
En el caso de los NIE, "yo entiendo", que además de detectar las letras YZ lo demás sigue igual. Osea, que con el resto de los caracteres se valida como un DNI normal, igual que pasaba hasta ahora con la X. Pero he probado con dos numeros que tengo y no me funciona. No tengo la seguridad de que estén bien estos dos números, pero deberían ser buenos. Pero no entiendo porque no me valida los restantes caracteres bien.

apicito
24-09-2008, 09:59:45
Bueno, creo que he encontrado el problema y es que la cita de Casimiro que pega una noticia de la seguridad social española tiene un error, no de casimiro sino de l seg.socail, cuando dice:
Dicho identificador siempre tiene 9 caracteres de longitud –una letra, siete dígitos numéricos y un carácter de control alfabético-
Ya que en el caso de los NIE la longitud es de 10 caracteres, así lo está exigiendo el I.N.Estadistica: 1 letra, ocho numeros y 1 letra.
Osea que la validación del NIE supone comprobar que empieza por XYZ y es este caso comprobar que con los restantes 9 dígitos valida correctamente como si fuera un DNI español.
Por ello deje las funciones anteriores así:

{----------------------------------------------------------EsCif---------------}
{ Validar si un CIF introducido es correcto}
function TDatos.EsCif(Cif : String) : Boolean;
var
Suma, Control : Integer;
n : Byte;
begin
Result := False;

{Se pasa todo a mayúsculas limpio de espacios y de caracteres especiales}
Cif := UpperCase(Trim(Cif));

{Se limpia de los caracteres '-' y '/'. }
Cif := CadCambioCar(Cif,'-','');
Cif := CadCambioCar(Cif,'/','');

{El cif debe ser de 9 cifras}
if (Length(Cif) = 9) or (Length(Cif) = 10) then
begin
{Comprobamos que sea un NIF}
if (pos(Cif[1],'0123456789'))>0 then
Result := EsNif(Cif)
else
begin
{Se comprueba que la letra que designa el tipo de cif sea correcta}
if (Pos(Cif[1], 'ABCDEFGHPQSKLMXYZJUVWR') = 0) then
Result := False
else
{Se comprueba si es un extranjero,
en ese caso se calcula el nif, cambiando la X, por 0}
if (Pos(Cif[1], 'XYZ') = 1) then
result := EsNif(Copy(Cif,2,9))
else
begin
Suma:= StrToInt(Cif[3])+StrToInt(Cif[5])+StrToInt(Cif[7]);
for n := 1 to 4 do
Suma := Suma +
((2*StrToInt(Cif[2*n])) mod 10)+((2*StrToInt(Cif[2*n])) div 10);
Control := 10 - (Suma mod 10);
{Se comprueba si es de tipo 'P' o 'S', es decir,
Corporaciones Locales (Ayuntamientos, etc.)
y Organismos públicos.}
if Pos(Cif[1],'PSQ')<>0 then
{Control tipo letra}
Result := (Cif[9] = Chr(64+Control))
else
{Resto de tipos de CIF}
begin
{Control tipo número}
if Control = 10 then
Control := 0;
Result:= ( StrToInt(Cif[9]) = Control);
end;
end;
end;
end;
end;
{----------------------------------------------------------EsNif---------------}
function TDatos.EsNif(Cif:String): Boolean;
var a:string;
Dni:String;
Letra:String;
begin
Dni:=copy(cif,1,8);
a:=Copy('TRWAGMYFPDXBNJZSQVHLCKET',StrToInt( Dni ) mod 23 + 1, 1 );
Letra:=Copy(cif,9,1);
if a = letra then
result:=True
else
result:=False;
end;
Espero no haberme equivicado esta vez.