Función para comprobar CIF español.

Función para comprobar CIF español.

Postby FiveWiDi » Sat Nov 09, 2024 2:37 pm

Hola todos,

Alguien tiene alguna función que compruebe/valide el CIF español?
(El NIF de personas jurídicas, empresas...)

Muchas gracias,
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1183
Joined: Mon Oct 10, 2005 2:38 pm

Re: Función para comprobar CIF español.

Postby paquitohm » Tue Nov 12, 2024 10:42 am

Ahí va !

Validacion de NIF, CIF y NIE nacional
Cuando se hizo, Junio 2023, comprobaba todos los tipos de CIFS y letras en NIF/ NIE existentes

Todos los méritos para Juan Pastor, el creador de las funciones.
apenas hice yo (Paquito) el testeo y unas leves modificaciones



Code: Select all  Expand view
///////////////////////////////
// ValidacionNif.prg
//
//
// Validacion de NIF, CIF y NIE nacional
// Cuando se hizo, Junio 2023, comprobaba todos los tipos de CIF y letras en NIF/ NIE existentes
//
// Todos los méritos para Juan Pastor, el creador de las funciones.
// Apenas hice yo (Paquito) el testeo y unas leves modificaciones
/////////////////////////////////////////////////////////////////////////////////////////////

#Define CRLF Chr(13)+ Chr(10)

#define regex_CIF '^(?>[NPQRSW]{1}\d{7}[A-J]{1})$|^(?>[ABEH]{1}\d{7}\d{1})$|^(?>[CDFGJUV]{1}\d{7}[A-J0-9]{1})$|^(?>[ABCDEFGHJNPQRSUVW]{1}00\d{5}[A-J]{1})$'
#define regex_NIE '^([XYZ])(\d{7,8})([A-Z])$'
#define regex_DNI '^(\d{8})([A-Z])$'
// 08/06/23
// Esta es la funcion PRINCIPAL que comprueba y es la que se exporta para ser usada desde fuera
// Esta funcion lo comprueba todo: NIF, CIF y NIE
// Se requiere que cCode sea Nacional, para lo cual la nacion ha de ser comprobada
// antes de entrar o lo que sea para garantizar que el parametro se corresponde con un
// NIF, CIF o NIE nacional.
//
function NIFCheck_JuanPastor( cCode )

    Local lRet := .F.


    cCode := ( hb_StrReplace( cCode, " .-/\,_" ) )             // 08/06/23

    Do Case
       Case hb_RegExLike( regex_DNI, cCode )    // DNI - NIF
           lRet := DNICheck( cCode )

       Case hb_RegExLike( regex_NIE, cCode )    // NIE
           lRet := DNICheck( cCode )

       Case hb_RegExLike( regex_CIF, cCode )    // CIF
           lRet := CIFCheck( cCode )
    End Case

return lRet        // 19/06/23


/* FUNCION: CIFCheck( cCode )
   Comprueba si una CIF es correcto

   Parámetros:
       cCode  - CIF

   Devuelve:
       Logical
*/

STATIC Function CIFCheck(cCode)

    Local lRet := .F.
    Local cDigit


    // Comprueba si formato CIF es correcto
    If !hb_RegExLike( regex_CIF, cCode )
        return lRet
    endif


    // Empieze por: PQRSW -> Letra  // HJUV -> Digito // Resto -> Indiferente // Si empieza por 00 -> Letra
    cDigit := CIFDigit( cCode )

    if ( Left( cCode, 1 ) $ "PQRSWABEH" ) .or. SubStr( cCode, 2, 2 ) == '00' // Obligatoriamente es Letra o Dígito
        lRet := Right( cCode, 1 ) ==  cDigit
    else // // Puede ser Letra o Dígito indistintamente
        lRet :=  cDigit != NIL .AND.;
                 ( Right( cCode, 1) == cDigit .or. Right( cCode, 1) ==  Chr(Val(IIF(cDigit == '0','10',cDigit) ) + 64) )

    endif

return lRet


/* FUNCION: CIFDigit( cCode )
    Calcula los dígitos de control de un CIF

    Parámetros:
        cCode  - Código CIF

    Devuelve:
        Character o NIL si no cumple formato    */

STATIC Function CIFDigit( cCode )

    Local nCheckSum := 0
    Local nImpar := 0
    Local n := 0
    Local cRet := 0
    Local cNewCode

