{ ------------------------------------------------------------------ PROGRAMA : VEPRMT020 OBJETIVO : Capturar, Modificar, Eliminar registros de la 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 CALL ARG_VAL(2) RETURNING clave CALL ARG_VAL(4) RETURNING impresor 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 OPTIONS FORM LINE 9, ERROR LINE 23, COMMENT LINE 21 OPEN FORM vefmmt020 FROM "vefmmt020" DISPLAY FORM vefmmt020 MENU ON ACTION nuevo CALL vepcad020() ON ACTION modificar CALL vepcmf020() ON ACTION Salir EXIT MENU EXIT PROGRAM END MENU END FUNCTION FUNCTION vepcad020() 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 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 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,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,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() 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" SET CONNECTION "MSSQL" CONSTRUCT criterio ON a.fecha,a.tipo_doc,a.codigo_dgii FROM fecha,tipo_doc,codigo_dgii BEFORE CONSTRUCT CALL localidades('1') AFTER CONSTRUCT 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.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,a.tipo_doc,a.codigo_dgii" PREPARE busca FROM selec 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.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.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 "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.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.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) 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.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) COMMAND "Escoger" " Actualiza Registro Cancela Operacion" # 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 CALL msg(numero_msg) LET int_flag = FALSE EXIT MENU END IF 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 tipo_doc = ncf.tipo_doc, 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 AND codigo_dgii=ncf.codigo_dgii 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} 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" # 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" CLEAR FORM EXIT MENU END MENU 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