Files
MBS/PROYECTOS/ipdir/ipprcs004.4gl
T

2013 lines
77 KiB
Plaintext

{
-------------------------------------------------------------------------------
PROGRAMA : IPPRCS004
OBJETIVO : Consulta Maestra de Productos con existencia
PROGRAMADOR : Ing. Juan F. Soto
FECHA REALIZACION : Julio 18, 1996.
MODIFICADO POR : Ing. Elvis Garcia
FECHA MODIFICACION : Junio 3, 2024.
-------------------------------------------------------------------------------
}
IMPORT os
GLOBALS "ipprgb000.4gl"
DEFINE bodega1, cod_n, cod_grupo, cod_tipo, cod_sec INT
DEFINE
productos DYNAMIC ARRAY OF RECORD
producto, parent, bodega, ubicacion VARCHAR(255),
existencia DEC(12, 5)
END RECORD,
pperfil SMALLINT,
accesso VARCHAR(2),
exitFlag BOOLEAN
DEFINE prod1 DYNAMIC ARRAY OF RECORD
estado STRING,
cod_n SMALLINT,
cod_grupo SMALLINT,
cod_tipo SMALLINT,
cod_sec SMALLINT,
descrip_esp CHAR(180),
unidad_med LIKE iptb00002.unidad_med,
bodega CHAR(50),
existencia DECIMAL(12, 5),
cantidad_ordenes DEC(12, 5),
disponible DEC(12, 5),
reservado DEC(12, 5),
transito DEC(12, 5),
valorOrden DEC(12, 5),
parent_id, child_id STRING
END RECORD
DEFINE
ubicaciones INT,
load_ubicaciones DYNAMIC ARRAY OF INTEGER,
bodegas DYNAMIC ARRAY OF INTEGER,
## Codigo de bodega indexado por FILA VISIBLE del arbol (arr_curr()),
## a diferencia de bodegas[] que va por ordinal de producto (z).
bodega_fila DYNAMIC ARRAY OF INTEGER
DEFINE prepHijos, prepTree, prepAjuste BOOLEAN
MAIN
DEFER INTERRUPT
CALL ARG_VAL(1) RETURNING usuarios
CALL ARG_VAL(2) RETURNING clave
CALL ARG_VAL(3) RETURNING impresor
CONNECT TO "smarmotech" USER usuarios USING clave
SELECT a.cod_perfil INTO pperfil FROM seg0001 a WHERE a.usuario = usuarios
CALL ipprcs004()
END MAIN
FUNCTION ipprcs004()
DEFINE
pcantidadConduce, pexistencia DEC(12, 5),
codigo_act, codigo_ant VARCHAR(50)
DEFINE i, j, bodegaCont, z INT
DEFINE answer STRING
LET exitFlag = FALSE
INITIALIZE bodega1, cod_n, cod_grupo, cod_tipo, cod_sec TO NULL
OPEN FORM ipfmcs004 FROM "ipfmcs004"
DISPLAY FORM ipfmcs004
CALL ui.Interface.LoadStyles("mbsStyle")
## Aqui se prepara el criterio de seleccion
DIALOG ATTRIBUTES(FIELD ORDER FORM, UNBUFFERED)
INPUT BY NAME datos_cons.fech_fi, inventario
BEFORE INPUT
LET datos_cons.fech_fi = TODAY
CALL prod1.clear()
DISPLAY BY NAME datos_cons.fech_fi
IF datos_cons.fech_fi IS NULL THEN
LET numero_msg = 16
CALL msg(numero_msg)
NEXT FIELD fech_fi
END IF
AFTER INPUT
END INPUT
CONSTRUCT criterio
ON b.bodega,
a.cod_n,
a.cod_grupo,
a.cod_tipo,
a.cod_sec,
a.descrip_esp
FROM bodega, cod_n, cod_grupo, cod_tipo, cod_sec, descrip_esp
BEFORE CONSTRUCT
CALL prod1.clear()
CALL bodegas("1")
ON ACTION Buscar ATTRIBUTES(IMAGE = "find")
IF inventario = "PRODUCTOS TERMINADOS" THEN
LET SELEC =
"SELECT ' ',a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,",
" a.unidad_med,c.descripcion,SUM(b.cantidad_2), ",
" '0','0','0','0',c.cod_bodega ",
"FROM iptb00002 a,iptb00006 b,intb00009 c ",
"WHERE ",
" (a.cod_n = b.cod_n and a.cod_grupo = b.cod_grupo and a.cod_tipo = b.cod_tipo and ",
" a.cod_sec = b.cod_Sec) and b.bodega = c.cod_bodega AND b.status_t is null and ",
" b.fecha < '",
(datos_cons.fech_fi + 1) USING "yyyy-mm-dd",
"' and ",
" a.status_t is null AND ",
criterio CLIPPED,
" GROUP BY c.cod_bodega,a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,a.unidad_med,c.descripcion ",
" ORDER BY c.cod_bodega,a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec "
END IF
IF inventario = "MATERIA PRIMA" THEN
LET SELEC =
"SELECT ' ',a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,",
" a.unidad_med,c.descripcion,SUM(b.cantidad_2) ",
"FROM intb00001 a,intb00006 b,intb00009 c ",
"WHERE ",
" a.cod_n = b.cod_n and a.cod_grupo = b.cod_grupo and a.cod_tipo = b.cod_tipo and ",
" a.cod_sec = b.cod_Sec and b.bodega = c.cod_bodega and ",
" b.fecha < '",
(datos_cons.fech_fi + 1) USING "yyyy-mm-dd",
"' ",
" AND a.status_t is null AND b.status_t is null and ",
criterio CLIPPED,
" GROUP BY a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,a.unidad_med,c.descripcion ",
" ORDER BY cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec "
END IF
PREPARE busca FROM selec
DECLARE accion CURSOR FOR busca
## Busca los registros con la condicion dada y verifica si el producto terminado
## existe en el catalogo de bienes y servicios.
LET idx = 1
LET j = 0
LET z = 1
CALL prod1.clear()
CALL bodegas.clear()
CALL bodega_fila.clear()
CALL load_ubicaciones.clear()
LET codigo_ant = '0'
LET codigo_act = '0'
FOREACH accion INTO prod1[idx].*
LET ubicaciones = 0
LET codigo_act =
prod1[idx].cod_n USING "&&&&&",
prod1[idx].cod_grupo USING "&&&&&",
prod1[idx].cod_tipo USING "&&&&&",
prod1[idx].cod_sec USING "&&&&&&&&"
LET prod1[idx].estado = NULL
SELECT UNIQUE a.cod_sec
FROM iptb00050 a
WHERE a.cod_n = prod1[idx].cod_n
AND a.cod_grupo = prod1[idx].cod_grupo
AND a.cod_tipo = prod1[idx].cod_tipo
AND a.cod_sec = prod1[idx].cod_sec
IF STATUS <> NOTFOUND THEN
LET prod1[idx].estado = "information.png"
END IF
IF prod1[idx].existencia IS NULL THEN
LET prod1[idx].existencia = 0
END IF
LET prod1[idx].cantidad_ordenes = 0
IF codigo_ant <> codigo_act THEN
LET codigo_ant =
prod1[idx].cod_n USING "&&&&",
prod1[idx].cod_grupo USING "&&&&",
prod1[idx].cod_tipo USING "&&&&",
prod1[idx].cod_sec USING "&&&&&&"
CALL disponibles(
prod1[idx].cod_n,
prod1[idx].cod_grupo,
prod1[idx].cod_tipo,
prod1[idx].cod_sec,
datos_cons.fech_fi)
RETURNING prod1[idx].cantidad_ordenes,
pcantidadConduce,
prod1[idx].transito,
pexistencia,
prod1[idx].reservado,
prod1[idx].valorOrden
LET prod1[idx].cantidad_ordenes =
prod1[idx].cantidad_ordenes - pcantidadConduce
IF prod1[idx].cantidad_ordenes = 0 THEN
LET prod1[idx].valorOrden = 0
END IF
END IF
IF prod1[idx].existencia IS NULL THEN
LET prod1[idx].existencia = 0
END IF
IF prod1[idx].cantidad_ordenes IS NULL THEN
LET prod11[idx].cantidad_ordenes = 0
END IF
IF prod1[idx].disponible IS NULL THEN
LET prod1[idx].disponible = 0
END IF
LET prod1[idx].disponible =
pexistencia
- prod1[idx].cantidad_ordenes
- prod1[idx].reservado
LET productos[idx].producto =
prod1[idx].cod_n USING "&&&&",
prod1[idx].cod_grupo USING "&&&&",
prod1[idx].cod_tipo USING "&&&&",
prod1[idx].cod_sec USING "&&&&&&",
" ",
prod1[idx].descrip_esp
LET productos[idx].bodega = prod1[idx].bodega
LET productos[idx].existencia = prod1[idx].existencia
LET productos[idx].parent = prod1[idx].bodega
CALL LlenarHijos(
prod1[idx].*)
RETURNING bodegaCont, ubicaciones
LET bodegas[z] = bodegacont
LET bodega_fila[idx] = bodegacont
LET load_ubicaciones[z] = ubicaciones
LET z = z + 1
LET INT_FLAG = FALSE
IF ubicaciones > 0 THEN
LET j = idx + 1
LET INT_FLAG = TRUE
LET prod1[idx].parent_id = NULL
LET prod1[idx].child_id = 1
CALL treeFunction(
j,
prod1[idx].cod_n,
prod1[idx].cod_grupo,
prod1[idx].cod_tipo,
prod1[idx].cod_sec,
bodegaCont,
prod1[idx].existencia)
RETURNING j
END IF
IF INT_FLAG THEN
LET idx = j
ELSE
LET idx = idx + 1
END IF
INITIALIZE ubicaciones TO NULL
END FOREACH
IF idx = 1 THEN
CALL msg(3)
DISPLAY criterio
LET bodega1 = extract_value(criterio, "b.bodega")
LET cod_n = extract_value(criterio, "a.cod_n")
LET cod_grupo = extract_value(criterio, "a.cod_grupo")
LET cod_tipo = extract_value(criterio, "a.cod_tipo")
LET cod_sec = extract_value(criterio, "a.cod_sec")
DISPLAY 'bodega: ', bodega1
DISPLAY 'cod_n: ', cod_n
DISPLAY 'cod_grupo: ', cod_grupo
DISPLAY 'cod_tipo: ', cod_tipo
DISPLAY 'cod_sec: ', cod_sec
IF bodega1 IS NOT NULL
AND cod_n IS NOT NULL
AND cod_grupo IS NOT NULL
AND cod_tipo IS NOT NULL
AND cod_sec IS NOT NULL THEN
SELECT UNIQUE a.cod_grupo
FROM iptb00006 a
WHERE a.cod_n = cod_n
AND a.cod_grupo = cod_grupo
AND a.cod_tipo = cod_tipo
AND a.cod_sec = cod_sec
AND a.status_t IS NULL
IF STATUS <> NOTFOUND THEN
LET answer =
fgl_winquestion(
'PRODUCTO NO DISPONIBLE EN SU BODEGA',
"Este producto no se encuentra en su bodega, desea adicionarlo sin existencia?",
"yes",
"yes|no",
"question",
0)
IF answer = 'yes' THEN
TRY
BEGIN WORK
INSERT INTO iptb00006(
cod_cia,
num_doc,
fecha,
cod_mov,
detalle,
area,
cod_n,
cod_grupo,
cod_tipo,
cod_sec,
cantidad_1,
cantidad_2,
bodega,
status_t,
us_crea,
fech_crea,
us_mod,
fech_mod)
VALUES(1,
99,
getdate(),
99,
NULL,
NULL,
cod_n,
cod_grupo,
cod_tipo,
cod_sec,
0,
0,
bodega1,
NULL,
usuarios,
getdate(),
NULL,
NULL)
INSERT INTO iptb00062(
num_doc,
fecha,
area,
cod_n,
cod_grupo,
cod_tipo,
cod_sec,
cod_mov,
bodega,
cod_seccion,
cod_tramo,
cod_fila,
cod_pos,
cantidad,
cantidad2,
status_t,
us_crea,
fech_crea,
us_mod,
fech_mod)
VALUES(99,
getdate(),
NULL,
cod_n,
cod_grupo,
cod_tipo,
cod_sec,
99,
bodega1,
0,
0,
0,
0,
0,
0,
NULL,
usuarios,
getdate(),
NULL,
NULL)
COMMIT WORK
LET numero_msg = 1
CALL msg(numero_msg)
CONTINUE DIALOG
CATCH
ROLLBACK WORK
LET numero_msg = 1663
CALL msg(numero_msg)
END TRY
ELSE
CONTINUE DIALOG
END IF
END IF
END IF
CONTINUE DIALOG
END IF
DISPLAY ARRAY prod1 TO consart.*
ON ACTION ordenDisponible
IF prod1[arr_curr()].cantidad_ordenes <> 0 THEN
CALL busca_ordenes_reservadas(
prod1[arr_curr()].cod_n,
prod1[arr_curr()].cod_grupo,
prod1[arr_curr()].cod_tipo,
prod1[arr_curr()].cod_sec)
ELSE
CALL fgl_winmessage(
"INFO",
"PRODUCTO NO TIENE ORDENES COLOCADAS",
"INFO")
END IF
ON ACTION reservado
LET idx = arr_curr()
IF prod1[idx].reservado > 0 THEN
CALL busca_reservas(
prod1[idx].cod_n,
prod1[idx].cod_grupo,
prod1[idx].cod_tipo,
prod1[idx].cod_sec)
ELSE
CALL fgl_winmessage(
"ERROR",
"PRODUCTO NO TIENE CANTIDAD RESERVADA",
"INFO")
END IF
{ ON ACTION foto
LET idx = arr_curr()
CALL fotos(prod1[idx].cod_n,prod1[idx].cod_grupo,prod1[idx].cod_tipo,
prod1[idx].cod_sec,prod1[idx].descrip_esp,usuarios,true)
LET prod1[idx].estado = " "
SELECT UNIQUE a.cod_sec FROM iptb00050 a
WHERE a.cod_n = prod1[idx].cod_n AND
a.cod_grupo = prod1[idx].cod_grupo AND
a.cod_tipo = prod1[idx].cod_tipo AND
a.cod_sec = prod1[idx].cod_sec
IF STATUS <> NOTFOUND THEN
LET prod1[idx].estado = "information.png"
END IF
DISPLAY prod1[idx].estado TO consart[scr_line()].estado}
ON ACTION imprime
ATTRIBUTE(TEXT = "Reporte", IMAGE = 'print')
CALL seg000(
usuarios, pperfil, 'reporte.ipprcs004')
RETURNING accesso
DISPLAY "usuario ", usuarios, " ", pperfil
IF accesso = "SI" THEN
CALL reporteData()
ELSE
CALL msg(503)
END IF
ON ACTION ubicar
SELECT a.usuario
FROM seg0001 a, seg0005 b
WHERE a.usuario = usuarios
AND a.cod_perfil = b.cod_perfil
AND b.programa = 'ipprcs004.ubicacion'
IF STATUS = NOTFOUND THEN
CALL fgl_winmessage(
"ERROR",
"USTED NO TIENE PERMISOS PARA UTILIZAR OPCION",
"INFO")
CONTINUE DIALOG
ELSE
SELECT UNIQUE a.usuario
FROM iptb00048 a
WHERE a.bodega = bodegas[arr_curr()]
AND a.usuario = usuarios
IF STATUS = NOTFOUND THEN
CALL msg(503)
ELSE
IF load_ubicaciones[arr_curr()] > 0 THEN
CALL InsertaUbicacionDH(
prod1[arr_curr()].*, NULL)
RETURNING exitFlag
ELSE
CALL colocar_ubicacion(prod1[arr_curr()].*)
IF prod1[arr_curr()].estado IS NOT NULL
AND prod1[arr_curr()]
.bodega IS NULL THEN
LET INT_FLAG = TRUE
LET i = 1
WHILE INT_FLAG
IF prod1[arr_curr() - i]
.cod_n IS NOT NULL THEN
CALL InsertaUbicacionDH(
prod1[arr_curr() - i].*,
prod1[arr_curr()].estado)
RETURNING exitFlag
LET INT_FLAG = FALSE
ELSE
LET i = i + 1
END IF
END WHILE
END IF
END IF
IF exitFlag THEN
LET idx = 1
LET j = 0
LET z = 1
CALL prod1.clear()
CALL bodegas.clear()
CALL bodega_fila.clear()
CALL load_ubicaciones.clear()
LET codigo_ant = '0'
LET codigo_act = '0'
FOREACH accion INTO prod1[idx].*,bodegas[idx]
LET ubicaciones = 0
LET codigo_act =
prod1[idx].cod_n USING "&&&&&",
prod1[idx].cod_grupo USING "&&&&&",
prod1[idx].cod_tipo USING "&&&&&",
prod1[idx].cod_sec USING "&&&&&&&&"
LET prod1[idx].estado = NULL
SELECT UNIQUE a.cod_sec
FROM iptb00050 a
WHERE a.cod_n = prod1[idx].cod_n
AND a.cod_grupo
=
prod1[idx].cod_grupo
AND a.cod_tipo
=
prod1[idx].cod_tipo
AND a.cod_sec
=
prod1[idx].cod_sec
IF STATUS <> NOTFOUND THEN
LET prod1[idx].estado =
"information.png"
END IF
IF prod1[idx].existencia IS NULL THEN
LET prod1[idx].existencia = 0
END IF
LET prod1[idx].cantidad_ordenes = 0
IF codigo_ant <> codigo_act THEN
LET codigo_ant =
prod1[idx].cod_n USING "&&&&",
prod1[idx].cod_grupo
USING "&&&&",
prod1[idx].cod_tipo
USING "&&&&",
prod1[idx].cod_sec
USING "&&&&&&"
CALL disponibles(
prod1[idx].cod_n,
prod1[idx].cod_grupo,
prod1[idx].cod_tipo,
prod1[idx].cod_sec,
datos_cons.fech_fi)
RETURNING prod1[idx]
.cantidad_ordenes,
pcantidadConduce,
prod1[idx].transito,
pexistencia,
prod1[idx].reservado,
prod1[idx].valorOrden
LET prod1[idx].cantidad_ordenes =
prod1[idx].cantidad_ordenes
- pcantidadConduce
IF prod1[idx].cantidad_ordenes
= 0 THEN
LET prod1[idx].valorOrden = 0
END IF
END IF
IF prod1[idx].existencia IS NULL THEN
LET prod1[idx].existencia = 0
END IF
IF prod1[idx]
.cantidad_ordenes IS NULL THEN
LET prod11[idx].cantidad_ordenes = 0
END IF
IF prod1[idx].disponible IS NULL THEN
LET prod1[idx].disponible = 0
END IF
LET prod1[idx].disponible =
pexistencia
- prod1[idx].cantidad_ordenes
- prod1[idx].reservado
LET productos[idx].producto =
prod1[idx].cod_n USING "&&&&",
prod1[idx].cod_grupo USING "&&&&",
prod1[idx].cod_tipo USING "&&&&",
prod1[idx].cod_sec USING "&&&&&&",
" ",
prod1[idx].descrip_esp
LET productos[idx].bodega =
prod1[idx].bodega
LET productos[idx].existencia =
prod1[idx].existencia
LET productos[idx].parent =
prod1[idx].bodega
CALL LlenarHijos(
prod1[idx].*)
RETURNING bodegaCont, ubicaciones
LET bodegas[z] = bodegacont
LET bodega_fila[idx] = bodegacont
LET load_ubicaciones[z] = ubicaciones
LET z = z + 1
LET INT_FLAG = FALSE
IF ubicaciones > 0 THEN
LET j = idx + 1
LET INT_FLAG = TRUE
LET prod1[idx].parent_id = NULL
LET prod1[idx].child_id = 1
CALL treeFunction(
j,
prod1[idx].cod_n,
prod1[idx].cod_grupo,
prod1[idx].cod_tipo,
prod1[idx].cod_sec,
bodegaCont,
prod1[idx].existencia)
RETURNING j
END IF
IF INT_FLAG THEN
LET idx = j
ELSE
LET idx = idx + 1
END IF
INITIALIZE ubicaciones TO NULL
END FOREACH
IF idx = 1 THEN
CALL msg(3)
CONTINUE DIALOG
END IF
END IF
END IF
END IF
ON ACTION ajustar
ATTRIBUTES(TEXT = "Ajustar Ubic.", IMAGE = "edit")
LET idx = arr_curr()
## El ajuste solo aplica sobre una fila de producto/bodega.
## Las filas del arbol de ubicaciones tienen cod_n NULL.
IF prod1[idx].cod_n IS NULL
OR prod1[idx].bodega IS NULL THEN
CALL fgl_winmessage(
"INFO",
"Seleccione un producto (fila de bodega) para ajustar sus ubicaciones.",
"info")
CONTINUE DISPLAY
END IF
## Mismo control de permiso que la opcion de ubicar.
SELECT a.usuario
FROM seg0001 a, seg0005 b
WHERE a.usuario = usuarios
AND a.cod_perfil = b.cod_perfil
AND b.programa = 'ipprcs004.ubicacion'
IF STATUS = NOTFOUND THEN
CALL fgl_winmessage(
"ERROR",
"USTED NO TIENE PERMISOS PARA UTILIZAR OPCION",
"INFO")
CONTINUE DISPLAY
END IF
IF ajustar_ubicaciones(
prod1[idx].cod_n,
prod1[idx].cod_grupo,
prod1[idx].cod_tipo,
prod1[idx].cod_sec,
bodega_fila[idx],
prod1[idx].bodega,
prod1[idx].descrip_esp,
prod1[idx].existencia) THEN
## Se aplico el ajuste: refrescar el arbol en pantalla.
CALL recargar_arbol()
END IF
AFTER DISPLAY
CALL prod1.clear()
END DISPLAY
END CONSTRUCT
ON ACTION CANCEL ATTRIBUTES(TEXT = "Cancelar", IMAGE = "cancel")
CALL prod1.clear()
CALL msg(2)
LET INT_FLAG = FALSE
EXIT PROGRAM
END DIALOG
END FUNCTION
FUNCTION LlenarHijos(prod1)
DEFINE
prod1 RECORD
estado VARCHAR(20),
cod_n SMALLINT,
cod_grupo SMALLINT,
cod_tipo SMALLINT,
cod_sec SMALLINT,
descrip_esp CHAR(180),
unidad_med LIKE iptb00002.unidad_med,
bodega CHAR(50),
existencia DECIMAL(12, 5),
cantidad_ordenes DEC(12, 5),
disponible DEC(12, 5),
reservado DEC(12, 5),
transito DEC(12, 5),
valorOrden DEC(16, 5),
parent_id, child_id VARCHAR(20)
END RECORD,
bodegaCont, checking INT,
Query STRING
## Los statements se preparan una sola vez por ejecucion del programa,
## no en cada fila (antes se hacia PREPARE por cada producto).
IF NOT prepHijos THEN
LET query =
"SELECT DISTINCT a.cod_bodega
FROM intb00009 a INNER JOIN iptb00006 b ON a.cod_bodega = b.bodega
WHERE cod_n = ?
AND cod_grupo = ?
AND cod_tipo = ?
AND cod_sec = ?
AND a.descripcion = ?"
PREPARE busqueda1 FROM query
LET query =
"SELECT COUNT(cod_seccion)
FROM iptb00062
WHERE cod_n = ?
AND cod_grupo = ?
AND cod_tipo = ?
AND cod_sec = ?
AND bodega = ? "
PREPARE busqueda2 FROM query
LET prepHijos = TRUE
END IF
EXECUTE busqueda1
USING prod1.cod_n,
prod1.cod_grupo,
prod1.cod_tipo,
prod1.cod_sec,
prod1.bodega
INTO bodegaCont
EXECUTE busqueda2
USING prod1.cod_n,
prod1.cod_grupo,
prod1.cod_tipo,
prod1.cod_sec,
bodegaCont
INTO checking
RETURN bodegaCont, checking
END FUNCTION
FUNCTION treeFunction(
j INT,
cod_n1 INT,
cod_grupo1 INT,
cod_tipo1 INT,
cod_sec1 INT,
bodegaCont INT,
existencia DECIMAL(12, 5))
DEFINE MirrorLocation DYNAMIC ARRAY OF RECORD
seccion STRING,
cod_seccion INT,
existenciaSec DECIMAL(12, 5),
tramo STRING,
cod_tramo INT,
existenciaTram DECIMAL(12, 5),
fila STRING,
cod_fila INT,
existenciaFil DECIMAL(12, 5),
posicion STRING,
cod_pos INT,
existenciaPos DECIMAL(12, 5)
END RECORD
DEFINE Container DYNAMIC ARRAY OF RECORD
seccion STRING,
cod_seccion INT,
existenciaSec DECIMAL(12, 5),
tramo STRING,
cod_tramo INT,
existenciaTram DECIMAL(12, 5),
fila STRING,
cod_fila INT,
existenciaFil DECIMAL(12, 5),
posicion STRING,
cod_pos INT,
existenciaPos DECIMAL(12, 5)
END RECORD
DEFINE i, z INT
CONSTANT firstID = 1
DEFINE counterSec, counterTram, counterFil, counterPos INT
DEFINE NextTree, NextTree2 BOOLEAN
DEFINE consulta STRING
LET i = 1
LET counterSec = 2
LET counterTram = 1
LET counterFil = 1
LET counterPos = 1
LET nextTree = FALSE
LET nextTree2 = FALSE
INITIALIZE MirrorLocation TO NULL
LET consulta =
"SELECT
RTRIM(a.descripcion) AS seccion,
a.cod_seccion as cod_seccion,
(SELECT SUM(cantidad2)
FROM iptb00062
WHERE (bodega = t.bodega AND cod_seccion = t.cod_seccion and cod_n = t.cod_n and cod_grupo = t.cod_grupo and cod_tipo = t.cod_tipo and cod_sec = t.cod_sec) and status_t is null) AS suma_cantidad2_seccion,
RTRIM(b.descripcion) AS tramo,
b.cod_tramo as cod_tramo,
(SELECT SUM(cantidad2)
FROM iptb00062
WHERE (bodega = t.bodega AND cod_seccion = t.cod_seccion AND cod_tramo = t.cod_tramo and cod_n = t.cod_n and cod_grupo = t.cod_grupo and cod_tipo = t.cod_tipo and cod_sec = t.cod_sec) and status_t is null) AS suma_cantidad2_tramo,
RTRIM(c.titulo) AS fila,
c.cod_fila as cod_fila,
(SELECT SUM(cantidad2)
FROM iptb00062
WHERE (bodega = t.bodega AND cod_seccion = t.cod_seccion AND cod_tramo = t.cod_tramo AND cod_fila = t.cod_fila and cod_n = t.cod_n and cod_grupo = t.cod_grupo and cod_tipo = t.cod_tipo and cod_sec = t.cod_sec) and status_t is null) AS suma_cantidad2_fila,
RTRIM(d.titulo) AS posicion,
d.cod_pos as cod_pos,
(SELECT SUM(cantidad2)
FROM iptb00062
WHERE (bodega = t.bodega AND cod_seccion = t.cod_seccion AND cod_tramo = t.cod_tramo AND cod_fila = t.cod_fila AND cod_pos = t.cod_pos and cod_n = t.cod_n and cod_grupo = t.cod_grupo and cod_tipo = t.cod_tipo and cod_sec = t.cod_sec) and status_t is null) AS suma_cantidad2_pos
FROM
iptb00062 t
INNER JOIN intb00010 a ON t.bodega = a.cod_bodega AND t.cod_seccion = a.cod_seccion
INNER JOIN intb00043 b ON t.bodega = b.cod_bodega AND t.cod_seccion = b.cod_seccion AND t.cod_tramo = b.cod_tramo
INNER JOIN intb00045 c ON t.bodega = c.cod_bodega AND t.cod_seccion = c.cod_seccion AND t.cod_tramo = c.cod_tramo AND t.cod_fila = c.cod_fila
INNER JOIN intb00046 d ON t.bodega = d.cod_bodega AND t.cod_seccion = d.cod_seccion AND t.cod_tramo = d.cod_tramo AND t.cod_fila = d.cod_fila AND t.cod_pos = d.cod_pos
WHERE
(t.bodega = ? AND t.cod_n = ? AND t.cod_grupo = ? AND t.cod_tipo = ? AND t.cod_sec = ? AND t.status_t IS NULL)
GROUP BY
t.cod_seccion, t.cod_tramo, t.cod_fila, t.cod_pos, a.cod_seccion, a.descripcion, b.cod_tramo, b.descripcion, c.cod_fila, c.titulo, d.cod_pos, d.titulo, t.bodega, t.cod_n, t.cod_grupo, t.cod_tipo, t.cod_sec
ORDER BY
t.cod_seccion, t.cod_tramo, t.cod_fila, t.cod_pos;"
## El statement se prepara y el cursor se declara una sola vez;
## los codigos se pasan por parametro (USING) en cada llamada.
IF NOT prepTree THEN
PREPARE treestmt FROM consulta
DECLARE query CURSOR FOR treestmt
LET prepTree = TRUE
END IF
LET i = 2
LET z = 1
FOREACH query USING bodegaCont, cod_n1, cod_grupo1, cod_tipo1, cod_sec1 INTO Container[z].*
{IF container[z].existenciaSec <> 0
AND container[z].existenciaTram <> 0
AND container[z].existenciaFil <> 0
AND container[z].existenciaPos <> 0 THEN}
LET MirrorLocation[i] = Container[z]
LET i = i + 1
{END IF}
LET z = z + 1
END FOREACH
LET i = 2
IF MirrorLocation.getLength() > 0 THEN
LET prod1[j].descrip_esp = " UBICACIONES "
LET prod1[j].parent_id = firstID
LET prod1[j].child_id = firstID || "." || firstID
LET j = j + 1
END IF
WHILE i <= mirrorLocation.getLength()
IF mirrorLocation[i].seccion = mirrorLocation[i - 1].seccion THEN
IF mirrorLocation[i].tramo = mirrorLocation[i - 1].tramo THEN
IF mirrorLocation[i].fila = mirrorLocation[i - 1].fila THEN
IF mirrorLocation[i].posicion
= mirrorLocation[i - 1].posicion THEN
DISPLAY "nothing happened" --se supone que gracias al
--query esto nunca saldr
ELSE
LET counterPos = counterPos + 1
LET prod1[j].estado =
mirrorLocation[i].seccion
|| " | "
|| mirrorLocation[i].cod_seccion,
" | " || mirrorLocation[i].cod_tramo,
" | " || mirrorLocation[i].cod_fila,
" | " || mirrorLocation[i].cod_pos
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].posicion,
" || Existencia:",
mirrorLocation[i].existenciaPos
LET prod1[j].parent_id =
firstID
|| "."
|| counterSec
|| "."
|| counterTram
|| "."
|| counterFil
LET prod1[j].child_id =
firstID
|| "."
|| counterSec
|| "."
|| counterTram
|| "."
|| counterFil
|| "."
|| counterPos
LET NextTree = TRUE
END IF
ELSE
IF nextTree = TRUE THEN
LET counterPos = 1
LET nextTree = FALSE
END IF
LET counterFil = counterFil + 1
LET prod1[j].estado =
mirrorLocation[i].seccion
|| " | "
|| mirrorLocation[i].cod_seccion
|| " | "
|| mirrorLocation[i].cod_tramo
|| " | "
|| mirrorLocation[i].cod_fila
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].fila,
" || Existencia:",
mirrorLocation[i].existenciaFil
LET prod1[j].parent_id =
firstID || "." || counterSec || "." || counterTram
LET prod1[j].child_id =
firstID
|| "."
|| counterSec
|| "."
|| counterTram
|| "."
|| counterFil
LET j = j + 1
LET prod1[j].estado =
prod1[j - 1].estado
|| " | "
|| mirrorLocation[i].cod_pos
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].posicion,
" || Existencia:",
mirrorLocation[i].existenciapos
LET prod1[j].parent_id = prod1[j - 1].child_id
LET prod1[j].child_id =
prod1[j - 1].child_id || "." || counterPos
LET nextTree2 = TRUE
END IF
ELSE
IF nextTree2 THEN
LET counterPos = 1
LET counterFil = 1
LET nextTree2 = FALSE
END IF
LET counterTram = counterTram + 1
LET prod1[j].estado =
mirrorLocation[i].seccion
|| " | "
|| mirrorLocation[i].cod_seccion
|| " | "
|| mirrorLocation[i].cod_tramo
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].tramo,
" || Existencia:",
mirrorLocation[i].existenciatram
LET prod1[j].parent_id = firstID || "." || counterSec
LET prod1[j].child_id =
firstID || "." || counterSec || "." || counterTram
LET j = j + 1
LET prod1[j].estado =
prod1[j - 1].estado || " | " || mirrorlocation[i].cod_fila
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].fila,
" || Existencia:",
mirrorLocation[i].existenciafil
LET prod1[j].parent_id = prod1[j - 1].child_id
LET prod1[j].child_id =
prod1[j - 1].child_id || "." || counterFil
LET j = j + 1
LET prod1[j].estado =
prod1[j - 1].estado || " | " || mirrorLocation[i].cod_pos
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].posicion,
" || Existencia:",
mirrorLocation[i].existenciapos
LET prod1[j].parent_id = prod1[j - 1].child_id
LET prod1[j].child_id =
prod1[j - 1].child_id || "." || counterPos
END IF
ELSE
LET counterSec = counterSec + 1
LET prod1[j].estado =
mirrorLocation[i].seccion
|| " | "
|| mirrorLocation[i].cod_seccion
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].seccion,
" || Existencia:",
mirrorLocation[i].existenciaSec
LET prod1[j].parent_id = firstID
LET prod1[j].child_id = firstID || "." || counterSec
LET j = j + 1
LET prod1[j].estado =
prod1[j - 1].estado || " | " || mirrorLocation[i].cod_tramo
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].tramo,
" || Existencia:",
mirrorLocation[i].existenciatram
LET prod1[j].parent_id = prod1[j - 1].child_id
LET prod1[j].child_id = prod1[j - 1].child_id || "." || firstID
LET j = j + 1
LET prod1[j].estado =
prod1[j - 1].estado || " | " || mirrorLocation[i].cod_fila
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].fila,
" || Existencia:",
mirrorLocation[i].existenciaFil
LET prod1[j].parent_id = prod1[j - 1].child_id
LET prod1[j].child_id = prod1[j - 1].child_id || "." || firstID
LET j = j + 1
LET prod1[j].estado =
prod1[j - 1].estado || " | " || mirrorLocation[i].cod_pos
LET prod1[j].descrip_esp =
" ",
mirrorLocation[i].posicion,
" || Existencia:",
mirrorLocation[i].existenciaPos
LET prod1[j].parent_id = prod1[j - 1].child_id
LET prod1[j].child_id = prod1[j - 1].child_id || "." || firstID
LET counterTram = 1
LET counterFil = 1
LET counterPos = 1
END IF
LET j = j + 1
LET i = i + 1
END WHILE
RETURN j
END FUNCTION
FUNCTION colocar_ubicacion(producto)
DEFINE producto RECORD
estado STRING,
cod_n SMALLINT,
cod_grupo SMALLINT,
cod_tipo SMALLINT,
cod_sec SMALLINT,
descrip_esp CHAR(180),
unidad_med LIKE iptb00002.unidad_med,
bodega CHAR(50),
existencia DECIMAL(12, 5),
cantidad_ordenes DEC(12, 5),
disponible DEC(12, 5),
reservado DEC(12, 5),
transito DEC(12, 5),
valorOrden DEC(12, 5),
parent_id, child_id STRING
END RECORD
DEFINE
answer, query STRING,
codigo_bodega INT
LET answer =
fgl_winquestion(
'COLOCAR UBICACION',
"Este Item no tiene ubicacion, desea colocar una ubicacion default?",
"yes",
"yes|no",
"question",
0)
PREPARE query3
FROM "SELECT cod_bodega FROM intb00009 WHERE descripcion = rtrim(?) AND status_t IS null "
EXECUTE query3 USING producto.bodega INTO codigo_bodega
PREPARE query4
FROM "Select sum(cantidad_1), sum(cantidad_2) FROM iptb00006 where cod_n = ? and cod_grupo = ? and cod_tipo = ?
and cod_sec = ? and bodega = ? and status_t is null"
LET producto.cantidad_ordenes = 0
LET producto.existencia = 0
EXECUTE query4
USING producto.cod_n,
producto.cod_grupo,
producto.cod_tipo,
producto.cod_sec,
codigo_bodega
INTO producto.cantidad_ordenes, producto.existencia
IF answer = "yes" THEN
INSERT INTO iptb00062(
num_doc,
fecha,
area,
cod_n,
cod_grupo,
cod_tipo,
cod_sec,
cod_mov,
bodega,
cod_seccion,
cod_tramo,
cod_fila,
cod_pos,
cantidad,
cantidad2,
status_t,
us_crea,
fech_crea,
us_mod,
fech_mod)
VALUES(99,
getdate(),
NULL,
producto.cod_n,
producto.cod_grupo,
producto.cod_tipo,
producto.cod_sec,
99,
codigo_bodega,
0,
0,
0,
0,
producto.cantidad_ordenes,
producto.existencia,
NULL,
usuarios,
getdate(),
NULL,
NULL)
CALL fgl_winmessage(" ", "UBICACION ASIGNADA.", "info")
END IF
{DEJO ESTO COMENTADO EN CASO DE QUE QUERRAMOS HACER UN BOTON PARA
QUE LOS USUARIOS PUEDAN COLOCAR UBICACION A PRODUCTOS QUE NO TIENEN
DEFINE seccion, tramo, fila, posicion INT
DEFINE descripcion STRING
LET descripcion = producto.cod_n USING "<<<&",
"-",producto.cod_grupo USING "<<<<&",
"-",producto.cod_tipo USING "<<<<&",
"-",producto.cod_sec USING "<<<<&"
LET descripcion = producto.descrip_esp CLIPPED,"-(",descripcion CLIPPED,")"
OPEN WINDOW w1 WITH FORM "coloca_ubicacion"
DIALOG ATTRIBUTE(UNBUFFERED)
INPUT BY NAME seccion,tramo,fila,posicion, producto.can ATTRIBUTES(WITHOUT DEFAULTS)
BEFORE INPUT
CALL init_seccion(producto.bodega)
LET seccion = 0, tramo = 0, fila = 0, posicion = 0
ON CHANGE seccion
CALL init_tramo(producto.bodega, seccion)
ON CHANGE tramo
CALL init_fila(
producto.bodega,
seccion,
tramo)
ON CHANGE fila
CALL init_posicion(
producto.bodega,
seccion,
tramo,
fila)
END INPUT
END DIALOG
CLOSE WINDOW w1 }
END FUNCTION
################################################################################
## Ajuste de existencia en ubicaciones (iptb00062).
## La existencia real la tiene iptb00006. Esta funcion NO toca iptb00006:
## permite cuadrar el total de las ubicaciones del item en la bodega contra la
## existencia real, insertando en iptb00062 SOLO la diferencia por ubicacion,
## con cod_mov = 99 (existencia inicial). Asi no se adiciona existencia al item.
################################################################################
FUNCTION ajustar_ubicaciones(
p_cod_n,
p_cod_grupo,
p_cod_tipo,
p_cod_sec,
p_cod_bodega,
p_bodega_nombre,
p_descrip,
p_existencia_real)
DEFINE
p_cod_n, p_cod_grupo, p_cod_tipo, p_cod_sec INTEGER,
p_bodega_nombre CHAR(50),
p_descrip CHAR(180),
p_existencia_real DECIMAL(12, 5),
p_cod_bodega INTEGER,
k INTEGER,
total_corr DECIMAL(12, 5),
p_factor DECIMAL(12, 5),
guardado, hay_real BOOLEAN,
def_sec, def_tra, def_fila, def_pos INTEGER,
d_sec, d_tra, d_fila, d_pos VARCHAR(100),
p_codigo_str, p_desc_str, msg_txt, q STRING
## unidades = iptb00062.cantidad (lo que digita el usuario)
## existencia= iptb00062.cantidad2 (= unidades * factor_conv de iptb00001)
DEFINE loc DYNAMIC ARRAY OF RECORD
cod_seccion, cod_tramo, cod_fila, cod_pos INTEGER,
desc_seccion, desc_tramo, desc_fila, desc_pos VARCHAR(100),
existencia_act DECIMAL(12, 5),
unidades_act DECIMAL(12, 5),
unidades DECIMAL(12, 5),
existencia DECIMAL(12, 5)
END RECORD
LET guardado = FALSE
IF p_existencia_real IS NULL THEN
LET p_existencia_real = 0
END IF
## El codigo de bodega viene del arreglo bodegas[] (ya calculado por
## LlenarHijos, igual que lo usa la opcion 'Ubicar'). Solo como respaldo,
## si no viniera, se resuelve por la descripcion.
DISPLAY "Dato Bodega: ",p_cod_bodega
IF p_cod_bodega IS NULL OR p_cod_bodega <= 0 THEN
SELECT cod_bodega
INTO p_cod_bodega
FROM intb00009
WHERE descripcion = RTRIM(p_cod_bodega)
AND status_t IS NULL
END IF
IF p_cod_bodega IS NULL THEN
CALL fgl_winmessage(
"ERROR", "No se pudo determinar la bodega del producto.", "stop")
RETURN FALSE
END IF
## El usuario debe tener acceso a la bodega (igual que la opcion de ubicar).
SELECT UNIQUE a.usuario
FROM iptb00048 a
WHERE a.bodega = p_cod_bodega
AND a.usuario = usuarios
IF STATUS = NOTFOUND THEN
CALL msg(503)
RETURN FALSE
END IF
## Factor de conversion del item (unidades -> existencia), igual que
## usa BuscarData/InsertaUbicacionDH: existencia = unidades * factor.
LET p_factor = NULL
SELECT factor_conv
INTO p_factor
FROM iptb00001
WHERE cod_n = p_cod_n
AND cod_grupo = p_cod_grupo
AND cod_tipo = p_cod_tipo
AND cod_sec = p_cod_sec
AND status_t IS NULL
IF p_factor IS NULL OR p_factor = 0 THEN
LET p_factor = 1
END IF
## Cargar TODAS las ubicaciones del item en la bodega (LEFT JOIN para que
## tambien aparezcan las filas placeholder 0/0/0/0 sin descripcion, y asi
## el total refleje realmente SUM(cantidad2) de iptb00062).
IF NOT prepAjuste THEN
LET q =
"SELECT t.cod_seccion, t.cod_tramo, t.cod_fila, t.cod_pos,",
" RTRIM(a.descripcion), RTRIM(b.descripcion), RTRIM(c.titulo), RTRIM(d.titulo),",
" ISNULL(SUM(t.cantidad2),0), ISNULL(SUM(t.cantidad),0)",
" FROM iptb00062 t",
" LEFT JOIN intb00010 a ON t.bodega=a.cod_bodega AND t.cod_seccion=a.cod_seccion",
" LEFT JOIN intb00043 b ON t.bodega=b.cod_bodega AND t.cod_seccion=b.cod_seccion AND t.cod_tramo=b.cod_tramo",
" LEFT JOIN intb00045 c ON t.bodega=c.cod_bodega AND t.cod_seccion=c.cod_seccion AND t.cod_tramo=c.cod_tramo AND t.cod_fila=c.cod_fila",
" LEFT JOIN intb00046 d ON t.bodega=d.cod_bodega AND t.cod_seccion=d.cod_seccion AND t.cod_tramo=d.cod_tramo AND t.cod_fila=d.cod_fila AND t.cod_pos=d.cod_pos",
" WHERE t.bodega=? AND t.cod_n=? AND t.cod_grupo=? AND t.cod_tipo=? AND t.cod_sec=? AND t.status_t IS NULL",
" GROUP BY t.cod_seccion,t.cod_tramo,t.cod_fila,t.cod_pos,a.descripcion,b.descripcion,c.titulo,d.titulo",
" ORDER BY t.cod_seccion,t.cod_tramo,t.cod_fila,t.cod_pos"
PREPARE stmt_ajuste FROM q
DECLARE cur_ajuste CURSOR FOR stmt_ajuste
LET prepAjuste = TRUE
END IF
CALL loc.clear()
LET k = 1
FOREACH cur_ajuste
USING p_cod_bodega, p_cod_n, p_cod_grupo, p_cod_tipo, p_cod_sec
INTO loc[k].cod_seccion,
loc[k].cod_tramo,
loc[k].cod_fila,
loc[k].cod_pos,
loc[k].desc_seccion,
loc[k].desc_tramo,
loc[k].desc_fila,
loc[k].desc_pos,
loc[k].existencia_act,
loc[k].unidades_act
IF loc[k].existencia_act IS NULL THEN
LET loc[k].existencia_act = 0
END IF
IF loc[k].unidades_act IS NULL THEN
LET loc[k].unidades_act = 0
END IF
IF loc[k].desc_seccion IS NULL THEN
LET loc[k].desc_seccion = "(sin ubicar)"
END IF
IF loc[k].desc_tramo IS NULL THEN
LET loc[k].desc_tramo = "-"
END IF
IF loc[k].desc_fila IS NULL THEN
LET loc[k].desc_fila = "-"
END IF
IF loc[k].desc_pos IS NULL THEN
LET loc[k].desc_pos = "-"
END IF
## Las UNIDADES arrancan en las actuales y la CANTIDAD (existencia) se
## calcula desde ya con el factor (unidades * factor), no desde el
## cantidad2 guardado (que puede estar descuadrado, p.ej. en 0).
LET loc[k].unidades = loc[k].unidades_act
LET loc[k].existencia = loc[k].unidades_act * p_factor
LET k = k + 1
END FOREACH
## Si el item NO tiene ninguna ubicacion REAL en la bodega (nunca tuvo
## transacciones en iptb00062, o solo tiene el placeholder 0/0/0/0 que crea
## "adicionar sin existencia"), se presenta la ubicacion por defecto
## configurada en la tabla companias para que el usuario cargue ahi.
LET hay_real = FALSE
FOR k = 1 TO loc.getLength()
IF loc[k].cod_seccion > 0
OR loc[k].cod_tramo > 0
OR loc[k].cod_fila > 0
OR loc[k].cod_pos > 0 THEN
LET hay_real = TRUE
EXIT FOR
END IF
END FOR
IF NOT hay_real THEN
INITIALIZE def_sec, def_tra, def_fila, def_pos TO NULL
SELECT cod_seccion, cod_tramo, cod_fila, cod_pos
INTO def_sec, def_tra, def_fila, def_pos
FROM companias
IF def_sec IS NOT NULL THEN
## Descripciones de la ubicacion por defecto (si estan en catalogo).
LET d_sec = NULL
SELECT RTRIM(descripcion) INTO d_sec FROM intb00010
WHERE cod_bodega = p_cod_bodega AND cod_seccion = def_sec
LET d_tra = NULL
SELECT RTRIM(descripcion) INTO d_tra FROM intb00043
WHERE cod_bodega = p_cod_bodega AND cod_seccion = def_sec
AND cod_tramo = def_tra
LET d_fila = NULL
SELECT RTRIM(titulo) INTO d_fila FROM intb00045
WHERE cod_bodega = p_cod_bodega AND cod_seccion = def_sec
AND cod_tramo = def_tra AND cod_fila = def_fila
LET d_pos = NULL
SELECT RTRIM(titulo) INTO d_pos FROM intb00046
WHERE cod_bodega = p_cod_bodega AND cod_seccion = def_sec
AND cod_tramo = def_tra AND cod_fila = def_fila
AND cod_pos = def_pos
## Se AGREGA como una fila mas (no se pierde ningun placeholder).
LET k = loc.getLength() + 1
LET loc[k].cod_seccion = def_sec
LET loc[k].cod_tramo = def_tra
LET loc[k].cod_fila = def_fila
LET loc[k].cod_pos = def_pos
LET loc[k].desc_seccion = d_sec
LET loc[k].desc_tramo = d_tra
LET loc[k].desc_fila = d_fila
LET loc[k].desc_pos = d_pos
IF loc[k].desc_seccion IS NULL THEN
LET loc[k].desc_seccion = "SEC " || def_sec
END IF
IF loc[k].desc_tramo IS NULL THEN
LET loc[k].desc_tramo = "TR " || def_tra
END IF
IF loc[k].desc_fila IS NULL THEN
LET loc[k].desc_fila = "FL " || def_fila
END IF
IF loc[k].desc_pos IS NULL THEN
LET loc[k].desc_pos = "POS " || def_pos
END IF
LET loc[k].existencia_act = 0
LET loc[k].unidades_act = 0
LET loc[k].unidades = 0
LET loc[k].existencia = 0
END IF
END IF
## Si aun asi no hay nada para mostrar (sin ubicaciones y sin default).
IF loc.getLength() = 0 THEN
CALL fgl_winmessage(
"INFO",
"Este item no tiene ubicaciones en esta bodega y no hay ubicacion por defecto configurada en companias. Use la opcion 'Ubicar' primero.",
"info")
RETURN FALSE
END IF
LET p_codigo_str =
(p_cod_n USING "<<<<<&") CLIPPED, " - ",
(p_cod_grupo USING "<<<<<&") CLIPPED, " - ",
(p_cod_tipo USING "<<<<<&") CLIPPED, " - ",
(p_cod_sec USING "<<<<<&") CLIPPED
LET p_desc_str = p_descrip CLIPPED
OPEN WINDOW w_ajuste WITH FORM "ipfmcs004b"
DISPLAY p_codigo_str TO pcodigo
DISPLAY p_desc_str TO pdesc
DISPLAY p_bodega_nombre CLIPPED TO pbodega
DISPLAY p_existencia_real TO ereal
INPUT ARRAY loc FROM sr_loc.*
ATTRIBUTES(WITHOUT DEFAULTS,
APPEND ROW = FALSE,
INSERT ROW = FALSE,
DELETE ROW = FALSE,
UNBUFFERED)
BEFORE INPUT
LET total_corr = 0
FOR k = 1 TO loc.getLength()
LET total_corr = total_corr + loc[k].existencia
END FOR
DISPLAY total_corr TO tubic
DISPLAY p_existencia_real - total_corr TO pdif
ON CHANGE unidades
## La existencia (cantidad2) se calcula multiplicando por el factor.
IF loc[arr_curr()].unidades IS NULL THEN
LET loc[arr_curr()].unidades = 0
END IF
LET loc[arr_curr()].existencia =
loc[arr_curr()].unidades * p_factor
LET total_corr = 0
FOR k = 1 TO loc.getLength()
LET total_corr = total_corr + loc[k].existencia
END FOR
DISPLAY total_corr TO tubic
DISPLAY p_existencia_real - total_corr TO pdif
ON ACTION accept
LET total_corr = 0
FOR k = 1 TO loc.getLength()
IF loc[k].existencia IS NULL THEN
LET loc[k].existencia = 0
END IF
LET total_corr = total_corr + loc[k].existencia
END FOR
IF total_corr <> p_existencia_real THEN
LET msg_txt =
"El total de las ubicaciones (",
total_corr,
") debe ser igual a la existencia real (",
p_existencia_real,
"). Diferencia: ",
(p_existencia_real - total_corr)
CALL fgl_winmessage("VALIDACION", msg_txt, "stop")
CONTINUE INPUT
END IF
TRY
BEGIN WORK
FOR k = 1 TO loc.getLength()
## Solo se registra la DIFERENCIA por ubicacion, con cod_mov 99.
## cantidad = delta de UNIDADES, cantidad2 = delta de existencia.
IF loc[k].existencia <> loc[k].existencia_act
OR loc[k].unidades <> loc[k].unidades_act THEN
INSERT INTO iptb00062(
num_doc,
fecha,
area,
cod_n,
cod_grupo,
cod_tipo,
cod_sec,
cod_mov,
bodega,
cod_seccion,
cod_tramo,
cod_fila,
cod_pos,
cantidad,
cantidad2,
status_t,
us_crea,
fech_crea,
us_mod,
fech_mod)
VALUES(99,
getdate(),
NULL,
p_cod_n,
p_cod_grupo,
p_cod_tipo,
p_cod_sec,
99,
p_cod_bodega,
loc[k].cod_seccion,
loc[k].cod_tramo,
loc[k].cod_fila,
loc[k].cod_pos,
loc[k].unidades - loc[k].unidades_act,
loc[k].existencia - loc[k].existencia_act,
NULL,
usuarios,
getdate(),
NULL,
NULL)
END IF
END FOR
COMMIT WORK
LET guardado = TRUE
CALL fgl_winmessage(
" ", "AJUSTE DE UBICACIONES APLICADO.", "info")
EXIT INPUT
CATCH
ROLLBACK WORK
CALL fgl_winmessage(
"ERROR", "NO SE PUDO APLICAR EL AJUSTE.", "stop")
END TRY
ON ACTION cancel
LET guardado = FALSE
EXIT INPUT
END INPUT
CLOSE WINDOW w_ajuste
RETURN guardado
END FUNCTION
################################################################################
## Recarga el arbol de productos/ubicaciones en pantalla reutilizando el cursor
## 'accion' ya preparado. Se usa tras aplicar un ajuste de ubicaciones para que
## el usuario vea las existencias actualizadas sin volver a buscar.
################################################################################
FUNCTION recargar_arbol()
DEFINE
pcantidadConduce, pexistencia DEC(12, 5),
codigo_act, codigo_ant VARCHAR(50),
idx, j, z, bodegaCont INT
LET idx = 1
LET j = 0
LET z = 1
CALL prod1.clear()
CALL bodegas.clear()
CALL bodega_fila.clear()
CALL load_ubicaciones.clear()
LET codigo_ant = '0'
LET codigo_act = '0'
FOREACH accion INTO prod1[idx].*
LET ubicaciones = 0
LET codigo_act =
prod1[idx].cod_n USING "&&&&&",
prod1[idx].cod_grupo USING "&&&&&",
prod1[idx].cod_tipo USING "&&&&&",
prod1[idx].cod_sec USING "&&&&&&&&"
LET prod1[idx].estado = NULL
SELECT UNIQUE a.cod_sec
FROM iptb00050 a
WHERE a.cod_n = prod1[idx].cod_n
AND a.cod_grupo = prod1[idx].cod_grupo
AND a.cod_tipo = prod1[idx].cod_tipo
AND a.cod_sec = prod1[idx].cod_sec
IF STATUS <> NOTFOUND THEN
LET prod1[idx].estado = "information.png"
END IF
IF prod1[idx].existencia IS NULL THEN
LET prod1[idx].existencia = 0
END IF
LET prod1[idx].cantidad_ordenes = 0
IF codigo_ant <> codigo_act THEN
LET codigo_ant =
prod1[idx].cod_n USING "&&&&",
prod1[idx].cod_grupo USING "&&&&",
prod1[idx].cod_tipo USING "&&&&",
prod1[idx].cod_sec USING "&&&&&&"
CALL disponibles(
prod1[idx].cod_n,
prod1[idx].cod_grupo,
prod1[idx].cod_tipo,
prod1[idx].cod_sec,
datos_cons.fech_fi)
RETURNING prod1[idx].cantidad_ordenes,
pcantidadConduce,
prod1[idx].transito,
pexistencia,
prod1[idx].reservado,
prod1[idx].valorOrden
LET prod1[idx].cantidad_ordenes =
prod1[idx].cantidad_ordenes - pcantidadConduce
IF prod1[idx].cantidad_ordenes = 0 THEN
LET prod1[idx].valorOrden = 0
END IF
END IF
IF prod1[idx].existencia IS NULL THEN
LET prod1[idx].existencia = 0
END IF
IF prod1[idx].cantidad_ordenes IS NULL THEN
LET prod1[idx].cantidad_ordenes = 0
END IF
IF prod1[idx].disponible IS NULL THEN
LET prod1[idx].disponible = 0
END IF
LET prod1[idx].disponible =
pexistencia - prod1[idx].cantidad_ordenes - prod1[idx].reservado
LET productos[idx].producto =
prod1[idx].cod_n USING "&&&&",
prod1[idx].cod_grupo USING "&&&&",
prod1[idx].cod_tipo USING "&&&&",
prod1[idx].cod_sec USING "&&&&&&",
" ",
prod1[idx].descrip_esp
LET productos[idx].bodega = prod1[idx].bodega
LET productos[idx].existencia = prod1[idx].existencia
LET productos[idx].parent = prod1[idx].bodega
CALL LlenarHijos(prod1[idx].*) RETURNING bodegaCont, ubicaciones
LET bodegas[z] = bodegacont
LET bodega_fila[idx] = bodegacont
LET load_ubicaciones[z] = ubicaciones
LET z = z + 1
LET INT_FLAG = FALSE
IF ubicaciones > 0 THEN
LET j = idx + 1
LET INT_FLAG = TRUE
LET prod1[idx].parent_id = NULL
LET prod1[idx].child_id = 1
CALL treeFunction(
j,
prod1[idx].cod_n,
prod1[idx].cod_grupo,
prod1[idx].cod_tipo,
prod1[idx].cod_sec,
bodegaCont,
prod1[idx].existencia)
RETURNING j
END IF
IF INT_FLAG THEN
LET idx = j
ELSE
LET idx = idx + 1
END IF
INITIALIZE ubicaciones TO NULL
END FOREACH
IF idx = 1 THEN
CALL msg(3)
END IF
END FUNCTION
FUNCTION reporteData()
DEFINE
j INT,
pcosto, valorcosto, pprecio, valorprecio DEC(12, 2),
xcodigo VARCHAR(100)
LET r_filename = "ipprcs004.4rp"
FOR j = 1 TO prod1.getLength()
IF prod1[j].cod_n IS NOT NULL THEN
IF j = 1 THEN
IF fgl_report_loadCurrentSettings(
r_filename) THEN -- load the .4rp file
CALL seleccionarSalida() RETURNING r_output
LET preview = 1
CALL fgl_report_selectDevice(r_output) -- changing default
CALL fgl_report_selectPreview(preview) -- changing default
LET handler =
fgl_report_commitCurrentSettings() -- commit changes
IF handler IS NOT NULL THEN -- report engine was configured ok
START REPORT datarp06 TO XML HANDLER HANDLER
ELSE
EXIT FOR
END IF
ELSE
EXIT FOR
END IF
END IF
#BUSCA COSTO STD
LET valorcosto = 0
SELECT AVG(a.material + a.labor + a.gastos)
INTO pcosto
FROM iptb00004 a
WHERE a.ano = YEAR(TODAY)
AND a.mes_fin = 12
AND a.cod_n = prod1[j].cod_n
AND a.cod_grupo = prod1[j].cod_grupo
AND a.cod_tipo = prod1[j].cod_tipo
AND a.cod_sec = prod1[j].cod_sec
AND a.status_t IS NULL
LET valorcosto = prod1[j].existencia * pcosto
SELECT ISNULL(AVG(a.precio), 0)
INTO pprecio
FROM vetb00025 a
WHERE a.ventas = '1'
AND a.cod_n = prod1[j].cod_n
AND a.cod_grupo = prod1[j].cod_grupo
AND a.cod_tipo = prod1[j].cod_tipo
AND a.cod_sec = prod1[j].cod_sec
AND a.status_t IS NULL
LET valorprecio = pprecio * prod1[j].existencia
LET xcodigo =
prod1[j].cod_n USING "<<<<<",
"-",
prod1[j].cod_tipo USING "<<<<<",
"-",
prod1[j].cod_grupo USING "<<<<<",
"-",
prod1[j].cod_sec USING "<<<<<"
OUTPUT TO REPORT DATARP06(
xcodigo, prod1[j].*, valorcosto, pprecio, valorprecio)
END IF
END FOR
FINISH REPORT datarp06
END FUNCTION
REPORT datarp06(pcodigo, x, xvalorcosto, pprecio, valorprecio)
DEFINE
x RECORD
estado VARCHAR(20),
cod_n SMALLINT,
cod_grupo SMALLINT,
cod_tipo SMALLINT,
cod_sec SMALLINT,
descrip_esp CHAR(180),
unidad_med LIKE iptb00002.unidad_med,
bodega CHAR(50),
existencia DECIMAL(12, 5),
cantidad_ordenes DEC(12, 5),
disponible DEC(12, 5),
reservado DEC(12, 5),
transito DEC(12, 5),
valorOrden DEC(16, 5),
parent_id, child_id VARCHAR(20)
END RECORD,
pcodigo VARCHAR(100),
xvalorcosto,
tvalororden,
tvalorcosto,
tvalorprecio,
pexistencia,
pcantidadorden,
pvalororden,
pvalorcosto,
pprecio,
valorprecio
DEC(12, 2),
tiempo VARCHAR(5)
ORDER BY pcodigo
FORMAT
AFTER GROUP OF pcodigo
LET tiempo = TIME
LET pvalororden = GROUP SUM(x.valorORden)
LET pexistencia = GROUP SUM(x.existencia)
LET pcantidadorden = GROUP SUM(x.cantidad_ordenes)
LET pvalorcosto = GROUP SUM(xvalorcosto)
PRINTX x.*,
xvalorcosto,
tiempo,
pvalororden,
pexistencia,
pcantidadorden,
pvalorcosto,
pprecio,
valorprecio
ON LAST ROW
LET tvalororden = SUM(x.cantidad_ordenes)
LET tvalorcosto = SUM(x.existencia)
LET tvalorprecio = SUM(valorprecio)
PRINTX tvalororden, tvalorcosto, tvalorprecio
END REPORT
FUNCTION extract_value(criterio, campo)
DEFINE criterio, campo VARCHAR(500)
DEFINE tok, tok2 base.StringTokenizer
DEFINE token, VALUE, token2 VARCHAR(200)
DEFINE idx INTEGER
LET tok = base.StringTokenizer.create(criterio, " ")
LET value = ""
LET campo = '*', campo, '*'
LET idx = 1
WHILE tok.hasMoreTokens()
LET token = tok.nextToken()
-- Verifica si el token comienza con el campo
IF token MATCHES campo THEN
LET tok2 = base.StringTokenizer.create(token, "=")
WHILE tok2.hasMoreTokens()
LET token2 = tok2.nextToken()
DISPLAY token2
IF idx = 2 THEN
LET VALUE = token2
EXIT WHILE
END IF
LET idx = idx + 1
END WHILE
END IF
END WHILE
DISPLAY VALUE
RETURN VALUE
END FUNCTION