Estoy teniendo un problema con la facturación, que me sucede generalmente cuando tengo que efectuar Percepciones de Ingresos Brutos. Trabajo en Visual FoxPro, en este momento estoy utilizando una versión 7.0 en este cliente, que tiene la versión vieja de mi sistema.
Me da el error 10029, que la suma de los importes en Tributo debe ser igual al valor ingresado en ImpTrib.
Ahora, yo chequeo y los montos COINCIDEN. Entonces, no sé por dónde puede estar viniendo este error. Busqué temas similares, pero los únicos dos que aludían a este error tenían que ver con otras cosas, con los importes no pasados como cadena o con un parámetro extra pasado a Python, por eso elegí crear un nuevo debate a ver si me pueden ayudar.
Les cuento como trabajo. Como me he topado anteriormente con problemas en lo que hacía a pasar "variables" hacia Python, opté directamente por generar un PRG cada vez que solicito un CAE. Tengo un programa generador que procesa esas variables, y genera a bajo nivel el código fuente con todo pasado directamente como valores, y no como variables, salvo en los casos en que tengo la variable declarada como pública y contiene un texto (como gcCUIT, que contiene el CUIT de la empresa que factura, es una variable pública de tipo string).
Incluyo el código fuente que me tira dicho error.
*- Programa generador de CAE.
WAIT WINDOW "Obteniendo CAE..." NOWAIT
SET POINT TO .
PUBLIC glErrorCAE
lcError = ON("Error")
gcCAEVenc = ""
ON ERROR DO errhand1;
*-- Crear objeto interface Web Service Autenticación y Autorización)
WAIT WINDOW "Creando el objeto Web Service..." NOWAIT
WSAA = CREATEOBJECT("WSAA")
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
*-- Generar un Ticket de Requerimiento de Acceso (TRA)
WAIT WINDOW "Generando el Ticket de Requerimiento de Acceso..." NOWAIT
tra = WSAA.CreateTRA()
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
ruta = gcDirPrograma
*-- Generar el mensaje firmado (CMS)
WAIT WINDOW "Generando el mensaje firmado..." NOWAIT
cms = WSAA.SignTRA(tra, ruta + "Amelia_22069e2478af7ffc.crt", ruta + "PRIVADA.KEY")
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
*-- Llamar al web service para autenticar
WAIT WINDOW "Llamando al Web Service para autenticar..." NOWAIT
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
ON ERROR DO errhand2;
*-- Crear objeto interface Web Service de Factura Electrónica
WAIT WINDOW "Creando el objeto de interface para la Factura Electrónica..." NOWAIT
WSFE = CREATEOBJECT("WSFEv1")
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
WAIT WINDOW WSFE.Version + CHR(13) + WSFE.InstallDir NOWAIT
*-- Setear tocken y sing de autorización (pasos previos)
WSFE.Token = WSAA.Token
WSFE.Sign = WSAA.Sign
* CUIT del emisor (debe estar registrado en la AFIP)
WSFE.Cuit = ALLTRIM(CHRTRAN(gcCUIT,"-",""))
*-- Conectar al Servicio Web de Facturación
*-- Producción usar:
WAIT WINDOW "Conectando al servicio Web de Facturación..." NOWAIT
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
WAIT WINDOW WSFE.DebugLog() NOWAIT
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
*-- Llamo a un servicio nulo, para obtener el estado del servidor (opcional)
WAIT WINDOW "Obteniendo el estado del servidor..." NOWAIT
WSFE.Dummy()
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
WAIT WINDOW "APPServer Status " + WSFE.AppServerStatus NOWAIT
WAIT WINDOW "DBServer Status " + WSFE.DbServerStatus NOWAIT
WAIT WINDOW "AuthServer Status " + WSFE.AuthServerStatus NOWAIT
*-- Recupero último número de comprobante para un punto de venta y tipo (opcional)
tipo_cbte = 1
punto_vta = 2
WAIT WINDOW "Obteniendo el último número de comprobante..." NOWAIT
LastCBTE = WSFE.CompUltimoAutorizado(tipo_cbte, punto_vta)
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
Fecha = DTOS(DATE())
WAIT WINDOW "Fecha de facturación: " + Fecha + "..." NOWAIT
*-- Establezco los valores de la factura o lote a autorizar:
concepto = 2
presta_serv = 1
tipo_doc = 80
nro_doc = "30509305206"
cbt_desde = INT(VAL(LastCbte)) + 1
cbt_hasta = INT(VAL(LastCbte)) + 1
imp_total = "57114.49"
imp_tot_conc = "0.00"
imp_neto = "47143.62"
imp_iva = "9900.15"
imp_trib = "70.72"
impto_liq_rni = "0.00"
imp_op_ex = "0.00"
fecha_cbte = Fecha
fecha_venc_pago = IIF(EMPTY("20150919"),Fecha,"20150919")
fecha_serv_desde = "20150729"
fecha_serv_hasta = "20150729"
moneda_id = "PES"
moneda_ctz = "1.000"
*-- Llamo al WebService de Autorización para obtener el CAE
ok = WSFE.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, ;
cbt_desde, cbt_hasta, imp_total, imp_tot_conc, imp_neto, ;
imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, ;
fecha_serv_desde, fecha_serv_hasta, ;
moneda_id, moneda_ctz)
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
IF ROUND(70.72,2) # 0
*-- Agrego Percepción
II.BB.
id = 99
desc = "Percepción
II.BB. Bs. As."
base_imp = "47143.62"
alic = "0.15"
importe = "70.72"
ok = WSFE.AgregarTributo(id, desc, base_imp, alic, importe)
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
ENDIF
*-- Agrego tasas de IVA
id = 5
base_imp = "47143.62"
imp_iva = "9900.15"
ok = WSFE.AgregarIva(id, base_imp, imp_iva)
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
**-- Solicito CAE:
cae = WSFE.CAESolicitar()
IF glErrorCAE
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
ENDIF
IF ISNULL(cae) OR EMPTY(cae)
lcRespuesta = WSFE.XMLResponse
lcRespuesta = SUBSTR(lcRespuesta,AT("<Obs>",lcRespuesta)+5)
lcRespuesta = SUBSTR(lcRespuesta,1,AT("</Obs>",lcRespuesta)-1)
lcCodigo = SUBSTR(lcRespuesta,AT("<Code>",lcRespuesta)+6)
lcCodigo = SUBSTR(lcCodigo,1,AT("</Code>",lcCodigo)-1)
lcMensaje = SUBSTR(lcRespuesta,AT("<Msg>",lcRespuesta)+5)
lcMensaje = SUBSTR(lcMensaje,1,AT("</Msg>",lcMensaje)-1)
DO FORM (gcFormAcepto) WITH ;
"CAE Rechazado." + CHR(13) + CHR(13) + ;
"Código: " + lcCodigo + CHR(13) + ;
"Mensaje: " + lcMensaje ,48,"¡¡¡CAE RECHAZADO!!!"
ELSE
DO FORM (gcFormAcepto) WITH ;
"Último Comprobante: " + LastCBTE + CHR(13) + ;
"CAE: " + IIF(ISNULL(cae),"",cae) + CHR(13) + ;
"Vencimiento: " + SUBSTR(WSFE.Vencimiento,7,2) + "/" ;
+ SUBSTR(WSFE.Vencimiento,5,2) + "/" ;
+ SUBSTR(WSFE.Vencimiento,1,4) + CHR(13) + ;
"Resultado: " + WSFE.Resultado + CHR(13) + ;
"Motivo de rechazo o advertencia: " + WSFE.Obs,48, ;
IIF(WSFE.Resultado = "A","CAE obtenido exitosamente." + ;
"¡¡¡CAE RECHAZADO!!!")
ENDIF
gcCAEVenc = cae + WSFE.Vencimiento
RELEASE glErrorCAE
ON ERROR &lcError
SET POINT TO .
RETURN gcCAEVenc
*-- Procedimiento para manejar errores WSAA
PROCEDURE errhand1
DO FORM (gcFormAcepto) WITH WSAA.Excepcion + CHR(13) + WSAA.Traceback,48,"VERIFIQUE LO SIGUIENTE"
*-- trato de extraer el código de error de afip (1000)
if afiperr>1000 and afiperr < 2000 then
? "codigo error afip:",afiperr
else
afiperr = 0
endif
*-- Preguntar: Aceptar o cancelar?
ch = MESSAGEBOX(WSAA.Excepcion, 5 + 48, "Error:")
IF ch = 2
RETURN
ENDIF
ENDPROC
*-- Procedimiento para manejar errores WSFE
PROCEDURE errhand2
=MESSAGEBOX(WSFE.Excepcion + CHR(13) + WSFE.Traceback)
*-- Preguntar: Aceptar o cancelar?
ch = MESSAGEBOX(WSFE.Excepcion, 5 + 48, "Error")
IF ch = 2
RETURN
ENDIF
ENDPROC