//    cNewCode := Upper( hb_StrReplace( cCode, " .-/\,_" ) )
    cNewCode := ( hb_StrReplace( cCode, " .-/\,_" ) )    // Al 08/06/23
    cNewCode := SubStr( cCode, 2, Len( cCode ) - 2 )     // Parte numérica

    // Comprueba si formato CIF es correcto

    If !hb_RegExLike( regex_CIF, cCode )
        return NIL
    endif

    for n := 1 TO Len ( cNewCode )
        if n % 2 == 0
            nCheckSum += Val( SubStr( cNewCode, n, 1 ) )

        else
            nImpar := Val( SubStr( cNewCode, n, 1 ) ) * 2
            nCheckSum +=  Int( nImpar / 10 ) + ( nImpar % 10 )
        endif
    next

    if ( Left( cCode, 1 ) $ "NPQRSW" ) .or. SubStr( cCode, 2, 2 ) == '00'
        cRet := Chr( 10 - ( nCheckSum % 10 ) + 64 ) // Devuelve Letra
    else
        cRet :=  Str( ( 10 - ( nCheckSum % 10 ) ) % 10, 1) // Devuelve Dígito

    endif

return cRet

/* FUNCION: DNICheck( cCode )
    Comprueba un DNI / NIF / NIE e Correcto

    Devuelve:
        Logical
*/

STATIC function DNICheck( cDNI )
return DNILetter( cDNI ) == Right( cDNI, 1 )


/* FUNCION: DNILetter( cCode )
    Calcula el caracter de control de un DNI / NIF Fisico / NIE

    Devuelve:
        Character o NIL si no cumple formato
*/

STATIC function DNILetter( cDNI )

    Local cClv := "TRWAGMYFPDXBNJZSQVHLCKE"
//cDNI := Upper( hb_StrReplace( cDNI , " .-/\,_" ) )
cDNI := ( hb_StrReplace( cDNI , " .-/\,_" ) )            // Al 08/06/23

    If hb_RegExLike( regex_NIE, cDNI ) // Si es NIE
        cDNI := Str( Asc( Left( cDNI, 1 ) ) - 88, 1 ) + SubStr( cDNI, 2 )
    endif

    If !hb_RegExLike( regex_DNI, cDNI )
        return NIL
    endif
    cDNI := Left( cDNI, Len( cDNI ) - 1 )

return SubStr( cClv, mod( Val( cDNI ), 23 ) + 1, 1 )



STATIC function CheckType( cCode )

    Local cRet := ''

//    cCode := Upper( hb_StrReplace( cCode, " .-/\,_" ) )
    cCode := ( hb_StrReplace( cCode, " .-/\,_" ) )             // Al 08/06/23


    Do Case
    Case hb_RegExLike( regex_DNI, cCode )   // DNI - NIF
        cRet := "DNI/NIF Fisico"

    Case hb_RegExLike( regex_NIE, cCode )   // NIE
        cRet := "NIE"

    Case hb_RegExLike( regex_CIF, cCode )   // CIF
        cRet := "NIF/CIF Juridico"


    End Case

return cRet
 
Last edited by paquitohm on Tue Nov 12, 2024 11:44 am, edited 1 time in total.
paquitohm
 
Posts: 262
Joined: Fri Jan 14, 2022 8:37 am

Re: Función para comprobar CIF español.

Postby FiveWiDi » Tue Nov 12, 2024 11:25 am

paquitohm wrote:Ahí va !

Validacion de NIF, CIF y NIE nacional
Cuando se hizo, Junio 2023, comprobaba todos los tipos de CIFS y letras en NIF/ NIE existentes

Todos los méritos para Juan Pastor, el creador de las funciones.
apenas hice yo (Paquito) el testeo y unas leves modificaciones


Las variables tipo 'regex_DNI' ... Que valores tienen? De dónde salen?

Falta algún fichero .CH ?

Muchas Paquito.
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1183
Joined: Mon Oct 10, 2005 2:38 pm

Re: Función para comprobar CIF español.

Postby paquitohm » Tue Nov 12, 2024 11:45 am

FiveWiDi wrote:
paquitohm wrote:Ahí va !

Validacion de NIF, CIF y NIE nacional
Cuando se hizo, Junio 2023, comprobaba todos los tipos de CIFS y letras en NIF/ NIE existentes

Todos los méritos para Juan Pastor, el creador de las funciones.
apenas hice yo (Paquito) el testeo y unas leves modificaciones


Las variables tipo 'regex_DNI' ... Que valores tienen? De dónde salen?

Falta algún fichero .CH ?

Muchas Paquito.



He modificado el fuente y he puesto las constantes faltantes al principio
paquitohm
 
Posts: 262
Joined: Fri Jan 14, 2022 8:37 am

Re: Función para comprobar CIF español.

Postby FiveWiDi » Tue Nov 12, 2024 12:35 pm

paquitohm wrote:He modificado el fuente y he puesto las constantes faltantes al principio


Perfecto, luego lo pruebo.

Muchas gracias Paquito.
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1183
Joined: Mon Oct 10, 2005 2:38 pm

Re: Función para comprobar CIF español.

