{ ------------------------------------------------------------------------------- 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