Su partner en Internet

Validar CUPS desde javascript

Validar CUPS

Siempre he querido hacer esta sección, pero por falta de tiempo o «no acordarme» no encontraba el momento de hacerla. Mi intención es ir poniendo entradas de «cosillas» que he tenido que ir haciendo buscando desde internet como hacerlo pero no encontrando la forma final, así que estas cosas que pongo no serán 100% desarrolladas por mi, pero es posible que el resultado final si que le interese a alguien o eso espero :-).

Comienzo esta sección con el validador desde javascript del código CUPS. (Código Unificado de Punto de Suministro).

Recientemente me he encontrado que para cumplimentar un formulario se necesitaba este código según Wikipedia Código CUPS es un código único e identificador de un punto de suministro de energía, ya sea de electricidad o gas canalizado.

Este código se compone de una serie de letras y números que debidamente colocados devuelve un código CUPS válido o inválido. Pues bien, buscando y buscando en internet un validador de CUPS para javascript, nada de nada. 🙁 solución: me dieron el algoritmo en C++ y lo que tuve que hacer simplemente es sustituir. Pero no solo esto, sino que em encontre con diferentes problemas de funciones añadidas en el algoritmo de C++ que son nativas del lenguaje y debía buscar su sustituto en un lenguaje «tan simple» como javascript. El resultado, fenomenal, y aquí os lo enseño.

Math.fmod = function (a,b) { return Number((a - (Math.floor(a / b) * b)).toPrecision(8)); };

function valida_cups(CUPS){	
	var status=false;
    var RegExPattern =/^ES[0-9]{16}[a-zA-Z]{2}[0-9]{0,1}[a-zA-Z]{0,1}$/;
	if ((CUPS.match(RegExPattern)) && (CUPS!='')) {
		var CUPS_16 = CUPS.substr(2,16);
		var control = CUPS.substr(18,2);
		var letters = Array('T','R','W','A','G','M','Y','F','P','D','X','B','N','J','Z','S','Q','V','H','L','C','K','E');

		var fmodv = Math.fmod(CUPS_16,529);
		var imod = parseInt(fmodv);
		var quotient = Math.floor(imod / 23);
		var remainder = imod % 23;
		
		var dc1 = letters[quotient];
		var dc2 = letters[remainder];
		status = (control == dc1+dc2);
	} else {
		status=false;
	}
	if(!status){
		alert("ERROR: Código CUPS incorrecto");
		$('#suministro_cups').val("");
		$('#suministro_cups').focus();
	}
	return status;	
}

Os explico un poco de que va…

  1. Primero pongo un flag en false porque partimos de que hay error.
  2. He creado una expresión regular para poder abarcar la estructura del código (consistente en dos letras mayúsculas (ES) en el caso de España seguido de 16 números, 2 letras más (posiciones 19 y 20) y luego un número y una letra (estas dos últimas partes son opcionales según el CUPS demandado. En la Wikipedia os explica bien cada tipo de CUPS. Si el código que viene como parámetro cumple con la expresión regular no es suficiente!. Por si no la habíais visto, mirar este enlace Test de expresiones regulares te permite probar y probar expresiones hasta que das exactamente con la que necesitas.
  3. Por medio de funciones que calculan fmod (Devuelve el resto en punto flotante (módulo) de la división de los argumentos) y residuos de división conseguimos saber qué letras son las que van al final de la secuencia, por lo que cualquier número no vale. Digamos que casa una operación aritmética con las dos ´letras (posiciones 19 y 20 de la secuencia).
  4. Tuve que añadir una función (Math.fmod()) para que lo calculara.

Si después de todos estos condicionantes el CUPS es correcto devuelve un true como status que es lo que se devuelve en la última linea de la función. De lo contrario muestra mensaje y false en status.

Espero que os sirva.

Entradas relacionadas

5 comentarios

  • Hola Manel,
    He llegado a tu página buscando un validador para el CUPS por javascript, y te agradezco mucho el esfuerzo 😉
    Pero he encontrado un error en la línea 11 de tu script, ya que estás usando una función de C (fmod) que hace que falle en javascript. Es tan sencillo como aplicar el operador módulo (%) entre los valores.
    Por si te interesa, la he adaptado un poco según la Wikipedia: https://es.wikipedia.org/wiki/C%C3%B3digo_Universal_de_Punto_de_Suministro ; he modificado la expresión regular y añadido algunas cosillas.

    Te la dejo aquí puesta:

    function valida_cups(CUPS){

    var RegExPattern =/^[a-zA-Z]{2}[0-9]{16}[a-zA-Z]{2}([0-9][A-Za-z])?$/;

    if (CUPS.length>22) {
    return {success: false, code: 1, msg:’Demasiado largo’ }; //Demasiado largo
    }

    if (CUPS.length<20) {
    return {success: false, code: 2, msg:'Demasiado corto' }; //Demasiado corto
    }

    if (!CUPS.match(RegExPattern)) {
    return {success: false, code: 3, msg:'Estructura no válida' }; //Estructura no válida
    }

    var CUPS_16 = parseInt(CUPS.substr(2,16));
    var control = CUPS.substr(18,2).toUpperCase();
    var letters = Array('T','R','W','A','G','M','Y','F','P','D','X','B','N','J','Z','S','Q','V','H','L','C','K','E');

    var R0 = CUPS_16 % 529;
    var cont_C = Math.floor(R0/23);
    var cont_R = R0 % 23;

    var dc1 = letters[cont_C];
    var dc2 = letters[cont_R];
    var status = (control === dc1+dc2);

    if(!status){
    return {success: false, code: 4, msg:'Dígitos de control no válidos, se esperaba '+dc1+dc2 }; //Los dígitos de control no son válidos
    }

    return {success: true};
    }

    $(function() {
    $('#cups').on('keyup', function(e) {
    if (!$(this).is(':invalid') && $(this).val()!='') {

    var res = valida_cups($(this).val());

    if (!res.success) {
    alert(res.msg);
    }
    }
    });
    });

  • Manel García

    Gracias David, solamente un detalle que a lo mejor no viste en mis script es que, como bien dices, la fmod (C) la puse en javascript en la primera linea de todas
    Math.fmod = function (a,b) { return Number((a – (Math.floor(a / b) * b)).toPrecision(8)); };
    quizás no la viste y evidentemente te dio problemas en la linea 11!
    En lo que se refiere a la expresión regular, muchas gracias, la probaré.
    MKe alegra que te pueda haber servido la función, era mi itención que la gente no pasara por este problema cuando alguien lo tiene solucionado.
    Un saludo

  • Muchas gracias Manel, tu código me ha ido perfecto para poder validar el CUPS en mi web. Yo hago la validación directamente en código PHP, pero a partir de tu código ha sido muy fácil hacer la conversión de JavaScript a PHP. Un cordial saludo y gracias.

  • Hola no se si sera tarde el comentario, por la fecha, pero me interesa esa funcion para un campo de formulario de una base de datos en access 2007 donde introduzco los cups de suministros que necesitos ir registrando.
    Ante todo enhorabuena y gracias por vuestro aporte, un saludo.

  • León Domingo

    Gracias por el trabajo.
    Me he creado una versión en forma de función pura con algunos ajustes y correcciones sobre la versión inicial.

    https://gist.github.com/leon-domingo/631a98a13afe6e6163422fa85d52e9c9

Deja un comentario

Deja una respuesta

Tu dirección de correo electrónico no será publicada.




Top