Postby FiveWiDi » Tue Nov 12, 2024 1:47 pm

Hola Paquito,

Como que yo preciso poder dejar el NIF/CIF en blanco, he modificado la función así para que sea compatible con el uso actual:

Code: Select all  Expand view
function NIFCheck_JuanPastor( cCode, lEmpty )

    Local lRet := .F.

    If lEmpty == Nil   // 12/11/2024
        lEmpty := .F.
    EndIf

    cCode := ( hb_StrReplace( cCode, " .-/\,_" ) )             // 08/06/23

    Do Case
       Case hb_RegExLike( regex_DNI, cCode )    // DNI - NIF
           lRet := DNICheck( cCode )

       Case hb_RegExLike( regex_NIE, cCode )    // NIE
           lRet := DNICheck( cCode )

       Case hb_RegExLike( regex_CIF, cCode )    // CIF
           lRet := CIFCheck( cCode )
    End Case

    If( lEmpty .and. Empty(cCode), lRet := .T., Nil )     // 12/11/2024

return lRet        // 19/06/23
 


Con las primeras pruebas me va perfecto, lástima que el CIF de Amazon ( LU.....) no se lo coma. ;)
Ya he leído que deben ser códigos españoles,

Muchas gracias de nuevo.
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1183
Joined: Mon Oct 10, 2005 2:38 pm

Re: Función para comprobar CIF español.

Postby paquitohm » Tue Nov 12, 2024 3:35 pm

FiveWiDi wrote:Hola Paquito,

Como que yo preciso poder dejar el NIF/CIF en blanco, he modificado la función así para que sea compatible con el uso actual:

Code: Select all  Expand view
function NIFCheck_JuanPastor( cCode, lEmpty )

    Local lRet := .F.

    If lEmpty == Nil   // 12/11/2024
        lEmpty := .F.
    EndIf

    cCode := ( hb_StrReplace( cCode, " .-/\,_" ) )             // 08/06/23

    Do Case
       Case hb_RegExLike( regex_DNI, cCode )    // DNI - NIF
           lRet := DNICheck( cCode )

       Case hb_RegExLike( regex_NIE, cCode )    // NIE
           lRet := DNICheck( cCode )

       Case hb_RegExLike( regex_CIF, cCode )    // CIF
           lRet := CIFCheck( cCode )
    End Case

    If( lEmpty .and. Empty(cCode), lRet := .T., Nil )     // 12/11/2024

return lRet        // 19/06/23
 


Con las primeras pruebas me va perfecto, lástima que el CIF de Amazon ( LU.....) no se lo coma. ;)
Ya he leído que deben ser códigos españoles,

Muchas gracias de nuevo.


FiveWidi,

Dos cosas:

1. Cuando estuve testeando la funcion de Juan Pastor lo que hice fue pasarsela a todos los clientes y proveedor de alguno de mis clientes. Para ello puse en el programa una comprobacion y salieron nifs que estaban mal... La rutina de Juan funciono a la perfeccion.

2. Para validar Amazon y cualquier operador INTRACOMUNITARIO te dejo aqui una validacion que hice para VIES. :D
El resto de extranjeros son incomprobables 8)


Code: Select all  Expand view
//////////////////////////
// Vies.prg
//
// Clase para comprobar un codigo VIES (Operador Intracomunitario)
//
// Autor: Paquito
/////////////////////////////////////////////////////////////////////////////


//-------------------------------------------------------------------------//
FUNCTION PruebaTCheckVies()
Local oCheck
Local a
Local c, nItem, lOk
Local cCountry, cVatNumber
Local cFile
*
a:= {;
      "PT249774194",;
      "ESA28017895",;
      "PT212629514",;
      "PT122965795",;
      "PT509064329",;
      "PT233221638",;
      "PT132291037",;
      "PT513376810",;
      "PT201580314",;
      "ESA28017895",;
      "PT514652110" ;
    }
*
oCheck:= TCheckVies():New()
IF !oCheck:lActivate()
   RETURN NIL
ENDIF
*
c:= ""
FOR nItem:= 1 TO Len(a)
   cCountry  := Left(  a[nItem], 2)
   cVatNumber:= SubStr(a[nItem], 3)
   *
   lOk:= oCheck:lCheck(cCountry, cVatNumber)
   c+= "CHECANDO "+ cCountry+ "/"+ cVatNumber+;
       " ("+ If(lOk, "Si correcto", "No correcto")+ ")"+;
       CRLF
NEXT
oCheck:End()
*
cFile:= "Tmp\CHECK_VIES_"+ DateStrZeroSeconds()+ ".txt"
hb_MemoWrit(cFile, c)
run ("Notepad "+ cFile)
*
RETURN NIL
*



