6 de noviembre de 2007

Corregir un NIF con PHP

Sigo pasando mis dias entre constipados y el desarrollo de un proyecto hecho con php y mysql siguiendo la extendida tendencia de llevar las aplicaciones de escritorio a la web.

Además de lo sorprendente que me está resultando Jquery, ya hablaremos más adelante de ello, estos días se me había planteado la necesidad de poder incorporar grandes archivos con series de DNI a la aplicación para poder trabajar con ellos. El inconveniente es que esos archivos provienen de distintos sitios y en algunos casos traen la letra, en otros se omiten los ceros a la izquierda, en otros casos hay errores o incluso se han insertado separadores de miles.

Para evitar la pesadez que supone que cada vez que alguien quiera incorporar uno de esos archivos tenga que modificar todos los DNI hasta convertirlos en NIF correctos (8 números más una letra de control), desarrollé esta pequeña función que toma un número que se asemeja a un NIF y devuelve un NIF totalmente correcto.
function corregir_nif($numero) {
$numero = str_replace( ',', '', $numero ); //Limpiamos separadores de miles, etc
$numero = str_replace( '.', '', $numero );
$numero = str_replace( '-', '', $numero );
$numero = str_replace( ' ', '', $numero );

if (strtoupper(substr($numero,0,1))!="X") { //Si es extranjero nos rendimos
if (strlen($numero)==7) {
$dni = "0".substr($numero, 0, 7);
}
else if (strlen($numero)==8) { //Probablemente le falte el cero o le falte la letra
if (is_nan(substr($numero, -1, 1)==1)) { //Si la letra no es un número
$dni = "0".substr($numero, 0, 7);
}
else {
$dni = substr($numero, 0, 8);
}
}
else if (strlen($numero)==9) { //Puede ser correcto
$dni = substr($numero, 0, 8);
}
else if (strlen($numero)>9) {
$dni = substr($numero, 1, 9);
}
}
$nif=$dni.letraNif($dni);
return $nif;
}
No es perfecta y se puede hacer con menos código, pero es que creo que es importante que sea legible. La parte de los NIF extranjeros la haré otro día, que ahora ando un poco perezoso.

Falta una función dentro del objeto llamada letraNif que es trivíal, se encarga de calcular la letra correcta. Sería algo así:
function letraNif ($dni) {
$valor= (int) ($dni / 23);
$valor *= 23;
$valor= $dni - $valor;
$serie= "TRWAGMYFPDXBNJZSQVHLCKEO";
$letra= substr ($serie, $valor, 1);
return $letra;
}

Espero que le sea de utilidad a alguien ahí fuera.