From 7e166ca85225df374461c60b3999a3300233ed6f Mon Sep 17 00:00:00 2001 From: Jhonny Soto Date: Mon, 19 Oct 2026 12:19:21 -0400 Subject: [PATCH 1/2] JSOTO MainMenu: lanza cada programa desde su ruta de seg0005 y con el runtime del menu - Cada programa arranca parado en su ruta de seg0005 (cd /d), como en 3.20: ahi estan cert\, filesXML\, net6.0\, tmp\... que la factura electronica busca con rutas relativas, y sus .42m. Antes heredaba como directorio de trabajo la carpeta del despliegue del GAR, que cambia en cada deploy y llego a tener .42m de 3.20 (-6201 Bad version). - Usa %FGLDIR%\bin\fglrun (el runtime del menu) en vez del primer fglrun del PATH. - Ya no imprime usuario y clave en la consola/log del GAS. Probado en .251 (despliegue mbs-20261019-121056): cgprmt001 y cgprmt004 OK. Co-Authored-By: Claude Opus 5.5 --- PROYECTO/otrodir/MainMenu.4gl | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/PROYECTO/otrodir/MainMenu.4gl b/PROYECTO/otrodir/MainMenu.4gl index 136e172..47f0201 100644 --- a/PROYECTO/otrodir/MainMenu.4gl +++ b/PROYECTO/otrodir/MainMenu.4gl @@ -96,6 +96,7 @@ END MAIN FUNCTION show_mbs(d) DEFINE d ui.Dialog DEFINE rdir, rmbs INTEGER + DEFINE runtime STRING DEFINE cmd STRING,file_path VARCHAR(100), strconect VARCHAR(20) @@ -116,9 +117,24 @@ FUNCTION show_mbs(d) a.programa = pprograma # LET file_path = 'E:\\MARMOTECHC\\BIN320' DISPLAY BY NAME file_path,pperfil - DISPLAY "mainmenu credenciales: ",usuario clipped," ",clave clipped," ",file_path clipped - LET cmd = "fglrun ",file_path CLIPPED, "\\",mbs[rmbs].prog, ".42r " ,usuario CLIPPED," ",clave CLIPPED, + -- (antes imprimia usuario y CLAVE en texto claro en la consola/log) + DISPLAY "mainmenu ejecuta: ",mbs[rmbs].prog CLIPPED," desde ",file_path CLIPPED + -- Mismo runtime que el menu (no el primer "fglrun" del PATH del servidor) + LET runtime = fgl_getenv("FGLDIR") + IF runtime IS NULL OR runtime.getLength() = 0 THEN + LET runtime = "fglrun" + ELSE + LET runtime = '"', runtime, '\\bin\\fglrun"' + END IF + LET cmd = runtime," ",file_path CLIPPED, "\\",mbs[rmbs].prog, ".42r " ,usuario CLIPPED," ",clave CLIPPED, " ",pprinter1 ," ",pprinter2, " ",ckprinter," ",file_path," ",strconect + -- El programa arranca parado en su ruta de seg0005 (como en 3.20): ahi estan + -- cert\, filesXML\, net6.0\, tmp\... que la factura electronica busca con rutas + -- relativas, y sus .42m. Sin esto heredaba como directorio de trabajo la carpeta + -- del despliegue del GAR (que cambia en cada deploy y llego a tener .42m de 3.20). + IF file_path IS NOT NULL AND LENGTH(file_path CLIPPED) > 0 THEN + LET cmd = 'cd /d "', file_path CLIPPED, '" && ', cmd + END IF RUN cmd WITHOUT WAITING UPDATE seg0001 SET ultimo_programa_ejecutado = pprograma WHERE seg0001.usuario = usuario From 9eb74bbea730047fcded95f902a9bac71215635a Mon Sep 17 00:00:00 2001 From: Jhonny Soto Date: Tue, 20 Oct 2026 16:04:59 -0400 Subject: [PATCH 2/2] JSOTO veconvierteorden/ccprmt003: evita ordenes duplicadas por cotizacion Dos usuarios convirtiendo la misma cotizacion a la vez creaban dos ordenes (cot 340001 -> 262237 y 262238, ticket 12234). La validacion "cotizacion tiene orden" corria antes del BEGIN WORK; el segundo usuario la pasaba, esperaba el bloqueo de prtb00020 y al liberarse insertaba otra orden. - vedir/veconvierteorden: re-valida dentro de la transaccion, ya con el bloqueo de prtb00020. - WEBSERVICES/veconvierteorden: misma re-validacion (no tenia ninguna). - ccdir/ccprmt003 verifica_orden(): COUNT(*) en vez de SELECT num_oc, que daba -284 con ordenes duplicadas. Co-Authored-By: Claude Opus 5.5 --- PROYECTO/ccdir/ccprmt003.4gl | 10 +++++----- PROYECTO/vedir/veconvierteorden.4gl | 12 ++++++++++++ WEBSERVICES/veconvierteorden.4gl | 11 +++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/PROYECTO/ccdir/ccprmt003.4gl b/PROYECTO/ccdir/ccprmt003.4gl index 3a50555..7b3b9de 100644 --- a/PROYECTO/ccdir/ccprmt003.4gl +++ b/PROYECTO/ccdir/ccprmt003.4gl @@ -2758,11 +2758,11 @@ REPORT cctb01b( END REPORT FUNCTION verifica_orden() - LET tieneorden = TRUE - SELECT a.num_oc + DEFINE cuantas INT + # COUNT(*) en vez de SELECT num_oc: con ordenes duplicadas daba -284 + LET cuantas = 0 + SELECT COUNT(*) INTO cuantas FROM prtb00012 a WHERE a.cotizacion_no = recibo_nc.num_orden AND a.status_T IS NULL - IF STATUS = NOTFOUND THEN - LET tieneorden = FALSE - END IF + LET tieneorden = (cuantas > 0) END FUNCTION diff --git a/PROYECTO/vedir/veconvierteorden.4gl b/PROYECTO/vedir/veconvierteorden.4gl index 3e9a5f4..4a77aab 100644 --- a/PROYECTO/vedir/veconvierteorden.4gl +++ b/PROYECTO/vedir/veconvierteorden.4gl @@ -126,6 +126,18 @@ FUNCTION convierteorden( UPDATE prtb00020 SET num_oc = ISNULL(num_oc, 0) + 1, us_crea = xusuario, fech_crea = GETDATE() SELECT num_oc INTO ult_numero FROM prtb00020 + # RE-VALIDACION YA CON EL BLOQUEO DE prtb00020: la validacion del inicio + # corre fuera de la transaccion; si otro usuario estaba convirtiendo la + # misma cotizacion, aqui ya vemos su orden confirmada (cot 340001, 20/10/2026) + LET existe_oc = 0 + SELECT COUNT(*) INTO existe_oc FROM prtb00012 + WHERE cotizacion_no = xcotizacion_no AND status_t IS NULL + IF existe_oc > 0 THEN + ROLLBACK WORK + CALL fgl_winmessage( + "ERROR", "COTIZACION TIENE ORDEN, NO PUEDE CREAR ORDEN", "STOP") + RETURN 0, FALSE + END IF # AUTOCORRECCION: si el contador quedo por detras de prtb00012 # (otro programa creo ordenes sin avanzarlo), salta al siguiente libre LET existe_oc = 0 diff --git a/WEBSERVICES/veconvierteorden.4gl b/WEBSERVICES/veconvierteorden.4gl index 7eff0f2..e460b96 100644 --- a/WEBSERVICES/veconvierteorden.4gl +++ b/WEBSERVICES/veconvierteorden.4gl @@ -139,6 +139,17 @@ BEGIN WORK us_crea = xusuario, fech_crea = GETDATE() SELECT num_oc INTO ult_numero FROM prtb00020 + # RE-VALIDACION YA CON EL BLOQUEO DE prtb00020: evita dos ordenes para la + # misma cotizacion si dos usuarios convierten a la vez (cot 340001, 20/10/2026) + LET existe_oc = 0 + SELECT COUNT(*) INTO existe_oc FROM prtb00012 + WHERE cotizacion_no = xcotizacion_no AND status_t IS NULL + IF existe_oc > 0 THEN + LET pmensaje_error = + SFMT("La cotizacion %1 ya tiene orden, no puede crear otra.", xcotizacion_no) + ROLLBACK WORK + RETURN 0,FALSE + END IF # AUTOCORRECCION: si el contador quedo por detras de prtb00012, salta al siguiente libre LET existe_oc = 0 SELECT COUNT(*) INTO existe_oc FROM prtb00012 WHERE num_oc = ult_numero