Validar CUIT / CUIL

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

Post Reply
User avatar
Claudio Ricardo
Posts: 367
Joined: Tue Oct 27, 2020 3:38 am
DBs Used: DBF, MySQL, MariaDB
Location: Bs. As. - Argentina

Validar CUIT / CUIL

Post by Claudio Ricardo »

Hola a todos !!! Hello to all !!!
Al verme obligado a trabajar sobre impresora fiscal encontré un problema si el usuario ingresa un número de CUIT / CUIL no válido...
Creo haberlo solucionado con esto y lo comparto para revisión/mejora, espero sirva de ayuda a quién le pase lo mismo que a mi...
When I was forced to work on a fiscal printer, I found a problem if the user enters an invalid CUIT / CUIL number...
I think I've solved it with this and I'm sharing it for review/improvement, I hope it helps someone who is going through the same thing as me...

En la función de guardar cliente nuevo:
In the save new client function:

Code: Select all

LOCAL cCUIT := AllTrim ( GetProperty ("Clientes_Nuevo" , "Text_CUIT" , "Value"))
......

	If ! Empty (cCUIT)								// Validar numero de CUIT
	
		If ! ValidateCuit (cCUIT)
		
			MsgStop ("CUIL / CUIT No válido !" , "Error !")
		
			Return Nil
		
		EndIf
		
	EndIf
Función de validación:
Validate function:

Code: Select all

//  Funcion ValidateCuit (cCUIT) Retorna .T. si el CUIT / CUIL es válido

Function ValidateCuit (cCUIT)

LOCAL nSub := 0
LOCAL nRes := 0
LOCAL cTipo := ""

	If HMG_Len (cCUIT) == 13							// Quito guiones si los tiene

		cCUIT := StrTran (cCUIT, "-", "")

	EndIf

	If HMG_Len (cCUIT) != 11							// Si no tiene 11 digitos es inválido
	
		Return .F.
		
	EndIf
	
	If ValType (cCUIT) == "C"							// Si es numerico lo convierto a character
	
		Hb_NtoS (cCUIT)
		
	EndIf
											// Si no comienza con 20, 23, 24, 27, 30, 33, 34
	cTipo := Hb_UsubStr (cCUIT, 1, 2)

	If cTipo == "20" .OR. cTipo == "23" .OR. cTipo == "24" .OR. cTipo == "27" .OR. cTipo == "30" .OR. cTipo == "33" .OR. cTipo == "34"

		nSub := Val ( Hb_UsubStr (cCUIT, 1, 1)) * 5				// Primer digito
		nSub += Val ( Hb_UsubStr (cCUIT, 2, 1)) * 4
		nSub += Val ( Hb_UsubStr (cCUIT, 3, 1)) * 3
		nSub += Val ( Hb_UsubStr (cCUIT, 4, 1)) * 2
		nSub += Val ( Hb_UsubStr (cCUIT, 5, 1)) * 7
		nSub += Val ( Hb_UsubStr (cCUIT, 6, 1)) * 6
		nSub += Val ( Hb_UsubStr (cCUIT, 7, 1)) * 5
		nSub += Val ( Hb_UsubStr (cCUIT, 8, 1)) * 4
		nSub += Val ( Hb_UsubStr (cCUIT, 9, 1)) * 3
		nSub += Val ( Hb_UsubStr (cCUIT, 10, 1)) * 2			// Ultimo digito antes del validador

		nRes := ( 11 - Mod (nSub, 11) )
		
		If nRes == 11
		
			nRes := 0
			
		ElseIf nRes == 10
		
			nRes := 9
			
		EndIf
		
	Else
	
		Return .F.
		
	EndIf

Return Iif ( nRes == Val ( Hb_UsubStr (cCUIT, 11, 1)), .T., .F.)
Corrige al sabio y lo harás más sabio, Corrige al necio y lo harás tu enemigo.
WhatsApp / Telegram: +54 911-63016162
User avatar
SerAlex08
Posts: 2
Joined: Wed Nov 24, 2021 1:40 pm
DBs Used: DBF
Location: Buenos Aires, Argentina

Re: Validar CUIT / CUIL

Post by SerAlex08 »

Hola Claudio. Te paso la rutina que implementé hace ya tiempo. En esencia es como la tuya:

Code: Select all

FUNCTION OkNroCUIT ( xParam1 )

LOCAL cParam2 := "", nParam3 := 0, cParam4 := "5432765432", nParam5 := 0, nParam6 := 0
   
   IF ( xParam1 = NIL ) .OR. ( VALTYPE(xParam1) != "C" ) .OR. ( ( VALTYPE(xParam1) = "C" ) .AND. ( LEN(ALLTRIM(xParam1)) != 13 ) )
      RETURN(.F.)
   ENDIF
   
   cParam2 := ( LEFT(xParam1, 2) + SUBSTR(xParam1, 4, 8) )
   
   FOR nParam6 := 1 TO 10
      nParam3 += ( VAL(SUBSTR(cParam2,nParam6, 1)) * VAL(SUBSTR(cParam4,nParam6, 1)) )
   NEXT
   
   nParam5 := ( nParam3 % 11 )
   
   IF nParam5 > 1
      nParam5 := ( 11 - nParam5 )
   ENDIF
   
   RETURN ( nParam5 = VAL(RIGHT(xParam1, 1)) )

Diferencias:
  • Ingreso siempre 13 caracteres numéricos (99-99999999-9).
  • Dejé de validar el prefijo (20,23,...) ya que con la Ley de Identidad de Género dejaron de tener vigencia.
Saludos.
Post Reply