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
+462 -105
View File
@@ -12,7 +12,7 @@ GLOBALS
"ipprgb000.4gl"
DEFINE ordenx,tmpnumero,tmpnueroExistencia INTEGER,
DEFINE ordenx,tmpnumero,tmpnueroExistencia,vnum_desp INTEGER,
hacerdocumento BOOLEAN,
direccion_p VARCHAR(200),
sucid SMALLINT
@@ -358,6 +358,11 @@ DISPLAY "numero factura2 ",otros_mov.descrip4
END IF
LET otros_mov.num_doc = tmpnumero + 1
DISPLAY BY NAME otros_mov.num_doc
# Numero provisional del DESPIECE: el provisional del documento en NEGATIVO
# (nunca coincide con un documento real) y siempre filtrado por usuario.
# Se limpian piezas que haya dejado un intento anterior no grabado.
LET vnum_desp = otros_mov.num_doc * -1
DELETE FROM iptb00025 WHERE num_doc = vnum_desp AND us_crea = usuarios
LET otros_mov.fecha = TODAY
DISPLAY BY NAME otros_mov.fecha
@@ -1291,12 +1296,16 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
a.cod_tipo = movi2[p_act].cod_tipo AND
a.cod_sec = movi2[p_act].cod_sec AND
a.cod_mov = otros_mov.cod_mov AND
a.num_doc = otros_mov.num_Doc
a.num_doc = vnum_desp AND a.us_crea = usuarios
IF STATUS = NOTFOUND THEN
LET numero_msg =398
CALL msg(numero_msg)
NEXT FIELD cod_n
# El producto lleva despiece y no se ha hecho: abrir la ventana
# sola (antes solo mostraba el mensaje 398)
IF NOT abre_despiece_si_falta() THEN
LET numero_msg =398
CALL msg(numero_msg)
NEXT FIELD cod_n
END IF
END IF
END IF
@@ -1313,6 +1322,19 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
END IF # CONTROL CODIGO EN BLANCO
BEFORE FIELD cantidad_1
# En devoluciones el cursor salta directo a la cantidad (no pasa por
# cod_sec): si el producto lleva despiece y no se ha hecho, abrirlo
IF otros_mov.cod_mov = 12 OR otros_mov.cod_mov = 13 THEN
LET p_act = arr_curr()
LET scr_l = scr_line()
IF NOT abre_despiece_si_falta() THEN
# se cancelo: avisa; al grabar igual lo exige (msg 398)
LET numero_msg = 398
CALL msg(numero_msg)
END IF
END IF
AFTER FIELD cantidad_1
LET p_act = arr_curr()
@@ -1398,8 +1420,8 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
# CONTROL CANTIDAD DESPIECE
LET total_medida = 0
IF otros_mov.cod_mov = 30 OR otros_mov.cod_mov = 31 OR
otros_mov.cod_mov = 55 OR otros_mov.cod_mov = 70 OR otros_mov.cod_mov = 71 OR
otros_mov.cod_mov = 72 THEN
otros_mov.cod_mov = 55 OR otros_mov.cod_mov = 56 OR otros_mov.cod_mov = 70 OR
otros_mov.cod_mov = 71 OR otros_mov.cod_mov = 72 THEN
# CONTROL DESPIECE
SELECT UNIQUE a.cod_n FROM iptb00027 a
@@ -1416,7 +1438,7 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
a.cod_tipo = movi2[p_act].cod_tipo AND
a.cod_sec = movi2[p_act].cod_sec AND
a.cod_mov = otros_mov.cod_mov AND
a.num_doc = otros_mov.num_Doc
a.num_doc = vnum_desp AND a.us_crea = usuarios
IF STATUS = NOTFOUND THEN
LET numero_msg =398
@@ -1431,7 +1453,7 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
a.cod_tipo = movi2[p_act].cod_tipo AND
a.cod_sec = movi2[p_act].cod_sec AND
a.cod_mov = otros_mov.cod_mov AND
a.num_doc = otros_mov.num_doc
a.num_doc = vnum_desp AND a.us_crea = usuarios
IF STATUS != NOTFOUND THEN
SELECT SUM(a.medida) INTO total_medida
@@ -1442,12 +1464,25 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
a.cod_sec = movi2[p_act].cod_sec AND
a.cod_mov = otros_mov.cod_mov AND
a.area = movi2[p_act].area AND
a.num_doc = otros_mov.num_doc
a.num_doc = vnum_desp AND a.us_crea = usuarios
IF total_medida <> movi2[p_act].cantidad_1 THEN
LET numero_msg = 152
CALL msg(numero_msg)
NEXT FIELD cantidad_1
# Diferencia de redondeo (la requisicion guarda 4 decimales y
# el despiece 5): la linea toma el total exacto del despiece.
LET diferencia = total_medida - movi2[p_act].cantidad_1
IF diferencia < 0 THEN
LET diferencia = diferencia * -1
END IF
IF diferencia <= .01 THEN
LET movi2[p_act].cantidad_1 = total_medida
LET movi2[p_act].cantidad_2 = movi2[p_act].cantidad_1 * factor_conv[p_act]
DISPLAY movi2[p_act].cantidad_1 TO s_movi1[scr_l].cantidad_1
DISPLAY movi2[p_act].cantidad_2 TO s_movi1[scr_l].cantidad_2
ELSE
LET numero_msg = 152
CALL msg(numero_msg)
NEXT FIELD cantidad_1
END IF
END IF
END IF
LET selec_pt = selec_pt CLIPPED,movi2[p_act].descrip_esp," CANTIDAD ",
@@ -1496,25 +1531,20 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
END IF
IF otros_mov.cod_mov <> 12 AND otros_mov.cod_mov <> 13 and otros_mov.cod_mov <> 43
THEN
LET cantidad_conduce = 0
IF movi2[p_act].id_kit IS NULL THEN
SELECT SUM(a.cantidad) INTO cantidad_conduce FROM prtb00013 a
WHERE a.cod_n = movi2[p_act].cod_n AND
a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND
a.cod_sec = movi2[p_act].cod_sec AND
a.num_oc = ordenx AND
a.status_t IS NULL
ELSE
SELECT SUM(a.cantidad) INTO cantidad_conduce FROM prtb00030 a
WHERE a.cod_n = movi2[p_act].cod_n AND
a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND
a.cod_sec = movi2[p_act].cod_sec AND
a.num_oc = ordenx
END IF
LET cantidad_orden =0
# Pendiente de la orden = pedido - ya despachado (antes se calculaba
# el pedido pero NUNCA se comparaba con la cantidad digitada)
CALL pendiente_orden(movi2[p_act].cod_n,movi2[p_act].cod_grupo,
movi2[p_act].cod_tipo,movi2[p_act].cod_sec,
movi2[p_act].id_kit)
RETURNING cantidad_conduce,cantidad_orden
LET movi2[p_act].cantidad_p = cantidad_conduce - cantidad_orden
DISPLAY movi2[p_act].cantidad_p TO s_movi1[scr_l].cantidad_p
IF pcontrol_despacho = "SI" THEN
IF NOT cantidad_cabe_en_orden(p_act) THEN
LET hacerdocumento = FALSE
NEXT FIELD cantidad_1
END IF
END IF
END IF # CONTROL CONDUCE_NO
END IF # CONTROL DEVOLUCION
@@ -1525,17 +1555,26 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
AFTER INPUT
IF int_flag THEN
DELETE FROM iptb00025 WHERE cod_mov = otros_mov.cod_mov and num_doc = otros_mov.num_Doc
DELETE FROM iptb00025 WHERE cod_mov = otros_mov.cod_mov and num_doc = vnum_desp AND us_crea = usuarios
LET numero_msg = 2
CALL msg(numero_msg)
LET int_flag = false
RETURN
END IF
# Todo producto que lleva despiece (iptb00027) debe tener su despiece
# abierto (iptb00025). Antes solo se validaba al salir de cod_sec, y los
# productos que vienen cargados de la orden nunca pasan por ese campo.
LET idx = falta_despiece()
IF idx > 0 THEN
CALL msg(398)
CALL fgl_set_arr_curr(idx)
NEXT FIELD cantidad_1
END IF
END INPUT
LABEL sale_boni:
PROMPT "Toda la Informacion Esta Correcta? (S/N)" FOR CHAR opc
LET opc = "S" # sin pregunta al guardar (antes: PROMPT "Toda la Informacion Esta Correcta? (S/N)")
IF OPC = "S" or OPC = "s" THEN
BEGIN WORK
@@ -1557,12 +1596,14 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
fech_crea = getdate()
WHERE cod_mov = otros_mov.cod_mov AND bodega = otros_mov.bodega
UPDATE iptb00025 SET num_doc = otros_mov.num_doc WHERE num_doc = tmpnueroExistencia AND
cod_mov = otros_mov.cod_mov
DISPLAY BY NAME otros_mov.num_doc ATTRIBUTE (BLUE)
# El despiece se capturo con el numero provisional NEGATIVO del usuario
# (vnum_desp); aqui pasa al numero definitivo. Antes renumeraba desde
# tmpnumero (provisional - 1) y tmpnueroExistencia, y arrastraba piezas de
# OTROS documentos reales con ese numero.
UPDATE iptb00025 SET num_doc = otros_mov.num_doc
WHERE num_doc = tmpnumero AND cod_mov = otros_mov.cod_mov
WHERE num_doc = vnum_desp AND cod_mov = otros_mov.cod_mov AND us_crea = usuarios
DISPLAY BY NAME otros_mov.num_doc ATTRIBUTE (BLUE)
# INSERTA REGISTROS DE ENTRADAS CON LOS CONDUCES
IF otros_mov.cod_mov1 IS NOT NULL THEN
@@ -1621,28 +1662,17 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
# CONTROL REQUISICION DESPACHO
#======================================================================
SELECT SUM(a.cantidad_2*-1) INTO cantidad_orden
FROM iptb00006 a
WHERE a.cod_n=movi2[idx].cod_n and a.cod_grupo=movi2[idx].cod_grupo
and a.cod_tipo=movi2[idx].cod_tipo AND
a.cod_sec=movi2[idx].cod_sec
and a.num_oc =ordenx AND
a.cod_mov in (30,31,55,12,13,43)
and a.status_t IS NULL
IF cantidad_orden IS NULL THEN
LET cantidad_orden = 0
END IF
IF cantidad_conduce IS NULL THEN
LET cantidad_conduce = 0
END IF
# pendiente de ESTE producto (incluye lo ya grabado en esta misma
# transaccion para renglones anteriores del mismo producto)
CALL pendiente_orden(movi2[idx].cod_n,movi2[idx].cod_grupo,
movi2[idx].cod_tipo,movi2[idx].cod_sec,
movi2[idx].id_kit)
RETURNING cantidad_conduce,cantidad_orden
LET movi2[idx].cantidad_p = cantidad_conduce - cantidad_orden
IF movi2[idx].cantidad_2 > movi2[idx].cantidad_p THEN
IF movi2[idx].cantidad_2 > movi2[idx].cantidad_p + .01 THEN # .01 = tolerancia de redondeo
ROLLBACK WORK
DISPLAY movi2[idx].cantidad_p TO s_movi1[scr_l].cantidad_p ATTRIBUTE(RED)
CALL msg(46)
@@ -1651,7 +1681,7 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
CALL control_requisicion(movi2[idx].cantidad_2,
movi2[idx].cod_n,movi2[idx].cod_grupo,
movi2[idx].cod_tipo,movi2[p_act].cod_sec,
movi2[idx].cod_tipo,movi2[idx].cod_sec,
movi2[idx].id_kit)
RETURNING estado_req
@@ -1705,9 +1735,11 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
ELSE
UPDATE iptb00043 SET num_doc = otros_mov.num_doc WHERE usuario = usuarios
END IF
# Estado de la requisicion y cierre de la orden (como la version de junio)
CALL cierre_orden_requisicion()
COMMIT WORK
PROMPT "Desea Imprimir Formulario Ahora? (S/N)" FOR CHAR opt2
LET opt2 = "S" # imprime (PDF) sin preguntar (antes: PROMPT "Desea Imprimir Formulario Ahora? (S/N)")
IF opt2 = "S" OR opt2 = "s" THEN
@@ -1720,6 +1752,7 @@ DISPLAY "CANTIDAD E ",cantidad_entrada," c salida ",cantidad_conduce
-- Carga el .4rp grafico nuevo (ipprmt044.4rp) en vez del default por
-- nombre del report. El cuerpo de formu4 ahora usa PRINTX.
IF fgl_report_loadCurrentSettings("ipprmt044.4rp") THEN
CALL fgl_report_selectDevice("PDF") -- el formulario sale en PDF
CALL fgl_report_selectPreview(TRUE)
LET handler = fgl_report_commitCurrentSettings()
ELSE
@@ -1910,6 +1943,9 @@ FORMAT
WHERE a.cod_mov = x.cod_mov AND a.num_doc = x.num_doc
AND a.cod_n = z.cod_n AND a.cod_grupo = z.cod_grupo
AND a.cod_tipo = z.cod_tipo AND a.cod_sec = z.cod_sec
-- por AREA: el mismo producto en dos lineas de areas distintas
-- imprimia las piezas de las dos debajo de cada linea
AND (a.area = z.area OR a.area IS NULL OR a.area = 0)
BEFORE GROUP OF z.area
@@ -2014,7 +2050,10 @@ FIRST + 1,PROMPT LINE LAST)
END FUNCTION
FUNCTION despiece()
DEFINE cetiqueta VARCHAR(20)
DEFINE cetiqueta VARCHAR(20),
vi INTEGER,
vtotal_piezas,vdespachado,vdif DEC(12,5),
vmensaje STRING
OPEN WINDOW wdespiece AT 5,3 WITH FORM "ipfmwd010" ATTRIBUTE (BORDER,FORM LINE
FIRST + 1,PROMPT LINE LAST)
@@ -2039,7 +2078,7 @@ FIRST + 1,PROMPT LINE LAST)
SELECT a.etiqueta,a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.lado_1,a.lado_2,a.lado_3,a.cantidad,a.medida
FROM iptb00025 a
WHERE a.cod_mov = otros_mov.cod_mov AND
a.num_doc = tmpnumero AND
a.num_doc = vnum_desp AND a.us_crea = usuarios AND
a.cod_n = movi2[p_act].cod_n AND
a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND
@@ -2055,7 +2094,7 @@ FIRST + 1,PROMPT LINE LAST)
SELECT UNIQUE a.cod_n FROM iptb00025 a
WHERE a.cod_mov = otros_mov.cod_mov AND
a.num_doc = otros_mov.num_doc AND
a.num_doc = vnum_desp AND a.us_crea = usuarios AND
a.cod_n = movi2[p_act].cod_n AND
a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND
@@ -2063,64 +2102,142 @@ FIRST + 1,PROMPT LINE LAST)
a.area = movi2[p_act].area
IF STATUS = NOTFOUND THEN
IF otros_mov.cod_mov = 12 OR otros_mov.cod_mov = 13 THEN
# DEVOLUCION: el despiece que realmente se DESPACHO para esa factura, o sea
# el de su(s) conduce(s) de salida (iptb00025 de los movs 30/31/55/56 con
# fact_no = factura). No el de la orden: si la orden no se despacho entera
# daria un valor errado. Primero con el area de la linea; si no hay, sin area.
DECLARE busca_despiece_dev CURSOR FOR
SELECT p.etiqueta,p.cod_n,p.cod_grupo,p.cod_tipo,p.cod_sec,p.lado_1,p.lado_2,p.lado_3,p.cantidad,p.medida
FROM iptb00025 p
WHERE p.cod_n = movi2[p_act].cod_n AND
p.cod_grupo = movi2[p_act].cod_grupo AND
p.cod_tipo = movi2[p_act].cod_tipo AND
p.cod_sec = movi2[p_act].cod_sec AND
p.area = movi2[p_act].area AND
p.cod_mov IN (30,31,55,56) AND
p.num_doc IN (SELECT d.num_doc FROM iptb00006 d
WHERE d.fact_no = otros_mov.fact_no AND d.cod_mov IN (30,31,55,56)
AND d.status_t IS NULL
AND d.cod_n = movi2[p_act].cod_n AND d.cod_grupo = movi2[p_act].cod_grupo
AND d.cod_tipo = movi2[p_act].cod_tipo AND d.cod_sec = movi2[p_act].cod_sec)
LET idx = 1
FOREACH busca_despiece_dev INTO despiece[idx].*
LET idx = idx + 1
END FOREACH
IF idx = 1 THEN
DECLARE busca_despiece_dev2 CURSOR FOR
SELECT p.etiqueta,p.cod_n,p.cod_grupo,p.cod_tipo,p.cod_sec,p.lado_1,p.lado_2,p.lado_3,p.cantidad,p.medida
FROM iptb00025 p
WHERE p.cod_n = movi2[p_act].cod_n AND
p.cod_grupo = movi2[p_act].cod_grupo AND
p.cod_tipo = movi2[p_act].cod_tipo AND
p.cod_sec = movi2[p_act].cod_sec AND
p.cod_mov IN (30,31,55,56) AND
p.num_doc IN (SELECT d.num_doc FROM iptb00006 d
WHERE d.fact_no = otros_mov.fact_no AND d.cod_mov IN (30,31,55,56)
AND d.status_t IS NULL
AND d.cod_n = movi2[p_act].cod_n AND d.cod_grupo = movi2[p_act].cod_grupo
AND d.cod_tipo = movi2[p_act].cod_tipo AND d.cod_sec = movi2[p_act].cod_sec)
FOREACH busca_despiece_dev2 INTO despiece[idx].*
LET idx = idx + 1
END FOREACH
END IF
IF idx = 1 THEN
CALL fgl_winmessage("DESPIECE",
"No se encontro el despiece de este producto en los conduces de la factura.",
"exclamation")
ELSE
# Control: la suma de las piezas debe cuadrar con lo despachado de ese
# producto en los conduces de la factura (conduces viejos pueden tener
# el despiece duplicado)
LET vtotal_piezas = 0
FOR vi = 1 TO idx - 1
IF despiece[vi].medida IS NOT NULL THEN
LET vtotal_piezas = vtotal_piezas + despiece[vi].medida
END IF
END FOR
LET vdespachado = 0
SELECT SUM(d.cantidad_2 * -1) INTO vdespachado FROM iptb00006 d
WHERE d.fact_no = otros_mov.fact_no AND d.cod_mov IN (30,31,55,56)
AND d.status_t IS NULL
AND d.cod_n = movi2[p_act].cod_n AND d.cod_grupo = movi2[p_act].cod_grupo
AND d.cod_tipo = movi2[p_act].cod_tipo AND d.cod_sec = movi2[p_act].cod_sec
IF vdespachado IS NULL THEN
LET vdespachado = 0
END IF
LET vdif = vtotal_piezas - vdespachado
IF vdif < 0 THEN
LET vdif = vdif * -1
END IF
IF vdif > .01 THEN
LET vmensaje = "El despiece del conduce suma ", vtotal_piezas USING "<<<,<<<,<<&.&&&&&",
" pero lo despachado de este producto fue ", vdespachado USING "<<<,<<<,<<&.&&&&&", ".",
"\nRevise las piezas antes de aceptar (el conduce puede tener piezas repetidas)."
CALL fgl_winmessage("DESPIECE",vmensaje,"exclamation")
END IF
END IF
ELSE
IF pcontrol_despacho = "SI" AND pnum_req IS NOT NULL THEN
# Despacho con requisicion: las piezas autorizadas en la requisicion
# (cctb00027, copia de las piezas de la orden con lo que se despacha).
# Antes se tomaban TODAS las piezas de la orden (prtb00022) y si la orden
# tenia mas de ese producto que la requisicion, la cantidad cambiaba
# (ej. requisicion 17, orden 19 -> el despiece ponia 19).
DECLARE busca_despiece_req CURSOR FOR
SELECT c.etiqueta,c.cod_n,c.cod_grupo,c.cod_tipo,
c.cod_sec,c.lado_1,c.lado_2,c.lado_3,
c.cantidad_r,c.medida_r
FROM cctb00027 c
WHERE c.num_req = pnum_req AND
c.area = movi2[p_act].area AND
c.cod_n = movi2[p_act].cod_n AND
c.cod_grupo = movi2[p_act].cod_grupo AND
c.cod_tipo = movi2[p_act].cod_tipo AND
c.cod_sec = movi2[p_act].cod_sec
LET idx = 1
FOREACH busca_despiece_req INTO despiece[idx].*
LET idx = idx + 1
END FOREACH
ELSE
DECLARE busca_despiece CURSOR FOR
SELECT a.etiqueta,a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.lado_1,a.lado_2,a.lado_3,a.cantidad,a.medida
FROM prtb00022 a
WHERE
WHERE
a.num_oc =ordenx AND
a.cod_n = movi2[p_act].cod_n AND
a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND
a.cod_sec = movi2[p_act].cod_sec AND
a.area = movi2[p_act].area
a.area = movi2[p_act].area
LET idx = 1
FOREACH busca_despiece INTO despiece[idx].*
LET idx = idx + 1
END FOREACH
END IF
END IF
ELSE
IF pcontrol_despacho <> "SI" THEN
DECLARE busca_despiece1 CURSOR FOR
SELECT b.descripcion,a.cod_n,a.cod_grupo,a.cod_tipo,
a.cod_sec,a.lado_1,a.lado_2,a.lado_3, a.cantidad,a.medida
FROM prtb00022 a,vetb00026 b
WHERE a.num_oc = otros_mov.conduce_no AND
a.area = movi2[p_act].area AND
a.cod_n = movi2[p_act].cod_n AND
a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND
a.cod_sec = movi2[p_act].cod_sec AND
CAST(a.etiqueta AS SMALLINT) = b.codid
LET idx = 1
FOREACH busca_despiece1 INTO despiece[idx].*
LET idx = idx + 1
END FOREACH
ELSE
DECLARE busca_despiece12 CURSOR FOR
# Ya hay despiece guardado de este producto en el documento (se esta
# volviendo a abrir): cargar LAS PIEZAS GUARDADAS para seguir editandolas.
# Antes recargaba todas las piezas de la orden (prtb00022) y con la
# DESCRIPCION de la etiqueta en un campo numerico, por lo que aparecian
# piezas de mas y todas con la etiqueta vacia.
DECLARE busca_despiece_guardado CURSOR FOR
SELECT a.etiqueta,a.cod_n,a.cod_grupo,a.cod_tipo,
a.cod_sec,a.lado_1,a.lado_2,a.lado_3,
c.cantidad_r,c.medida_r
FROM prtb00022 a, cctb00027 c
WHERE a.num_oc = ordenx AND
a.area = c.area AND
a.area = movi2[p_act].area AND
a.cod_sec,a.lado_1,a.lado_2,a.lado_3,a.cantidad,a.medida
FROM iptb00025 a
WHERE a.cod_mov = otros_mov.cod_mov AND
a.num_doc = vnum_desp AND a.us_crea = usuarios AND
a.cod_n = movi2[p_act].cod_n AND
a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND
a.cod_sec = movi2[p_act].cod_sec AND
a.cod_n = C.cod_n AND
a.cod_grupo = c.cod_grupo AND
a.cod_tipo = c.cod_tipo AND
a.cod_sec = c.cod_sec AND
c.num_req = pnum_req
a.area = movi2[p_act].area
LET idx = 1
FOREACH busca_despiece12 INTO despiece[idx].*
FOREACH busca_despiece_guardado INTO despiece[idx].*
LET idx = idx + 1
END FOREACH
END IF
END IF
END IF
@@ -2147,7 +2264,8 @@ FIRST + 1,PROMPT LINE LAST)
LET despiece[curr1].etiqueta = despiece[curr1-1].etiqueta
END IF
END IF
DISPLAY cetiqueta TO sdespiece[fila].etiqueta
# antes mostraba cetiqueta (siempre vacia) y BORRABA la etiqueta de la linea
DISPLAY despiece[curr1].etiqueta TO sdespiece[fila].etiqueta
DISPLAY movi2[p_act].cod_n TO sdespiece[fila].cod_n
DISPLAY movi2[p_act].cod_grupo TO sdespiece[fila].cod_grupo
@@ -2182,6 +2300,11 @@ FIRST + 1,PROMPT LINE LAST)
CALL msg(numero_msg)
NEXT FIELD lado_1
END IF
IF despiece[curr1].etiqueta IS NULL AND
(despiece[curr1].lado_1 IS NOT NULL OR despiece[curr1].medida IS NOT NULL) THEN
CALL fgl_winmessage("DESPIECE","Seleccione la etiqueta de la pieza.","exclamation")
NEXT FIELD etiqueta
END IF
LET total_medida = 0
FOR idx = 1 TO arr_count()
IF despiece[idx].medida IS NOT NULL THEN
@@ -2197,6 +2320,17 @@ FIRST + 1,PROMPT LINE LAST)
CALL msg(numero_msg)
EXIT INPUT
END IF
# toda pieza con medidas debe tener etiqueta (las cargadas de la orden o
# la requisicion pueden venir sin ella)
FOR idx = 1 TO arr_count()
IF despiece[idx].etiqueta IS NULL AND
(despiece[idx].lado_1 IS NOT NULL OR despiece[idx].medida IS NOT NULL) THEN
CALL fgl_winmessage("DESPIECE",
"Hay piezas sin etiqueta. Seleccione la etiqueta de la linea marcada.","exclamation")
CALL fgl_set_arr_curr(idx)
NEXT FIELD etiqueta
END IF
END FOR
LET total_medida = 0
FOR idx = 1 TO arr_count()
IF despiece[idx].medida IS NOT NULL THEN
@@ -2210,7 +2344,7 @@ FIRST + 1,PROMPT LINE LAST)
CLOSE WINDOW wdespiece
RETURN
END IF
DELETE FROM iptb00025 WHERE num_doc = otros_mov.num_doc AND
DELETE FROM iptb00025 WHERE num_doc = vnum_desp AND us_crea = usuarios AND
cod_mov = otros_mov.cod_mov AND
cod_n = movi2[p_act].cod_n AND
cod_grupo = movi2[p_act].cod_grupo AND
@@ -2223,7 +2357,7 @@ FIRST + 1,PROMPT LINE LAST)
INSERT INTO iptb00025(etiqueta,cod_mov,num_doc,cod_n,cod_grupo,cod_tipo,cod_sec,
lado_1,lado_2,lado_3,cantidad,medida,us_crea,fech_crea,bodega,area)
VALUES(despiece[idx].etiqueta,otros_mov.cod_mov,otros_mov.num_doc,
VALUES(despiece[idx].etiqueta,otros_mov.cod_mov,vnum_desp,
movi2[p_act].cod_n,movi2[p_act].cod_grupo,
movi2[p_act].cod_tipo,movi2[p_act].cod_sec,
despiece[idx].lado_1,despiece[idx].lado_2,
@@ -2378,6 +2512,7 @@ MENU "Busqueda "
-- Carga el .4rp grafico nuevo (ipprmt044.4rp) en vez del default por
-- nombre del report. El cuerpo de formu4 ahora usa PRINTX.
IF fgl_report_loadCurrentSettings("ipprmt044.4rp") THEN
CALL fgl_report_selectDevice("PDF") -- el formulario sale en PDF
CALL fgl_report_selectPreview(TRUE)
LET handler = fgl_report_commitCurrentSettings()
ELSE
@@ -2661,7 +2796,7 @@ FUNCTION control_requisicion(cantidad_Trx,xcodn,xcodgrupo,xcodtipo,xcodsec,xkit)
a.num_req = pnum_req AND
a.status_t IS NULL
LET Rcantidad_requisicion = 0
SELECT SUM(a.cantidad_2) INTO Rcantidad_requisicion
SELECT SUM(a.cantidad_2 * -1) INTO Rcantidad_requisicion # despachos se graban en negativo
FROM iptb00006 a
WHERE
@@ -2669,14 +2804,18 @@ FUNCTION control_requisicion(cantidad_Trx,xcodn,xcodgrupo,xcodtipo,xcodsec,xkit)
a.cod_grupo = xcodgrupo AND
a.cod_tipo = xcodtipo AND
a.cod_sec = xcodsec AND
a.cod_mov IN (30,31,55,12,13) and
a.cod_mov IN (30,31,55,56,12,13) and
a.num_req = pnum_req AND
a.status_t IS NULL
IF Rcantidad_requisicion IS NULL THEN
LET Rcantidad_requisicion=0
END IF
IF (Rcantidad_requisicion)+cantidad_Trx > cantidadRequisicion THEN
IF cantidadRequisicion IS NULL THEN
LET cantidadRequisicion = 0
END IF
# .01 = tolerancia de redondeo (cctb00026.cantidad solo guarda 4 decimales)
IF (Rcantidad_requisicion)+cantidad_Trx > cantidadRequisicion + .01 THEN
RETURN FALSE
ELSE
RETURN true
@@ -2685,3 +2824,221 @@ END IF
END FUNCTION
# Cantidad pedida en la orden (ordenx) de un producto y lo ya despachado.
# Pedido: prtb00013 (o prtb00030 si es kit). Despachado: conduces de salida
# (30,31,55,56) neto de devoluciones/averias (12,13,43) en iptb00006.
FUNCTION pendiente_orden(pcod_n,pcod_grupo,pcod_tipo,pcod_sec,pid_kit)
DEFINE pcod_n,pcod_grupo,pcod_tipo,pcod_sec,pid_kit INTEGER,
vpedido,vdespachado DEC(12,5)
LET vpedido = 0
IF pid_kit IS NULL THEN
SELECT SUM(a.cantidad) INTO vpedido FROM prtb00013 a
WHERE a.cod_n = pcod_n AND a.cod_grupo = pcod_grupo AND
a.cod_tipo = pcod_tipo AND a.cod_sec = pcod_sec AND
a.num_oc = ordenx AND a.status_t IS NULL
ELSE
SELECT SUM(a.cantidad) INTO vpedido FROM prtb00030 a
WHERE a.cod_n = pcod_n AND a.cod_grupo = pcod_grupo AND
a.cod_tipo = pcod_tipo AND a.cod_sec = pcod_sec AND
a.num_oc = ordenx
END IF
IF vpedido IS NULL THEN
LET vpedido = 0
END IF
LET vdespachado = 0
SELECT SUM(a.cantidad_2*-1) INTO vdespachado FROM iptb00006 a
WHERE a.cod_n = pcod_n AND a.cod_grupo = pcod_grupo AND
a.cod_tipo = pcod_tipo AND a.cod_sec = pcod_sec AND
a.num_oc = ordenx AND
a.cod_mov IN (30,31,55,56,12,13,43) AND
a.status_t IS NULL
IF vdespachado IS NULL THEN
LET vdespachado = 0
END IF
RETURN vpedido,vdespachado
END FUNCTION
# TRUE si la cantidad del renglon (mas lo que llevan otros renglones del mismo
# producto en este documento) cabe en lo pendiente de la orden.
FUNCTION cantidad_cabe_en_orden(prow)
DEFINE prow,i INTEGER,
votros,vpedido,vdespachado,vpendiente DEC(12,5),
vmensaje STRING
CALL pendiente_orden(movi2[prow].cod_n,movi2[prow].cod_grupo,
movi2[prow].cod_tipo,movi2[prow].cod_sec,
movi2[prow].id_kit)
RETURNING vpedido,vdespachado
LET vpendiente = vpedido - vdespachado
LET votros = 0
FOR i = 1 TO movi2.getLength()
IF i <> prow AND movi2[i].cantidad_2 IS NOT NULL AND
movi2[i].cod_n = movi2[prow].cod_n AND movi2[i].cod_grupo = movi2[prow].cod_grupo AND
movi2[i].cod_tipo = movi2[prow].cod_tipo AND movi2[i].cod_sec = movi2[prow].cod_sec THEN
LET votros = votros + movi2[i].cantidad_2
END IF
END FOR
IF movi2[prow].cantidad_2 + votros > vpendiente + .01 THEN # .01 = tolerancia de redondeo
LET vmensaje = "La cantidad excede lo pendiente de la orden ", ordenx USING "<<<<<<<<<", ".",
"\nPedido en la orden: ", vpedido USING "<<<,<<<,<<&.&&&&&",
"\nYa despachado: ", vdespachado USING "<<<,<<<,<<&.&&&&&",
"\nPendiente: ", vpendiente USING "<<<,<<<,<<&.&&&&&"
IF votros > 0 THEN
LET vmensaje = vmensaje, "\nEn otras lineas de este documento: ", votros USING "<<<,<<<,<<&.&&&&&"
END IF
LET vmensaje = vmensaje, "\nDigitado: ", movi2[prow].cantidad_2 USING "<<<,<<<,<<&.&&&&&"
CALL fgl_winmessage("CANTIDAD",vmensaje,"stop")
RETURN FALSE
END IF
RETURN TRUE
END FUNCTION
# Despues de grabar un movimiento (dentro de la misma transaccion):
# - Requisicion (pnum_req): DESPACHADA si ya se despacho todo lo pedido en
# ella (cctb00026), si no DESPACHO PARCIAL (cctb00025.estado_despacho).
# - Orden (ordenx): si lo despachado (conduces 30,31,55,56 neto de
# devoluciones 12,13) cubre todo lo pedido (prtb00013), la orden queda
# cerrada = "S" / DESPACHADA y ya no deja despachar mas contra ella.
# - Devoluciones (12/13): la requisicion vuelve a DESPACHO PARCIAL y, si la
# devolucion es parcial, la orden se reabre (cerrada = 'N').
# Portado del ipprmt044 que decomarmol usaba hasta junio 2026.
FUNCTION cierre_orden_requisicion()
DEFINE vpedido_req,vdespachado_req,vpedido,vdespachado,vdif DEC(12,5)
IF pnum_req IS NOT NULL THEN
LET vpedido_req = 0
SELECT ISNULL(SUM(a.cantidad),0) INTO vpedido_req
FROM cctb00026 a
WHERE a.num_req = pnum_req AND a.status_t IS NULL
LET vdespachado_req = 0
SELECT ISNULL(SUM(a.cantidad_2 * -1),0) INTO vdespachado_req
FROM iptb00006 a
WHERE a.num_req = pnum_req AND a.status_t IS NULL
IF vpedido_req - vdespachado_req < .05 THEN
UPDATE cctb00025 SET estado_despacho = 'DESPACHADA',
us_mod = usuarios, fech_mod = getdate()
WHERE num_req = pnum_req
ELSE
UPDATE cctb00025 SET estado_despacho = 'DESPACHO PARCIAL',
us_mod = usuarios, fech_mod = getdate()
WHERE num_req = pnum_req
END IF
END IF
IF ordenx IS NULL THEN
RETURN
END IF
LET vpedido = 0
SELECT ISNULL(SUM(a.cantidad),0) INTO vpedido
FROM prtb00013 a
WHERE a.num_oc = ordenx
LET vdespachado = 0
SELECT ISNULL(SUM(a.cantidad_2 * -1),0) INTO vdespachado
FROM iptb00006 a
WHERE a.num_oc = ordenx
AND a.cod_mov IN (12,13,30,31,55,56)
AND a.status_t IS NULL
LET vdif = vpedido - vdespachado
IF vdif < 0 THEN
LET vdif = vdif * -1
END IF
IF vdif < .05 AND status_m <> 1 THEN
UPDATE prtb00012 SET cerrada = "S",
estado_despacho = 'DESPACHADA',
fecha_cierre = otros_mov.fecha,
us_mod = usuarios, fech_mod = getdate()
WHERE num_oc = ordenx
IF pnum_req IS NOT NULL THEN
UPDATE cctb00025 SET estado_despacho = 'DESPACHADA',
us_mod = usuarios, fech_mod = getdate()
WHERE num_req = pnum_req
END IF
END IF
IF otros_mov.cod_mov = 12 OR otros_mov.cod_mov = 13 THEN
IF pnum_req IS NOT NULL THEN
UPDATE cctb00025 SET estado_despacho = 'DESPACHO PARCIAL',
us_mod = usuarios, fech_mod = getdate()
WHERE num_req = pnum_req AND status_t IS NULL
END IF
IF cantidad_devuelta > vpedido THEN
UPDATE prtb00012 SET estado_devolucion = 'DEVOLUCION COMPLETA',
us_mod = usuarios, fech_mod = getdate()
WHERE num_oc = otros_mov.conduce_no
ELSE
UPDATE prtb00012 SET estado_devolucion = 'DEVOLUCION PARCIAL',
cerrada = 'N',
us_mod = usuarios, fech_mod = getdate()
WHERE num_oc = otros_mov.conduce_no
END IF
END IF
END FUNCTION
# Devuelve el primer renglon cuyo producto lleva despiece (iptb00027) y no
# tiene despiece grabado en iptb00025 para este movimiento/documento; 0 si todos
# estan bien.
FUNCTION falta_despiece()
DEFINE i INTEGER
FOR i = 1 TO movi2.getLength()
IF movi2[i].cod_n IS NULL OR movi2[i].cod_grupo IS NULL OR
movi2[i].cod_tipo IS NULL OR movi2[i].cod_sec IS NULL THEN
CONTINUE FOR
END IF
SELECT UNIQUE a.cod_n FROM iptb00027 a
WHERE a.cod_n = movi2[i].cod_n AND a.cod_grupo = movi2[i].cod_grupo AND
a.cod_tipo = movi2[i].cod_tipo AND a.cod_sec = movi2[i].cod_sec
IF STATUS = NOTFOUND THEN
CONTINUE FOR
END IF
SELECT UNIQUE a.cod_n FROM iptb00025 a
WHERE a.cod_n = movi2[i].cod_n AND a.cod_grupo = movi2[i].cod_grupo AND
a.cod_tipo = movi2[i].cod_tipo AND a.cod_sec = movi2[i].cod_sec AND
a.cod_mov = otros_mov.cod_mov AND a.num_doc = vnum_desp AND a.us_crea = usuarios
IF STATUS = NOTFOUND THEN
RETURN i
END IF
END FOR
RETURN 0
END FUNCTION
# Si el producto del renglon actual (p_act) lleva despiece (iptb00027) y aun no
# tiene despiece en este documento (iptb00025), abre la ventana del despiece.
# Devuelve TRUE si al final el renglon tiene despiece (o no lo necesita).
FUNCTION abre_despiece_si_falta()
IF movi2[p_act].cod_n IS NULL OR movi2[p_act].cod_grupo IS NULL OR
movi2[p_act].cod_tipo IS NULL OR movi2[p_act].cod_sec IS NULL THEN
RETURN TRUE
END IF
SELECT UNIQUE a.cod_n FROM iptb00027 a
WHERE a.cod_n = movi2[p_act].cod_n AND a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND a.cod_sec = movi2[p_act].cod_sec
IF STATUS = NOTFOUND THEN
RETURN TRUE
END IF
SELECT UNIQUE a.cod_n FROM iptb00025 a
WHERE a.cod_n = movi2[p_act].cod_n AND a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND a.cod_sec = movi2[p_act].cod_sec AND
a.cod_mov = otros_mov.cod_mov AND a.num_doc = vnum_desp AND a.us_crea = usuarios
IF STATUS != NOTFOUND THEN
RETURN TRUE
END IF
IF movi2[p_act].area IS NULL THEN
LET movi2[p_act].area = 1
END IF
CALL despiece()
DISPLAY movi2[p_act].cantidad_1 TO s_movi1[scr_l].cantidad_1
SELECT UNIQUE a.cod_n FROM iptb00025 a
WHERE a.cod_n = movi2[p_act].cod_n AND a.cod_grupo = movi2[p_act].cod_grupo AND
a.cod_tipo = movi2[p_act].cod_tipo AND a.cod_sec = movi2[p_act].cod_sec AND
a.cod_mov = otros_mov.cod_mov AND a.num_doc = vnum_desp AND a.us_crea = usuarios
RETURN (STATUS != NOTFOUND)
END FUNCTION