Files
MBS/PROYECTO/PRDIR/prprmt022.4gl
T

789 lines
24 KiB
Plaintext

{
PROGRAMA : prprmt022.4gl
OBJETIVO : Visualizar las ordenes, con la finalidad de mostrar diferentes estados
DESARROLLADO POR : Ing. Elvis Garcia
FECHA : JULIO 12, 2025
}
IMPORT util
IMPORT FGL fgldialog
SCHEMA smarmotech
DEFINE usuarios, clave STRING
DEFINE pcompanias RECORD LIKE companias.*
DEFINE fechas RECORD
fech_inicial DATE,
fech_final DATE
END RECORD
DEFINE data DYNAMIC ARRAY OF RECORD
orden INT,
estado STRING,
cotizacion STRING,
fecha_orden DATE,
cliente STRING,
email STRING,
vendedor STRING,
emailVendedor STRING,
celular_vendedor STRING,
telefono_casa STRING,
celular1 STRING,
tel_contacto STRING,
parentId STRING,
childId STRING
END RECORD
DEFINE cell_colors DYNAMIC ARRAY OF STRING,
criterio STRING,
contador INT
DEFINE handler om.SaxDocumentHandler, -- return value from fgl_report_commitCurrentSettings()
r_filename STRING, -- filename of Report Design Document including .4rp extension
r_output VARCHAR(10), -- output format option
preview INTEGER
MAIN
CALL ARG_VAL(1) RETURNING usuarios
CALL ARG_VAL(2) RETURNING clave
CONNECT TO "smarmotech" USER usuarios USING clave
SELECT * INTO pcompanias.* FROM companias
CALL estado_ordenes()
END MAIN
FUNCTION estado_ordenes()
OPEN WINDOW w1 WITH FORM "prfmmt022"
CALL ui.Interface.LoadStyles("mbsStyle")
CALL initConditions()
CALL consulta()
DIALOG ATTRIBUTE(UNBUFFERED)
DISPLAY ARRAY data TO s_tree.*
BEFORE DISPLAY
DISPLAY BY NAME contador
ON ACTION consultar ATTRIBUTES(TEXT = "OK")
CALL initConditions()
CALL consulta()
ON ACTION visualiza_log ATTRIBUTES(TEXT = "Abrir Log")
CALL abrir_log(arr_curr())
ON ACTION b_reporte ATTRIBUTE(TEXT="Informe",IMAGE="printer")
CALL generar_reporte_tiempos(fechas.fech_inicial, fechas.fech_final)
ON ACTION salir ATTRIBUTES(TEXT = "Salir", IMAGE = "fa-power-off")
EXIT PROGRAM
END DISPLAY
END DIALOG
CLOSE WINDOW w1
END FUNCTION
FUNCTION abrir_log(indice INT)
END FUNCTION
FUNCTION initConditions()
INITIALIZE fechas.* TO NULL
CLEAR FORM
DIALOG ATTRIBUTES(UNBUFFERED)
INPUT BY NAME fechas.* ATTRIBUTES(WITHOUT DEFAULTS)
AFTER INPUT
IF fechas.fech_final IS NOT NULL AND fechas.fech_inicial IS NOT NULL THEN
IF fechas.fech_inicial > fechas.fech_final THEN
CALL msg(86)
NEXT FIELD fech_inicial
END IF
END IF
END INPUT
CONSTRUCT criterio
ON view_ordenes.estado,
view_ordenes.orden,
view_ordenes.rnc,
view_ordenes.cliente,
view_ordenes.clase,
view_ordenes.grupo,
view_ordenes.tipo,
view_ordenes.medida,
view_ordenes.cotizacion
FROM estado1,
orden1,
rnc,
nombre_cliente,
cod_n,
cod_grupo,
cod_tipo,
cod_sec,
cotizacion1
END CONSTRUCT
ON ACTION ACCEPT ATTRIBUTES(TEXT = "Consultar", IMAGE = "mag")
ACCEPT DIALOG
ON ACTION salir ATTRIBUTES(TEXT = "Salir", IMAGE = "fa-power-off")
EXIT PROGRAM
END DIALOG
END FUNCTION
FUNCTION consulta()
------------------------------------------------------------------
-- 1) VARIABLES
------------------------------------------------------------------
DEFINE i, grp_no, prod_idx, mov_idx INT
DEFINE last_key, curr_key, last_prod STRING
DEFINE prod_id, param_fechas STRING
DEFINE flag BOOLEAN
-- Buffers de FECHAS / ESTADOS del producto activo
DEFINE
bf_fOrd DATE,
bf_fCot DATE,
bf_fIns DATE,
bf_fTdm DATE,
bf_fCal DATE,
bf_fDes DATE,
bf_fComp DATE,
bf_estProd STRING,
bf_estProc STRING,
bf_observ STRING
-- Variables del cursor
DEFINE
v_orden INT,
v_estado STRING,
v_cot INT,
v_cliente STRING,
v_email STRING,
v_vendedor STRING,
v_emailVend STRING,
v_celVend STRING,
v_telCasa STRING,
v_cel1 STRING,
v_telContacto STRING,
v_desc_prod STRING,
v_docAlm INT,
v_desc_mov STRING,
v_sumcant DECIMAL(12, 5),
v_fInst DATE,
v_fTDM DATE,
v_fCal DATE,
v_fOrd DATE,
v_fCot DATE,
v_fDoc DATE,
v_fDes DATE,
v_fcomp DATE,
v_estProd STRING,
v_estProc STRING,
v_observ STRING
------------------------------------------------------------------
-- 2) SENTENCIA SQL
------------------------------------------------------------------
DEFINE sql STRING
INITIALIZE cell_colors TO NULL
LET sql =
"
SELECT orden, view_ordenes.ESTADO, cotizacion,Cliente, view_ordenes.email,
RTRIM(NOMBRE_VENDEDOR)+' '+RTRIM(APELLIDO_VENDEDOR) AS vendedor,
ISNULL(telefono, 'NO TIENE'), ISNULL(vetb00050.telefono_r,'NO TIENE'),ISNULL(vetb00050.celular,'NO TIENE'),
ISNULL(vetb00050.celular1,'NO TIENE'),equipoVentas,
CONCAT('(',clase,'-',grupo,'-',tipo,'-',medida,') - ',DESCRIPCION_PRODUCTO) AS PRODUCTO,
documentoAlmacen, DescripcionMovimiento,
SUM(CANTIDAD_ORDEN) AS suma_cantidad_orden,
fechaSolicitudInstalacion, fechaSolicitudTDMCompletada, fechaInspeccionCalidad,
fechaOrden, fechaCotizacion, FechaDocumento, FechaDespacho, fecha_compromiso,
estado_producto, EstadoProcesos, observacion
FROM view_ordenes inner join vetb00050 on view_ordenes.cotizacion = vetb00050.cotizacion_no WHERE "
IF fechas.fech_inicial IS NULL AND fechas.fech_final IS NULL THEN
LET param_fechas = ""
END IF
IF fechas.fech_inicial IS NOT NULL AND fechas.fech_final IS NULL THEN
LET SQL = SQL || " fechaOrden >= ? AND "
END IF
IF fechas.fech_inicial IS NULL AND fechas.fech_final IS NOT NULL THEN
LET SQL = SQL || " fechaOrden <= ? AND "
END IF
IF fechas.fech_final IS NOT NULL AND fechas.fech_final IS NOT NULL THEN
LET SQL =
SQL
|| " fechaOrden BETWEEN ? AND ? AND "
END IF
LET SQL =
SQL || criterio CLIPPED || "
GROUP BY orden, view_ordenes.ESTADO, cotizacion, Cliente, view_ordenes.email,
NOMBRE_VENDEDOR, APELLIDO_VENDEDOR,
telefono, equipoVentas,
clase, grupo, tipo, medida, DESCRIPCION_PRODUCTO,
documentoAlmacen, DescripcionMovimiento,
fechaSolicitudInstalacion, fechaSolicitudTDMCompletada, fechaInspeccionCalidad,
fechaOrden, fechaCotizacion, FechaDocumento, FechaDespacho, fecha_compromiso,
estado_producto, EstadoProcesos, observacion, vetb00050.telefono_o, vetb00050.telefono_r,vetb00050.celular,vetb00050.celular1
ORDER BY orden, view_ordenes.ESTADO, cotizacion, Cliente, view_ordenes.email,
vendedor, telefono, equipoVentas,
clase, grupo, tipo, medida, DESCRIPCION_PRODUCTO, DescripcionMovimiento"
PREPARE stmt FROM sql
DECLARE cur CURSOR FOR stmt
IF fechas.fech_inicial IS NULL AND fechas.fech_final IS NULL THEN
OPEN cur
END IF
IF fechas.fech_inicial IS NOT NULL AND fechas.fech_final IS NULL THEN
OPEN cur USING fechas.fech_inicial
END IF
IF fechas.fech_inicial IS NULL AND fechas.fech_final IS NOT NULL THEN
OPEN cur USING fechas.fech_final
END IF
IF fechas.fech_final IS NOT NULL AND fechas.fech_final IS NOT NULL THEN
OPEN cur USING fechas.fech_inicial, fechas.fech_final
END IF
OPEN cur
------------------------------------------------------------------
-- 3) CONSTRUCCIÓN DEL TREE
------------------------------------------------------------------
CALL data.clear()
LET i = 1
LET contador = 0
LET grp_no = 0
LET last_key = "¤"
LET last_prod = "¤"
LET prod_id = ""
FOREACH cur
INTO v_orden,
v_estado,
v_cot,
v_cliente,
v_email,
v_vendedor,
v_emailVend,
v_celVend,
v_telCasa ,
v_cel1 ,
v_telContacto,
v_desc_prod,
v_docAlm,
v_desc_mov,
v_sumcant,
v_fInst,
v_fTDM,
v_fCal,
v_fOrd,
v_fCot,
v_fDoc,
v_fDes,
v_fcomp,
v_estProd,
v_estProc,
v_observ
LET curr_key =
v_orden
|| '|'
|| v_estado
|| '|'
|| v_cot
|| '|'
|| v_cliente
|| '|'
|| v_email
|| '|'
|| v_vendedor
|| '|'
|| v_emailVend
|| '|'
|| v_celVend
--===== NUEVA ORDEN ==========================================
IF curr_key <> last_key THEN
LET i =
finaliza_producto(
i,
prod_id,
last_prod,
bf_fOrd,
bf_fCot,
bf_fIns,
bf_fTdm,
bf_fCal,
bf_fDes,
bf_fComp,
bf_estProd,
bf_estProc,
bf_observ)
LET grp_no = grp_no + 1
LET prod_idx = 0
LET last_prod = "¤"
-- Raíz
LET data[i].orden = v_orden
LET flag = FALSE
LET cell_colors[i] = NULL
CALL Marcar_Amarillo(data[i].orden) RETURNING flag
IF flag THEN
LET cell_colors[i] = 'yellow reverse'
END IF
LET data[i].estado = v_estado
LET data[i].cotizacion = v_cot
LET data[i].fecha_orden = v_fOrd
LET data[i].cliente = v_cliente
LET data[i].email = v_email
LET data[i].vendedor = v_vendedor
LET data[i].emailVendedor = v_emailVend
LET data[i].celular_vendedor = v_celVend
LET data[i].telefono_casa = v_telCasa
LET data[i].celular1 = v_cel1
LET data[i].tel_contacto = v_telcontacto
LET data[i].parentId = NULL
LET data[i].childId = grp_no
LET contador = contador + 1
LET i = i + 1
-- título PRODUCTOS
INITIALIZE data[i].* TO NULL
LET data[i].estado = "PRODUCTOS"
LET data[i].parentId = grp_no
LET data[i].childId = grp_no || ".1"
LET i = i + 1
END IF
--===== NUEVO PRODUCTO =======================================
IF v_desc_prod <> last_prod THEN
LET i =
finaliza_producto(
i,
prod_id,
last_prod,
bf_fOrd,
bf_fCot,
bf_fIns,
bf_fTdm,
bf_fCal,
bf_fDes,
bf_fComp,
bf_estProd,
bf_estProc,
bf_observ)
LET prod_idx = prod_idx + 1
LET prod_id = grp_no || ".1." || prod_idx
LET mov_idx = 0
LET last_prod = v_desc_prod
-- buffer de FECHAS / ESTADOS
LET bf_fOrd = v_fOrd;
LET bf_fCot = v_fCot
LET bf_fIns = v_fInst;
LET bf_fTdm = v_fTDM
LET bf_fCal = v_fCal;
LET bf_fDes = v_fDes
LET bf_fComp = v_fComp
LET bf_estProd = v_estProd
LET bf_estProc = v_estProc
LET bf_observ = v_observ
-- nodo PRODUCTO
INITIALIZE data[i].* TO NULL
LET data[i].cotizacion = v_desc_prod || " (" || v_sumcant || ")"
LET data[i].parentId = grp_no || ".1"
LET data[i].childId = prod_id
LET i = i + 1
-- título MOVIMIENTOS
INITIALIZE data[i].* TO NULL
LET data[i].cotizacion = " MOVIMIENTOS"
LET data[i].parentId = prod_id
LET data[i].childId = prod_id || ".1"
LET i = i + 1
ELSE
-- mismo producto ? actualiza buffers
IF v_fInst IS NOT NULL THEN
LET bf_fIns = v_fInst
END IF
IF v_fTDM IS NOT NULL THEN
LET bf_fTdm = v_fTDM
END IF
IF v_fCal IS NOT NULL THEN
LET bf_fCal = v_fCal
END IF
IF v_fDes IS NOT NULL THEN
LET bf_fDes = v_fDes
END IF
IF v_fComp IS NOT NULL THEN
LET bf_fComp = v_fComp
END IF
END IF
--===== DETALLE MOVIMIENTO ===================================
IF v_docAlm IS NOT NULL THEN
LET mov_idx = mov_idx + 1
INITIALIZE data[i].* TO NULL
LET data[i].cotizacion =
" " || v_docAlm || " - " || v_desc_mov CLIPPED
|| " - "
|| v_fDoc
LET data[i].parentId = prod_id || ".1"
LET data[i].childId = prod_id || ".1." || mov_idx
LET i = i + 1
END IF
LET last_key = curr_key
END FOREACH
-- cierra el último producto
LET i =
finaliza_producto(
i,
prod_id,
last_prod,
bf_fOrd,
bf_fCot,
bf_fIns,
bf_fTdm,
bf_fCal,
bf_fDes,
bf_fComp,
bf_estProd,
bf_estProc,
bf_observ)
END FUNCTION
------------------------------------------------------------------
-- FIN PRODUCTO (devuelve nuevo índice i)
------------------------------------------------------------------
FUNCTION finaliza_producto(
start_i INT,
p_prod_id STRING,
p_last_prod STRING,
fOrd DATE,
fCot DATE,
fIns DATE,
fTdm DATE,
fCal DATE,
fDes DATE,
fComp DATE,
sProd STRING,
sProc STRING,
sObs STRING)
DEFINE i INT
LET i = start_i
IF p_last_prod = "¤" THEN
RETURN i -- nada pendiente
END IF
-- ----- FECHAS título + detalles -----
INITIALIZE data[i].* TO NULL
LET data[i].cotizacion = " FECHAS"
LET data[i].parentId = p_prod_id
LET data[i].childId = p_prod_id || ".2"
LET i = i + 1
LET i =
add_fecha_block(
i, p_prod_id || ".2", fOrd, fCot, fIns, fTdm, fCal, fDes, fComp)
-- ----- ESTADOS título + detalles -----
INITIALIZE data[i].* TO NULL
LET data[i].cotizacion = " ESTADOS"
LET data[i].parentId = p_prod_id
LET data[i].childId = p_prod_id || ".3"
LET i = i + 1
LET sProd = ' Estado producto : ', sProd
LET sProc = ' Estado procesos : ', sProc
LET sObs = ' Observacion : ', sObs
CALL add_simple_detail(
i, p_prod_id || ".3", 1, sProd);
LET i = i + 1
CALL add_simple_detail(
i, p_prod_id || ".3", 2, sProc);
LET i = i + 1
CALL add_simple_detail(
i, p_prod_id || ".3", 3, sObs);
LET i = i + 1
RETURN i
END FUNCTION
------------------------------------------------------------------
-- helpers
------------------------------------------------------------------
FUNCTION add_simple_detail(pos INT, parent STRING, n INT, txt STRING)
INITIALIZE data[pos].* TO NULL
LET data[pos].cotizacion = txt
LET data[pos].parentId = parent
LET data[pos].childId = parent || "." || n
END FUNCTION
FUNCTION add_fecha_block(
start_i INT,
parent STRING,
f_ord DATE,
f_cot DATE,
f_ins DATE,
f_tdm DATE,
f_cal DATE,
f_dep DATE,
f_comp DATE)
DEFINE
i, idx INT,
descrip_fecha STRING
LET i = start_i
LET idx = 0
LET idx = idx + 1
LET descrip_fecha = "Fecha Orden : ", f_ord
CALL add_simple_detail(i, parent, idx, descrip_fecha);
LET i = i + 1
LET idx = idx + 1
LET descrip_fecha = "Fecha Cotizacion : ", f_cot
CALL add_simple_detail(i, parent, idx, descrip_fecha);
LET i = i + 1
LET idx = idx + 1
LET descrip_fecha = "Solic. Instalacion : ", f_ins
CALL add_simple_detail(i, parent, idx, descrip_fecha);
LET i = i + 1
LET idx = idx + 1
LET descrip_fecha = "TDM Completada : ", f_tdm
CALL add_simple_detail(i, parent, idx, descrip_fecha);
LET i = i + 1
LET idx = idx + 1
LET descrip_fecha = "Inspeccion Calidad : ", f_cal
CALL add_simple_detail(i, parent, idx, descrip_fecha);
LET i = i + 1
LET idx = idx + 1
LET descrip_fecha = "Fecha Despacho : ", f_dep
CALL add_simple_detail(i, parent, idx, descrip_fecha);
LET i = i + 1
LET idx = idx + 1
LET descrip_fecha = "Fecha Compromiso : ", f_comp
CALL add_simple_detail(i, parent, idx, descrip_fecha);
LET i = i + 1
RETURN i
END FUNCTION
FUNCTION marcar_amarillo(orden INT)
DEFINE flag BOOLEAN, idx INT
DEFINE CompromisoProduccion DYNAMIC ARRAY OF RECORD
orden INT,
producto STRING,
fecha_compromiso DATE,
es_produccion BOOLEAN
END RECORD
LET flag = FALSE
DECLARE data_compromisoProduccion CURSOR FOR
SELECT a.num_oc, CONCAT('(',a.cod_n,'-',a.cod_grupo,'-',a.cod_tipo,'-',a.cod_sec,')',b.descrip_esp) AS producto,
a.fecha_compromiso, b.es_produccion FROM prtb00013 a INNER JOIN iptb00002 b ON
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
WHERE b.es_produccion = 1 and
a.num_oc = orden
LET idx = 1
FOREACH data_compromisoProduccion INTO CompromisoProduccion[idx].*
IF compromisoProduccion[idx].fecha_compromiso IS NULL THEN
LET flag = TRUE
EXIT FOREACH
END IF
LET idx = idx + 1
END FOREACH
RETURN flag
END FUNCTION
FUNCTION generar_reporte_tiempos(fi DATE, ff DATE)
DEFINE r RECORD
-- periodo DATETIME YEAR TO DAY ,
tiempo_colocacion INTEGER,
tiempo_despacho INTEGER,
tiempo_solicitud_instalacion INTEGER,
tiempo_tdm INTEGER,
tiempo_inspeccion_calidad INTEGER
END RECORD
DEFINE respuesta DYNAMIC ARRAY OF RECORD
nombre_categoria STRING,
cantidad_dias INTEGER
END RECORD
DEFINE fecha_final, fecha_inicial DATE
DEFINE idx INT
DEFINE query_report STRING
LET fecha_final = ff USING "yyyy-mm-dd"
LET fecha_inicial = fi USING "yyyy-mm-dd"
LET r_filename ='tiempos_ordenes.4rp'
LET preview = 1
IF fgl_report_loadCurrentSettings(r_filename) THEN -- load the .4rp file
CALL fgl_report_selectDevice(r_output) -- changing default
CALL fgl_report_selectPreview(preview) -- changing default
LET handler = fgl_report_commitCurrentSettings() -- commit changes
END IF --run the report
IF handler IS NOT NULL THEN
START REPORT tiempos_ordenes_report TO XML HANDLER HANDLER
LET query_report =
--"SELECT DATEADD(month, DATEDIFF(month, 0, fechaOrden), 0) as Fecha_general,
"SELECT AVG(ISNULL(DATEDIFF(day, fechaCotizacion, fechaOrden),0)) as 'Cotizacion de la orden',
AVG(ISNULL(DATEDIFF(day, fechaOrden, FechaDespacho),0)) as 'Dias para despachar',
AVG(ISNULL(DATEDIFF(day, fechaSolicitudInstalacion, fechaOrden),0)) as 'Solicitud de instalacion',
AVG(ISNULL(DATEDIFF(day, fechaSolicitudMedida, fechaSolicitudTDMCompletada),0)) as 'Tiempo toma de medida',
AVG(ISNULL(DATEDIFF(day, fechaInspeccionCalidad, FechaDespacho),0)) as 'Fecha de inspeccion de calidad'
FROM view_ordenes
WHERE fechaOrden BETWEEN '",fi USING "mm/dd/yyyy" ,"' AND '",ff USING "mm/dd/yyyy" ,"'
AND ",criterio {,"
GROUP BY DATEADD(month, DATEDIFF(month, 0, fechaOrden), 0)
ORDER BY DATEADD(month, DATEDIFF(month, 0, fechaOrden), 0) " }
DISPLAY query_report
PREPARE buscar_graph FROM query_report
EXECUTE buscar_graph INTO --r.periodo,
r.tiempo_colocacion,
r.tiempo_despacho,
r.tiempo_solicitud_instalacion,
r.tiempo_tdm,
r.tiempo_inspeccion_calidad
FOR idx = 1 TO 5
CASE idx
WHEN 1
LET respuesta[idx].nombre_categoria = 'Colocacion'
LET respuesta[idx].cantidad_dias = r.tiempo_colocacion
EXIT CASE
WHEN 2
LET respuesta[idx].nombre_categoria = 'Despacho'
LET respuesta[idx].cantidad_dias = r.tiempo_despacho
EXIT CASE
WHEN 3
LET respuesta[idx].nombre_categoria = 'Solic. instalacion'
LET respuesta[idx].cantidad_dias = r.tiempo_solicitud_instalacion
EXIT CASE
WHEN 4
LET respuesta[idx].nombre_categoria = 'TDM'
LET respuesta[idx].cantidad_dias = r.tiempo_tdm
EXIT CASE
WHEN 5
LET respuesta[idx].nombre_categoria = 'Inspec. calidad'
LET respuesta[idx].cantidad_dias = r.tiempo_inspeccion_calidad
EXIT CASE
END CASE
IF respuesta[idx].cantidad_dias IS NULL THEN
LET respuesta[idx].cantidad_dias = 0
END IF
DISPLAY respuesta[idx].nombre_categoria
DISPLAY respuesta[idx].cantidad_dias
OUTPUT TO REPORT tiempos_ordenes_report(fecha_inicial,fecha_final, respuesta[idx].*)
END FOR
FINISH REPORT tiempos_ordenes_report
END IF
END FUNCTION
REPORT tiempos_ordenes_report(fi,ff, respuesta)
DEFINE respuesta RECORD
nombre_categoria STRING,
cantidad_dias INTEGER
END RECORD
DEFINE fi, ff DATE
DEFINE rango STRING
DEFINE hora CHAR(5)
DEFINE fecha_reporte CHAR(16)
FORMAT
PAGE HEADER
LET rango = 'Desde el ', fi, ' hasta ', ff
LET hora = TIME
LET fecha_reporte = TODAY,' ',hora
ON EVERY ROW
PRINTX respuesta.*
END REPORT