//-------------------------------------------------------------------------//
CLASS TCheckVies

   METHOD New()
   METHOD lActivate()
   METHOD lCheck()
   METHOD End()

   DATA oDoc
   DATA oHttp
   DATA cUrl

ENDCLASS

//-------------------------------------------------------------------------//
METHOD New()

::cUrl:= "https://ec.europa.eu/taxation_customs/vies/rest-api/ms/%COUNTRY%/vat/%VATNUMBER%"

RETURN Self

//-------------------------------------------------------------------------//
METHOD lActivate()
*
   Local lOk:= .t.
   Local oTry
   *
   xTRY INI TO oTry
      ::oDoc := CreateObject( "MSXML2.DOMDocument" )
      ::oHttp:= CreateObject( "MSXML2.XMLHTTP"     )
   xTRY END
   *
   IF oTry:lError
      lOk:= .f.
      oTry:SaveError()
   ENDIF
*
RETURN lOk
*
*
//-------------------------------------------------------------------------//
METHOD lCheck(cCountry, cVatNumber, cCountryYVatNumber)

   local odoc  := ::oDoc
   local ohttp := ::oHttp
   local cResponseText
   Local cUrl  := ::cUrl
   Local hHash
   Local lOk


   IF cCountryYVatNumber != NIL
      cCountry  := Left(  cCountryYVatNumber, 2)
      cVatNumber:= Substr(cCountryYVatNumber, 3)
   ENDIF

/////////////////////////////////////   cUrl:= "https://ec.europa.eu/taxation_customs/vies/rest-api/ms/%COUNTRY%/vat/%VATNUMBER%"
   cUrl:= StrTran(cUrl, "%COUNTRY%"  , cCountry  )
   cUrl:= StrTran(cUrl, "%VATNUMBER%", cVatNumber)

   ohttp:Open( "GET" , cUrl, .F. )
      oHttp:SetRequestHeader( "Content-Type"    , "application/x-www-form-urlencoded" )
      oHttp:setRequestHeader('User-Agent', 'node-soap')
      oHttp:setRequestHeader('Accept' , 'text/html,application/xhtml+xml,application/xml,text/xml;q=0.9,*/*;q=0.8')
      oHttp:setRequestHeader('Accept-Encoding', 'none')
      oHttp:setRequestHeader('Accept-Charset', 'utf-8')

      oDoc:async := .f.
      oDoc:LoadXml('<?xml version=""1.0"" encoding=""utf-8""?>')
   ohttp:Send(oDoc:xml)

   cResponseText:= alltrim(ohttp:responseText)

   #Define lES_JSON             cLeft(cResponseText, "{")
   #Define cDATA_               "isValid"
   #Define lJSON_ESTRUCTURA_OK ( lES_JSON .AND. At("isValid", cResponseText) > 0 )
   lOk:= !Empty(cResponseText) .AND. lJSON_ESTRUCTURA_OK
   IF lOk
      hb_jsonDecode(cResponseText, @hHash)
      lOk:= Valtype(hHash) == "H" .AND. hb_hPos(hHash, cDATA_) > 0
      IF lOk
         lOk:= hHash[cDATA_]  // True / False
      ELSE
         FLOGMSG_("Error !! No es hash o no es de la estructura o data isValid no encontrado !!", cResponseText, cDATA_, Valtype(hHash))
      ENDIF
   ELSE
      FLOGMSG_("Error !! Respuesta vacia o invalida !!", cResponseText)
   ENDIF

RETURN lOk

//-------------------------------------------------------------------------//
METHOD End()
   ::oDoc := NIL
   ::oHttp:= NIL
RETURN NIL

 
paquitohm
 
Posts: 262
Joined: Fri Jan 14, 2022 8:37 am

Re: Función para comprobar CIF español.

Postby FiveWiDi » Tue Nov 12, 2024 11:25 pm

El otro día estuve viendo como un usuario daba de alta una empresa en un software de contabilidad, y me dio a entender que ese software utilizaba algo como lo que has detallado, informaba del CIF y el software le respondía con los campos de dirección postal rellenados, facilitando la tarea y evitando errores.

Lo tendré en cuenta.

Muchas gracias
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1183
Joined: Mon Oct 10, 2005 2:38 pm

Re: Función para comprobar CIF español.

Postby FiveWiDi » Tue Nov 12, 2024 11:25 pm

El otro día estuve viendo como un usuario daba de alta una empresa en un software de contabilidad, y me dio a entender que ese software utilizaba algo como lo que has detallado, informaba del CIF y el software le respondía con los campos de dirección postal rellenados, facilitando la tarea y evitando errores.

Lo tendré en cuenta.

Muchas gracias
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1183
Joined: Mon Oct 10, 2005 2:38 pm


Return to Off Topic / Otros temas

Who is online

Users browsing this forum: No registered users and 6 guests