modificaciones facturacion electronica

This commit is contained in:
Luis
2026-10-15 16:07:57 -04:00
parent 07649704b1
commit ba982b7635
158 changed files with 206301 additions and 27838 deletions
+215 -92
View File
@@ -5,10 +5,15 @@
Tabla Comprobantes Fiscales
PROGRAMADOR : Ing. Juan Soto.
FECHA REALIZACION : Diciembre 27, 2006
------------------------------------------------------------------
2026-10-09: la llave de un comprobante es tipo_doc + codigo_dgii + sucid
(la misma que usa la factura veprmt001). Nuevo no deja duplicar,
Modificar/Eliminar solo tocan ese registro y se guardan
itbis, disponible y fecha_vencimiento.
------------------------------------------------------------------
}
GLOBALS "veprgb000.4gl"
MAIN
DEFER INTERRUPT
CALL ARG_VAL(1) RETURNING usuarios
@@ -17,12 +22,12 @@ MAIN
CONNECT TO "decomarmol" AS "MSSQL" USER usuarios USING clave
# CONNECT to "smarmotech" AS "IFMX" USER usuarios USING clave
CALL veprmt020()
END MAIN
FUNCTION veprmt020()
CLEAR SCREEN
FUNCTION veprmt020()
CLEAR SCREEN
OPTIONS
FORM LINE 9,
ERROR LINE 23,
@@ -30,14 +35,14 @@ FUNCTION veprmt020()
OPEN FORM vefmmt020 FROM "vefmmt020"
DISPLAY FORM vefmmt020
MENU
ON ACTION nuevo
MENU
ON ACTION nuevo
CALL vepcad020()
ON ACTION modificar
CALL vepcmf020()
ON ACTION Salir
EXIT MENU
@@ -47,45 +52,87 @@ END FUNCTION
FUNCTION vepcad020()
DEFINE hoy DATE
DEFINE hoy DATE,
existe INTEGER,
vsec INTEGER,
vfec_vence DATE
## Captura los datos que va a contener el registro
# WHENEVER ERROR CONTINUE
LET hoy = today
INPUT BY NAME ncf.*
INITIALIZE ncf.* TO NULL
LET fecha_vencimiento = NULL
INPUT BY NAME ncf.*,fecha_vencimiento
BEFORE INPUT
CALL localidades('1')
AFTER INPUT
IF int_flag THEN
LET numero_msg = 2
LET numero_msg = 2
CALL msg(numero_msg)
LET int_flag = FALSE
RETURN
END IF
IF NOT valida_ncf() THEN
CONTINUE INPUT
END IF
{ SET CONNECTION "IFMX"
INSERT INTO vetb00071 (fecha,tipo_ncf,tipo_doc,ncf_inicial,ncf_final,
codigo_dgii,disponible,itbis,us_mod,fech_mod,sucid)
VALUES (ncf.fecha,ncf.tipo_ncf,ncf.tipo_doc,ncf.ncf_inicial,
ncf.ncf_final,ncf.codigo_dgii,ncf.disponible,
ncf.itbis,usuarios,GETDATE(),ncf.sucid)
}
SET CONNECTION "MSSQL"
# No deja registrar dos veces el mismo comprobante en la misma localidad
LET existe = 0
SELECT COUNT(*) INTO existe FROM vetb00071 a
WHERE a.tipo_doc = ncf.tipo_doc AND a.codigo_dgii = ncf.codigo_dgii
AND a.sucid = ncf.sucid
IF existe > 0 THEN
CALL fgl_winmessage("NCF DUPLICADO",
"Ese comprobante ya existe para esta localidad.\nUse Consultar/Modificar para cambiarle el rango.",
"stop")
CONTINUE INPUT
END IF
LET vfec_vence = fecha_vencimiento
INSERT INTO vetb00071 (fecha,tipo_ncf,tipo_doc,ncf_inicial,ncf_final,
codigo_dgii,disponible,itbis,us_mod,fech_mod,sucid)
codigo_dgii,disponible,itbis,fecha_vencimiento,
us_crea,fech_crea,sucid)
VALUES (ncf.fecha,ncf.tipo_ncf,ncf.tipo_doc,ncf.ncf_inicial,
ncf.ncf_final,ncf.codigo_dgii,ncf.disponible,
ncf.itbis,usuarios,getdate(),ncf.sucid)
ncf.itbis,vfec_vence,usuarios,getdate(),ncf.sucid)
# La factura solo hace UPDATE a vetb00073; si no existe el control de
# secuencia, la secuencia nunca avanza. Se crea en el inicial - 1.
LET existe = 0
SELECT COUNT(*) INTO existe FROM vetb00073 a
WHERE a.tipo_doc = ncf.tipo_doc AND a.codigo_dgii = ncf.codigo_dgii
IF existe = 0 THEN
LET vsec = ncf.ncf_inicial - 1
IF vsec IS NULL OR vsec < 0 THEN
LET vsec = 0
END IF
INSERT INTO vetb00073 (codigo_dgii,tipo_doc,ncf,sucid,us_crea,fech_crea)
VALUES (ncf.codigo_dgii,ncf.tipo_doc,vsec,ncf.sucid,usuarios,getdate())
END IF
LET numero_msg = 1
CALL msg(numero_msg)
END INPUT
END FUNCTION
FUNCTION vepcmf020()
END FUNCTION
FUNCTION vepcmf020()
DEFINE k_tipo_doc LIKE vetb00071.tipo_doc,
k_codigo_dgii LIKE vetb00071.codigo_dgii,
k_sucid LIKE vetb00071.sucid,
sec_ncf INTEGER,
usados INTEGER,
vfec_vence DATE
## Aqui se prepara para la captura del criterio de seleccion
#WHENEVER ERROR CONTINUE
#SET CONNECTION "IFMX"
@@ -95,67 +142,88 @@ FUNCTION vepcmf020()
BEFORE CONSTRUCT
CALL localidades('1')
AFTER CONSTRUCT
IF int_flag THEN
LET numero_msg = 2
CALL msg(numero_msg)
IF int_flag THEN
LET numero_msg = 2
CALL msg(numero_msg)
LET int_flag = FALSE
RETURN
END IF
END CONSTRUCT
LET SELEC = " SELECT CONVERT(CHAR(10),a.fecha,103),a.tipo_ncf,a.tipo_doc,a.codigo_dgii,a.ncf_inicial,",
" a.ncf_final,a.disponible,a.us_crea,a.fech_crea,a.us_mod,a.fech_mod,",
" a.sucid ",
" a.ncf_final,a.disponible,a.itbis,a.fecha_vencimiento,",
" a.us_crea,a.fech_crea,a.us_mod,a.fech_mod,a.sucid,",
" (SELECT MAX(b.ncf) FROM vetb00073 b",
" WHERE b.tipo_doc = a.tipo_doc AND b.codigo_dgii = a.codigo_dgii) ",
" FROM vetb00071 a ",
" WHERE ",
criterio clipped,
" ORDER BY a.sucid"
" ORDER BY a.sucid,a.tipo_doc,a.codigo_dgii"
PREPARE busca FROM selec
DECLARE datos SCROLL CURSOR WITH HOLD FOR busca
OPEN datos
DECLARE datos SCROLL CURSOR WITH HOLD FOR busca
OPEN datos
INITIALIZE ncf.* TO NULL
LET fecha_vencimiento = NULL
LET sec_ncf = NULL
FETCH FIRST datos INTO ncf.fecha,ncf.tipo_ncf,ncf.tipo_doc,ncf.codigo_dgii,ncf.ncf_inicial,ncf.ncf_final,
ncf.disponible,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid
DISPLAY BY NAME ncf.*
ncf.disponible,ncf.itbis,fecha_vencimiento,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid,sec_ncf
IF SQLCA.SQLCODE = NOTFOUND THEN
CALL fgl_winmessage("NCF","No se encontraron comprobantes con ese criterio.","info")
CLOSE datos
RETURN
END IF
CALL refresca_ncf() RETURNING sec_ncf
DISPLAY BY NAME sec_ncf
MENU "OPCIONES "
COMMAND "Siguiente"
"Presenta en pantalla el proximo registro encontrado"
FETCH NEXT datos INTO ncf.fecha,ncf.tipo_ncf,ncf.tipo_doc,ncf.codigo_dgii,ncf.ncf_inicial,ncf.ncf_final,
ncf.disponible,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid
DISPLAY "SUC ",ncf.sucid
ncf.disponible,ncf.itbis,fecha_vencimiento,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid,sec_ncf
DISPLAY BY NAME ncf.*
CALL refresca_ncf() RETURNING sec_ncf
DISPLAY BY NAME sec_ncf
COMMAND "Anterior"
"Presenta en pantalla el registro anterior encontrado"
FETCH PREVIOUS datos INTO ncf.fecha,ncf.tipo_ncf,ncf.tipo_doc,ncf.codigo_dgii,ncf.ncf_inicial,ncf.ncf_final,
ncf.disponible,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid
DISPLAY BY NAME ncf.*
ncf.disponible,ncf.itbis,fecha_vencimiento,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid,sec_ncf
CALL refresca_ncf() RETURNING sec_ncf
DISPLAY BY NAME sec_ncf
COMMAND "Primero"
"Presenta en pantalla el primer registro encontrado"
FETCH FIRST datos INTO ncf.fecha,ncf.tipo_ncf,ncf.tipo_doc,ncf.codigo_dgii,ncf.ncf_inicial,ncf.ncf_final,
ncf.disponible,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid
DISPLAY BY NAME ncf.*
ncf.disponible,ncf.itbis,fecha_vencimiento,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid,sec_ncf
CALL refresca_ncf() RETURNING sec_ncf
DISPLAY BY NAME sec_ncf
LET numero_msg = 5
CALL msg(numero_msg)
LET numero_msg = 5
CALL msg(numero_msg)
COMMAND "Ultimo"
"Presenta en pantalla el ultimo registro encontrado"
FETCH LAST datos INTO ncf.fecha,ncf.tipo_ncf,ncf.tipo_doc,ncf.codigo_dgii,ncf.ncf_inicial,ncf.ncf_final,
ncf.disponible,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid
DISPLAY BY NAME ncf.*
ncf.disponible,ncf.itbis,fecha_vencimiento,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod,ncf.sucid,sec_ncf
CALL refresca_ncf() RETURNING sec_ncf
DISPLAY BY NAME sec_ncf
LET numero_msg = 4
CALL msg(numero_msg)
LET numero_msg = 4
CALL msg(numero_msg)
COMMAND "Escoger"
"<Esc> Actualiza Registro <Delete> Cancela Operacion"
INPUT BY NAME ncf.* WITHOUT DEFAULTS
# La llave (tipo doc, codigo, localidad) no se edita aqui: asi el
# UPDATE toca solo este comprobante y no se crean duplicados
LET k_tipo_doc = ncf.tipo_doc
LET k_codigo_dgii = ncf.codigo_dgii
LET k_sucid = ncf.sucid
INPUT BY NAME ncf.fecha,ncf.tipo_ncf,ncf.itbis,ncf.ncf_inicial,
ncf.ncf_final,ncf.disponible,fecha_vencimiento WITHOUT DEFAULTS
AFTER INPUT
IF int_flag THEN
LET numero_msg = 2
@@ -163,23 +231,32 @@ DISPLAY "SUC ",ncf.sucid
LET int_flag = FALSE
EXIT MENU
END IF
EXIT INPUT
IF NOT valida_ncf() THEN
NEXT FIELD ncf_final
END IF
IF sec_ncf IS NOT NULL AND ncf.ncf_final < sec_ncf THEN
CALL fgl_winmessage("NCF",
"El NCF final no puede ser menor que la ultima secuencia usada ("||sec_ncf||").",
"stop")
NEXT FIELD ncf_final
END IF
EXIT INPUT
END INPUT
{ SET CONNECTION "IFMX"
SELECT UNIQUE a.sucid FROM vetb00071 a
WHERE a.sucid = ncf.sucid AND
a.fecha = ncf.fecha AND
a.tipo_doc = ncf.tipo_doc AND a.codigo_dgii=ncf.codigo_dgii
IF STATUS <> NOTFOUND THEN
DISPLAY "aqui"
UPDATE vetb00071 SET
UPDATE vetb00071 SET
tipo_doc = ncf.tipo_doc,
tipo_ncf = ncf.tipo_ncf,
tipo_ncf = ncf.tipo_ncf,
ncf_inicial = ncf.ncf_inicial,
ncf_final = ncf.ncf_final,
itbis = ncf.itbis,
us_mod = USUARIOS,
us_mod = USUARIOS,
fech_mod = GETDATE()
WHERE fecha = ncf.fecha AND
sucid = ncf.sucid AND
@@ -190,56 +267,102 @@ DISPLAY "SUC ",ncf.sucid
VALUES (ncf.fecha,ncf.tipo_ncf,ncf.tipo_doc,ncf.ncf_inicial,
ncf.ncf_final,ncf.codigo_dgii,ncf.disponible,
ncf.itbis,usuarios,GETDATE(),ncf.sucid)
END IF}
SET CONNECTION "MSSQL"
SELECT UNIQUE a.sucid FROM vetb00071 a
WHERE a.sucid = ncf.sucid AND
a.fecha = ncf.fecha AND
a.tipo_doc = ncf.tipo_doc AND a.codigo_dgii=ncf.codigo_dgii
IF STATUS <> NOTFOUND THEN
UPDATE vetb00071 SET
tipo_ncf = ncf.tipo_ncf,
ncf_inicial = ncf.ncf_inicial,
ncf_final = ncf.ncf_final,
itbis = ncf.itbis,
us_mod = USUARIOS,
fech_mod = GETDATE()
WHERE fecha = ncf.fecha AND
sucid = ncf.sucid AND
tipo_doc = ncf.tipo_doc
ELSE
INSERT INTO vetb00071 (fecha,tipo_ncf,tipo_doc,ncf_inicial,ncf_final,
codigo_dgii,disponible,itbis,us_mod,fech_mod,sucid)
VALUES (ncf.fecha,ncf.tipo_ncf,ncf.tipo_doc,ncf.ncf_inicial,
ncf.ncf_final,ncf.codigo_dgii,ncf.disponible,
ncf.itbis,usuarios,getdate(),ncf.sucid)
END IF
LET numero_msg = 13
CALL msg(numero_msg)
SET CONNECTION "MSSQL"
LET vfec_vence = fecha_vencimiento
UPDATE vetb00071 SET
fecha = ncf.fecha,
tipo_ncf = ncf.tipo_ncf,
ncf_inicial = ncf.ncf_inicial,
ncf_final = ncf.ncf_final,
itbis = ncf.itbis,
disponible = ncf.disponible,
fecha_vencimiento = vfec_vence,
us_mod = USUARIOS,
fech_mod = GETDATE()
WHERE tipo_doc = k_tipo_doc AND
codigo_dgii = k_codigo_dgii AND
sucid = k_sucid
IF SQLCA.SQLERRD[3] = 0 THEN
CALL fgl_winmessage("NCF","No se encontro el comprobante a modificar.","stop")
ELSE
LET numero_msg = 13
CALL msg(numero_msg)
END IF
# Muestra lo que quedo grabado en la base
CALL refresca_ncf() RETURNING sec_ncf
DISPLAY BY NAME sec_ncf
COMMAND KEY ("L") "eLiminar"
SELECT a.ncf FROM vetb00072 a
WHERE a.ncf BETWEEN ncf.ncf_inicial AND ncf.ncf_final AND
sucid = ncf.sucid
IF STATUS = NOTFOUND THEN
DELETE FROM vetb00071 WHERE fecha = ncf.fecha AND
# Solo se borra si ningun documento uso NCF de ese comprobante/rango
LET usados = 0
SELECT COUNT(*) INTO usados FROM vetb00072 a
WHERE a.tipo_doc = ncf.tipo_doc AND a.codigo_dgii = ncf.codigo_dgii AND
a.ncf BETWEEN ncf.ncf_inicial AND ncf.ncf_final AND
a.sucid = ncf.sucid
IF usados = 0 THEN
DELETE FROM vetb00071 WHERE tipo_doc = ncf.tipo_doc AND
codigo_dgii = ncf.codigo_dgii AND
sucid = ncf.sucid
ELSE
LET numero_msg =32
CALL msg(numero_msg)
EXIT MENU
END IF
LET numero_msg = 39
CALL msg(numero_msg)
COMMAND "Retornar"
"Retorna al menu anterior"
COMMAND "Retornar"
"Retorna al menu anterior"
CLEAR FORM
EXIT MENU
END MENU
END FUNCTION
END FUNCTION
# Validaciones comunes de Nuevo y Modificar
FUNCTION valida_ncf()
IF ncf.tipo_doc IS NULL OR ncf.codigo_dgii IS NULL OR ncf.sucid IS NULL THEN
CALL fgl_winmessage("NCF","Tipo de documento, codigo y localidad son obligatorios.","stop")
RETURN FALSE
END IF
IF ncf.ncf_inicial IS NULL OR ncf.ncf_final IS NULL OR
ncf.ncf_final < ncf.ncf_inicial THEN
CALL fgl_winmessage("NCF","El NCF final debe ser mayor o igual al NCF inicial.","stop")
RETURN FALSE
END IF
RETURN TRUE
END FUNCTION
# Relee de la base el comprobante actual y lo muestra. El SCROLL CURSOR guarda
# una foto de cuando se abrio la consulta: sin esto, al navegar se ven los
# valores viejos (p.ej. disponible) aunque ya esten modificados.
FUNCTION refresca_ncf()
DEFINE vsec INTEGER,
vmensaje STRING
LET vsec = NULL
IF ncf.codigo_dgii IS NULL THEN
RETURN vsec
END IF
WHENEVER ERROR CONTINUE
SELECT a.fecha,a.tipo_ncf,a.ncf_inicial,a.ncf_final,a.disponible,a.itbis,
a.fecha_vencimiento,a.us_crea,a.fech_crea,a.us_mod,a.fech_mod
INTO ncf.fecha,ncf.tipo_ncf,ncf.ncf_inicial,ncf.ncf_final,ncf.disponible,
ncf.itbis,fecha_vencimiento,ncf.us_crea,ncf.fech_crea,ncf.us_mod,ncf.fech_mod
FROM vetb00071 a
WHERE a.tipo_doc = ncf.tipo_doc AND a.codigo_dgii = ncf.codigo_dgii
AND a.sucid = ncf.sucid
IF SQLCA.SQLCODE < 0 THEN
LET vmensaje = "El comprobante ",ncf.tipo_doc," ",ncf.codigo_dgii CLIPPED,
" esta duplicado en vetb00071 para esta localidad."
CALL fgl_winmessage("NCF",vmensaje,"stop")
END IF
WHENEVER ERROR STOP
SELECT MAX(b.ncf) INTO vsec FROM vetb00073 b
WHERE b.tipo_doc = ncf.tipo_doc AND b.codigo_dgii = ncf.codigo_dgii
DISPLAY BY NAME ncf.*,fecha_vencimiento
RETURN vsec
END FUNCTION