Merge branch 'main' of http://192.168.40.251:3000/jsoto/MBS
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
<Label gridHeight="1" gridWidth="8" name="label2" posX="24" posY="1" text="FECHA FINAL"/>
|
||||
<DateEdit fieldId="16" gridHeight="1" gridWidth="13" name="fech_final" posX="33" posY="1" tabIndex="-1" title="dateedit2" widget="DateEdit"/>
|
||||
<Label gridHeight="1" gridWidth="6" name="label3" posX="47" posY="1" text="ESTADO "/>
|
||||
<ComboBox fieldId="17" gridHeight="1" gridWidth="12" items="ABIERTA, CERRADA" name="estado1" posX="54" posY="1" tabIndex="-1" title="combobox1" widget="ComboBox">
|
||||
<ComboBox fieldId="17" gridHeight="1" gridWidth="12" items="ABIERTA, CERRADA" name="estado1" notNull="true" posX="54" posY="1" tabIndex="-1" title="combobox1" widget="ComboBox">
|
||||
<Item lstrtext="false" name="ABIERTA" text="ABIERTA"/>
|
||||
<Item lstrtext="false" name="CERRADA" text="CERRADA"/>
|
||||
</ComboBox>
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<ManagedForm databaseName="smarmotech" fileVersion="40100" gstVersion="60003" name="ManagedForm" uid="{50926d70-025d-4be1-a15f-45acbf1b2888}">
|
||||
<AGSettings>
|
||||
<DynamicProperties version="4"/>
|
||||
</AGSettings>
|
||||
<Record name="record1" uid="{ae577ed1-a849-40c1-a3a8-3df0bfba35f6}">
|
||||
<RecordField colName="cotizacion_no" fieldIdRef="5" name="cotizacion_no" sqlTabName="formonly" uid="{34fb79d0-ea3c-45e5-bd43-bd2484db0e24}"/>
|
||||
<RecordField colName="num_oc" fieldIdRef="12" name="num_oc" sqlTabName="formonly" uid="{1b817c74-fb63-4453-9c9e-580cd0ebe8dd}"/>
|
||||
<RecordField colName="cerrada" fieldIdRef="10" name="cerrada" sqlTabName="formonly" uid="{a0ade89e-f809-4801-83fc-82267e75339d}"/>
|
||||
<RecordField colName="sec_vend" fieldIdRef="13" name="sec_vend" sqlTabName="formonly" uid="{532f53e9-4b3f-4c15-8919-c4afedd6e638}"/>
|
||||
<RecordField colName="historico" defaultValue="N" fieldIdRef="0" name="historico" sqlTabName="formonly" uid="{a297c185-81e7-4ae6-8988-2224946811de}"/>
|
||||
<RecordField colName="fecha" fieldIdRef="11" name="fecha" sqlTabName="formonly" sqlType="DATE" uid="{62430a14-a00f-413f-b6b1-766e90f9315e}"/>
|
||||
<RecordField colName="tipo_cliente" fieldIdRef="7" name="tipo_cliente" sqlTabName="formonly" uid="{7cf8df86-dc57-4cd8-9b40-6636785559c9}"/>
|
||||
<RecordField colName="sec_cliente" fieldIdRef="8" name="sec_cliente" sqlTabName="formonly" uid="{c77b4cbf-8ab9-4072-b566-5ce5401f170b}"/>
|
||||
<RecordField colName="nombre_cliente" fieldIdRef="6" name="nombre_cliente" sqlTabName="formonly" uid="{b775b626-23dd-4f6c-8fda-b729a1e40605}"/>
|
||||
<RecordField colName="telefono_r" fieldIdRef="9" name="telefono_r" sqlTabName="formonly" uid="{c545bc0e-23c1-465b-9688-5d5039b27597}"/>
|
||||
<RecordField colName="cod_n" fieldIdRef="1" name="cod_n" sqlTabName="formonly" uid="{a8bcc1fa-5503-4b65-8249-fdaa1e91c258}"/>
|
||||
<RecordField colName="cod_grupo" fieldIdRef="2" name="cod_grupo" sqlTabName="formonly" uid="{71e68d6d-8151-44c2-a42c-4e9465dd3c2b}"/>
|
||||
<RecordField colName="cod_tipo" fieldIdRef="3" name="cod_tipo" sqlTabName="formonly" uid="{a5d7c1ab-90d7-4feb-b86d-6a74f1966b44}"/>
|
||||
<RecordField colName="cod_sec" fieldIdRef="4" name="cod_sec" sqlTabName="formonly" uid="{0fed854c-cd15-4a85-b593-c3a9f114d277}"/>
|
||||
<RecordField colName="salida" defaultValue="Detallado" fieldIdRef="14" name="salida" sqlTabName="formonly" uid="{72b478e3-81f8-4d24-ad49-d777be1c0608}"/>
|
||||
<RecordField colName="visualiza" defaultValue="PANTALLA" fieldIdRef="15" name="visualiza" sqlTabName="formonly" uid="{7c7aa938-7433-4dd6-bcc2-c27d6b3e2e34}"/>
|
||||
</Record>
|
||||
<Form gridHeight="10" gridWidth="67" name="prfmrp116" text="STATUS ORDENES PEDIDOS">
|
||||
<ActionDefaultList name="actiondefaultlist1">
|
||||
<ActionDefault image="print" name="ejecutar" text="Genera Reporte"/>
|
||||
</ActionDefaultList>
|
||||
<Grid gridHeight="10" gridWidth="67" name="grid1" posX="0" posY="0">
|
||||
<Label gridHeight="1" gridWidth="10" name="label1" posX="3" posY="0" text="Cotizacion"/>
|
||||
<Edit colName="cotizacion_no" comment="Digite un numero de cotizacion o deje en blanco para todas" fieldId="5" gridHeight="1" gridWidth="10" name="cotizacion_no" posX="19" posY="0" sqlTabName="formonly" tabIndex="1" widget="Edit"/>
|
||||
<Label gridHeight="1" gridWidth="5" name="label2" posX="3" posY="1" text="Orden"/>
|
||||
<Edit colName="num_oc" comment="Digite un numero de orden o deje en blanco para todas" fieldId="12" gridHeight="1" gridWidth="10" name="num_oc" posX="19" posY="1" sqlTabName="formonly" tabIndex="2" widget="Edit"/>
|
||||
<Label gridHeight="1" gridWidth="12" name="label3" posX="34" posY="1" text="Status Orden"/>
|
||||
<ComboBox colName="cerrada" fieldId="10" gridHeight="1" gridWidth="14" items="Cerrada, Abiertas" name="cerrada" notNull="true" posX="47" posY="1" sqlTabName="formonly" tabIndex="3" widget="ComboBox">
|
||||
<Item name="S" text="Cerrada"/>
|
||||
<Item name="N" text="Abiertas"/>
|
||||
</ComboBox>
|
||||
<Label gridHeight="1" gridWidth="8" name="label4" posX="3" posY="2" text="Vendedor"/>
|
||||
<Edit colName="sec_vend" comment="Digite un numero de vendedor o deje en blanco para todos" fieldId="13" gridHeight="1" gridWidth="10" name="sec_vend" posX="19" posY="2" sqlTabName="formonly" tabIndex="4" widget="Edit"/>
|
||||
<RadioGroup colName="historico" defaultValue="N" fieldId="0" gridHeight="1" gridWidth="26" items="HISTORICO, ACTUAL" name="historico" posX="35" posY="2" sqlTabName="formonly" tabIndex="5" widget="RadioGroup">
|
||||
<Item name="H" text="HISTORICO"/>
|
||||
<Item name="N" text="ACTUAL"/>
|
||||
</RadioGroup>
|
||||
<Label gridHeight="1" gridWidth="5" name="label5" posX="3" posY="3" text="Fecha"/>
|
||||
<DateEdit colName="fecha" fieldId="11" format="dd/mm/yyyy" gridHeight="1" gridWidth="10" name="fecha" posX="19" posY="3" sqlTabName="formonly" sqlType="DATE" tabIndex="6" widget="DateEdit"/>
|
||||
<Label gridHeight="1" gridWidth="15" name="label6" posX="3" posY="4" text="Codigo Cliente"/>
|
||||
<Edit colName="tipo_cliente" fieldId="7" gridHeight="1" gridWidth="3" name="tipo_cliente" posX="19" posY="4" sqlTabName="formonly" tabIndex="7" widget="Edit"/>
|
||||
<Label gridHeight="1" gridWidth="1" name="label7" posX="23" posY="4" text="-"/>
|
||||
<Edit colName="sec_cliente" fieldId="8" gridHeight="1" gridWidth="6" name="sec_cliente" posX="25" posY="4" sqlTabName="formonly" tabIndex="8" widget="Edit"/>
|
||||
<Label gridHeight="1" gridWidth="15" name="label8" posX="3" posY="5" text="Nombre Cliente"/>
|
||||
<Edit colName="nombre_cliente" comment="Utilice el simbolo (*) para buscar nombres similares al que desea" fieldId="6" gridHeight="1" gridWidth="47" name="nombre_cliente" posX="19" posY="5" sqlTabName="formonly" tabIndex="9" widget="Edit"/>
|
||||
<Label gridHeight="1" gridWidth="13" name="label9" posX="3" posY="6" text="Telefono Res."/>
|
||||
<Edit colName="telefono_r" fieldId="9" gridHeight="1" gridWidth="15" name="telefono_r" posX="19" posY="6" sqlTabName="formonly" tabIndex="10" widget="Edit"/>
|
||||
<Label gridHeight="1" gridWidth="8" name="label10" posX="3" posY="7" text="Producto"/>
|
||||
<Edit colName="cod_n" fieldId="1" gridHeight="1" gridWidth="5" name="cod_n" posX="19" posY="7" sqlTabName="formonly" tabIndex="11" widget="Edit"/>
|
||||
<Edit colName="cod_grupo" fieldId="2" gridHeight="1" gridWidth="6" name="cod_grupo" posX="26" posY="7" sqlTabName="formonly" tabIndex="12" widget="Edit"/>
|
||||
<Edit colName="cod_tipo" fieldId="3" gridHeight="1" gridWidth="6" name="cod_tipo" posX="34" posY="7" sqlTabName="formonly" tabIndex="13" widget="Edit"/>
|
||||
<Edit colName="cod_sec" fieldId="4" gridHeight="1" gridWidth="7" name="cod_sec" posX="42" posY="7" sqlTabName="formonly" tabIndex="14" widget="Edit"/>
|
||||
<Label gridHeight="1" gridWidth="15" name="label11" posX="3" posY="8" text="Salida Reporte"/>
|
||||
<ComboBox colName="salida" defaultValue="Detallado" fieldId="14" gridHeight="1" gridWidth="15" items="Detallado, Resumido" name="salida" posX="19" posY="8" sqlTabName="formonly" tabIndex="15" widget="ComboBox">
|
||||
<Item name="prprrp116.4rp" text="Detallado"/>
|
||||
<Item name="prprrp016a.4rp" text="Resumido"/>
|
||||
</ComboBox>
|
||||
<Label gridHeight="1" gridWidth="13" name="label12" posX="3" posY="9" text="Visualizacion"/>
|
||||
<ComboBox colName="visualiza" defaultValue="PANTALLA" fieldId="15" gridHeight="1" gridWidth="15" items="PANTALLA, ACROBAT READER, EXCEL" name="visualiza" posX="19" posY="9" sqlTabName="formonly" tabIndex="16" widget="ComboBox">
|
||||
<Item name="SVG" text="PANTALLA"/>
|
||||
<Item name="PDF" text="ACROBAT READER"/>
|
||||
<Item name="XLSX" text="EXCEL"/>
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
</Form>
|
||||
</ManagedForm>
|
||||
@@ -48,7 +48,7 @@ DATEEDIT f1 = formonly.fecha type date,format = "dd/mm/yyyy";
|
||||
o1 = formonly.num_oc,comments="Digite un numero de orden o deje en blanco para todas";
|
||||
v1 = formonly.sec_vend,comments="Digite un numero de vendedor o deje en blanco para todos";
|
||||
COMBOBOX s=formonly.salida,ITEMS=(("prprrp116.4rp","Detallado"),("prprrp016a.4rp","Resumido")),default="Detallado";
|
||||
COMBOBOX v=formonly.visualiza,ITEMS=(("SVG","PANTALLA"),("PDF","ACROBAT READER")),default="PANTALLA";
|
||||
COMBOBOX v=formonly.visualiza,ITEMS=(("SVG","PANTALLA"),("PDF","ACROBAT READER"),("XLSX","EXCEL")),default="PANTALLA";
|
||||
instructions
|
||||
delimiters " "
|
||||
end
|
||||
|
||||
@@ -71,7 +71,9 @@ DEFINE hoy DATE
|
||||
END INPUT
|
||||
|
||||
CONSTRUCT BY NAME criterio ON a.tipo_cliente,a.sec_cliente,
|
||||
a.num_oc,a.fecha
|
||||
a.num_oc,a.fecha_oc
|
||||
FROM tipo_cliente,sec_cliente,
|
||||
num_oc,fecha
|
||||
|
||||
AFTER CONSTRUCT
|
||||
IF tipo_orden = 'N' THEN
|
||||
|
||||
@@ -79,6 +79,8 @@ FUNCTION prprrp016()
|
||||
END RECORD,
|
||||
salida,visualiza CHAR(20)
|
||||
|
||||
DEFINE hay_datos SMALLINT
|
||||
|
||||
OPTIONS
|
||||
PROMPT LINE 23,
|
||||
FORM LINE 8,
|
||||
@@ -201,12 +203,46 @@ FUNCTION prprrp016()
|
||||
"WHERE ",criterio clipped,
|
||||
" and a.status_t is null and f.status_t is null "
|
||||
|
||||
END IF
|
||||
END IF
|
||||
PREPARE comando FROM selec
|
||||
DECLARE busca CURSOR FOR comando
|
||||
|
||||
-- Verifica primero si hay registros: si el reporte se inicia sin filas,
|
||||
-- el motor de reportes falla al no poder resolver p_compania.nombre
|
||||
-- (variable "look ahead" del encabezado) porque nunca se llega a imprimir nada.
|
||||
OPEN busca
|
||||
FETCH busca INTO busqueda.cotizacion_no,busqueda.fecha,busqueda.tipo_cliente,
|
||||
busqueda.sec_cliente,busqueda.nombre_proyecto,busqueda.direccion_proyecto,
|
||||
busqueda.telefono_r,busqueda.nombre,busqueda.num_oc,busqueda.fecha_oc,
|
||||
busqueda.fecha_entrega,busqueda.fecha_cierre,busqueda.cod_n,
|
||||
busqueda.cod_grupo,busqueda.cod_tipo,busqueda.cod_sec,
|
||||
busqueda.descrip_esp,busqueda.unidad_med,busqueda.cantidad,
|
||||
busqueda.precio,busqueda.cantidad_2,busqueda.cod_mov,
|
||||
busqueda.fecha_doc,busqueda.documento,busqueda.status_mov,
|
||||
busqueda.simbolo,busqueda.vendedor,busqueda.monto_cotizacion,
|
||||
busqueda.condicion,busqueda.estado_orden,busqueda.telefono,
|
||||
busqueda.celular,busqueda.email,busqueda.contacto
|
||||
IF STATUS = NOTFOUND THEN
|
||||
CALL fgl_winmessage("WARNING","NO EXISTEN REGISTROS CON ESA CONDICION","SOP")
|
||||
LET hay_datos = FALSE
|
||||
ELSE
|
||||
LET hay_datos = TRUE
|
||||
END IF
|
||||
|
||||
# El formulario solo guarda el texto visible del combo (no el valor interno
|
||||
# que tenia el .per original), asi que aqui se traduce de vuelta.
|
||||
CASE salida CLIPPED
|
||||
WHEN "Detallado" LET salida = "prprrp116.4rp"
|
||||
WHEN "Resumido" LET salida = "prprrp016a.4rp"
|
||||
END CASE
|
||||
CASE visualiza CLIPPED
|
||||
WHEN "PANTALLA" LET visualiza = "SVG"
|
||||
WHEN "ACROBAT READER" LET visualiza = "PDF"
|
||||
WHEN "EXCEL" LET visualiza = "XLSX"
|
||||
END CASE
|
||||
|
||||
LET r_filename = salida CLIPPED
|
||||
|
||||
|
||||
IF fgl_report_loadCurrentSettings(r_filename) THEN -- load the .4rp file
|
||||
LET r_output=visualiza CLIPPED
|
||||
LET preview=1
|
||||
@@ -216,30 +252,13 @@ FUNCTION prprrp016()
|
||||
END IF
|
||||
|
||||
|
||||
IF handler IS NOT NULL THEN -- report engine was configured ok
|
||||
IF handler IS NOT NULL AND hay_datos THEN -- report engine was configured ok and there is data to print
|
||||
|
||||
START REPORT reporte_16 TO XML HANDLER handler
|
||||
|
||||
|
||||
|
||||
FOREACH busca INTO busqueda.cotizacion_no,busqueda.fecha,busqueda.tipo_cliente,
|
||||
busqueda.sec_cliente,busqueda.nombre_proyecto,busqueda.direccion_proyecto,
|
||||
busqueda.telefono_r,busqueda.nombre,busqueda.num_oc,busqueda.fecha_oc,
|
||||
busqueda.fecha_entrega,busqueda.fecha_cierre,busqueda.cod_n,
|
||||
busqueda.cod_grupo,busqueda.cod_tipo,busqueda.cod_sec,
|
||||
busqueda.descrip_esp,busqueda.unidad_med,busqueda.cantidad,
|
||||
busqueda.precio,busqueda.cantidad_2,busqueda.cod_mov,
|
||||
busqueda.fecha_doc,busqueda.documento,busqueda.status_mov,
|
||||
busqueda.simbolo,busqueda.vendedor,busqueda.monto_cotizacion,
|
||||
busqueda.condicion,busqueda.estado_orden,busqueda.telefono,
|
||||
busqueda.celular,busqueda.email,busqueda.contacto
|
||||
|
||||
|
||||
|
||||
IF STATUS = NOTFOUND THEN
|
||||
CALL fgl_winmessage("WARNING","NO EXISTEN REGISTROS CON ESA CONDICION","SOP")
|
||||
EXIT FOREACH
|
||||
END IF
|
||||
-- La primera fila ya fue leida arriba (para saber si hay_datos); aqui se
|
||||
-- procesa esa fila y se sigue con FETCH manual hasta agotar el cursor.
|
||||
WHILE hay_datos
|
||||
IF busqueda.cantidad_2 IS NULL THEN
|
||||
LET busqueda.cantidad_2 = 0
|
||||
END IF
|
||||
@@ -247,7 +266,7 @@ IF handler IS NOT NULL THEN -- report engine was configured ok
|
||||
LET busqueda.fecha_avance= NULL
|
||||
LET busqueda.monto_avance = NULL
|
||||
|
||||
SELECT MAX(a.num_doc),MAX(a.fecha_orig)
|
||||
SELECT MAX(a.num_doc),MAX(a.fecha_orig)
|
||||
INTO busqueda.avance,busqueda.fecha_avance,
|
||||
busqueda.monto_avance
|
||||
FROM cctb00001 a
|
||||
@@ -255,7 +274,7 @@ IF handler IS NOT NULL THEN -- report engine was configured ok
|
||||
a.tipo_Doc = 'AV' and a.tipo_cliente = busqueda.tipo_cliente and
|
||||
a.sec_cliente = busqueda.sec_cliente and a.status_t is null and
|
||||
a.fecha_orig > '08/01/2009'
|
||||
|
||||
|
||||
LET busqueda.codigo = busqueda.cod_n using "&&&&","-",
|
||||
busqueda.cod_grupo USING "&&&&","-",
|
||||
busqueda.cod_tipo USING "&&&&","-",
|
||||
@@ -266,11 +285,27 @@ IF handler IS NOT NULL THEN -- report engine was configured ok
|
||||
IF busqueda.estado_orden = "S" THEN
|
||||
LET busqueda.estado_orden = "CERRADA"
|
||||
END IF
|
||||
|
||||
|
||||
OUTPUT TO REPORT reporte_16(busqueda.*)
|
||||
END FOREACH
|
||||
|
||||
FETCH busca INTO busqueda.cotizacion_no,busqueda.fecha,busqueda.tipo_cliente,
|
||||
busqueda.sec_cliente,busqueda.nombre_proyecto,busqueda.direccion_proyecto,
|
||||
busqueda.telefono_r,busqueda.nombre,busqueda.num_oc,busqueda.fecha_oc,
|
||||
busqueda.fecha_entrega,busqueda.fecha_cierre,busqueda.cod_n,
|
||||
busqueda.cod_grupo,busqueda.cod_tipo,busqueda.cod_sec,
|
||||
busqueda.descrip_esp,busqueda.unidad_med,busqueda.cantidad,
|
||||
busqueda.precio,busqueda.cantidad_2,busqueda.cod_mov,
|
||||
busqueda.fecha_doc,busqueda.documento,busqueda.status_mov,
|
||||
busqueda.simbolo,busqueda.vendedor,busqueda.monto_cotizacion,
|
||||
busqueda.condicion,busqueda.estado_orden,busqueda.telefono,
|
||||
busqueda.celular,busqueda.email,busqueda.contacto
|
||||
IF STATUS = NOTFOUND THEN
|
||||
LET hay_datos = FALSE
|
||||
END IF
|
||||
END WHILE
|
||||
FINISH REPORT reporte_16
|
||||
END IF
|
||||
CLOSE busca
|
||||
|
||||
|
||||
AFTER DIALOG
|
||||
@@ -349,7 +384,7 @@ BEFORE GROUP OF x.cotizacion_no
|
||||
|
||||
PRINTX x.cotizacion_no,x.direccion_proyecto,x.nombre_proyecto,
|
||||
x.tipo_cliente,x.sec_cliente,x.telefono_r,x.num_oc,x.fecha,x.fecha_cierre,
|
||||
x.fecha_entrega,x.fecha_oc
|
||||
x.fecha_entrega,x.fecha_oc,p_compania.nombre
|
||||
|
||||
|
||||
BEFORE GROUP OF x.codigo
|
||||
|
||||
@@ -20,7 +20,7 @@ DEFINE
|
||||
DEFINE
|
||||
dias, registros, pcod_sp, numero_entrada SMALLINT,
|
||||
secuencia_entrada INT,
|
||||
xentrada VARCHAR(14),
|
||||
xentrada VARCHAR(25),
|
||||
nom1_emp, nom2_Emp, apell1_Emp, apell2_emp VARCHAR(30),
|
||||
num_doccxp, num_doccxc VARCHAR(25)
|
||||
|
||||
|
||||
@@ -35,7 +35,27 @@ DEFINE xusername,xsmtphost,xsmtpport,xpassword STRING,
|
||||
|
||||
toEmail, orden_trabajo, answer_workorder, descrip_depto STRING, depto INT
|
||||
|
||||
DEFINE data RECORD LIKE cotb00001.*
|
||||
DEFINE data RECORD
|
||||
area_sp VARCHAR(10),
|
||||
ciu_sp VARCHAR(30),
|
||||
cod_pais VARCHAR(3),
|
||||
cod_sp SMALLINT,
|
||||
cod_sp_sec SMALLINT,
|
||||
cont_sp VARCHAR(30),
|
||||
contactID INTEGER,
|
||||
dir_sp VARCHAR(60),
|
||||
email VARCHAR(60),
|
||||
fax_sp VARCHAR(25),
|
||||
fech_crea DATETIME YEAR TO FRACTION,
|
||||
fech_mod DATETIME YEAR TO FRACTION,
|
||||
id_maintainx INTEGER,
|
||||
nom_sp VARCHAR(41),
|
||||
status_t VARCHAR(1),
|
||||
tel_sp VARCHAR(25),
|
||||
term_sp SMALLINT,
|
||||
us_crea VARCHAR(50),
|
||||
us_mod VARCHAR(50)
|
||||
END RECORD
|
||||
|
||||
DEFINE container RECORD
|
||||
tipo_inv STRING,
|
||||
|
||||
@@ -1596,7 +1596,7 @@ FUNCTION cppcmd000()
|
||||
END IF
|
||||
END FOR
|
||||
|
||||
IF entradas_atadas[0].entrada IS NOT NULL THEN
|
||||
IF entradas_atadas[1].entrada IS NOT NULL THEN
|
||||
DELETE FROM cptb00010
|
||||
WHERE num_doc = factura.num_doc
|
||||
AND cod_sp = factura.cod_sp
|
||||
|
||||
+62
-4
@@ -330,8 +330,65 @@
|
||||
</Library>
|
||||
</Group>
|
||||
<Group id="202834315" label="MATERIA PRIMA">
|
||||
<Library binaryName="FORMULARIOS_IN" id="-863149381" label="FORMULARIOS_IN"/>
|
||||
<Library binaryName="FUNCIONES_IN" id="-801525068" label="FUNCIONES_IN"/>
|
||||
<Library binaryName="FORMULARIOS_IN" id="-863149381" label="FORMULARIOS_IN">
|
||||
<File filePath="../PROYECTOS/indir/infmmt002.per"/>
|
||||
<File filePath="../PROYECTOS/indir/infmmt005.per"/>
|
||||
</Library>
|
||||
<Library binaryName="FUNCIONES_IN" dependencies="-1026233879" id="-801525068" label="FUNCIONES_IN">
|
||||
<File filePath="../PROYECTOS/indir/inprgb000.4gl"/>
|
||||
</Library>
|
||||
<Application binaryName="inprmt002" dependencies="-801525068,-1026233879,-764824792" id="-900000001" label="inprmt002">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000002" label="Configuration"/>
|
||||
<File filePath="../PROYECTOS/indir/inprmt002.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprmt005" dependencies="-801525068,-1026233879,-764824792" id="-900000003" label="inprmt005">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000004" label="Configuration"/>
|
||||
<File filePath="../PROYECTOS/indir/inprmt005.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprmt013" dependencies="-801525068,-1026233879,-764824792" id="-900000005" label="inprmt013">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000006" label="Configuration"/>
|
||||
<File filePath="../PROYECTOS/indir/inprmt013.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprmt046" dependencies="-801525068,-1026233879,-764824792" id="-900000007" label="inprmt046">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000008" label="Configuration"/>
|
||||
<File filePath="../PROYECTOS/indir/inprmt046.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprmt036" dependencies="-801525068,-1026233879,-764824792" id="-900000009" label="inprmt036">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000010" label="Configuration"/>
|
||||
<File filePath="../PROYECTOS/indir/inprmt036.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprmt066" dependencies="-801525068,-1026233879,-764824792" id="-900000011" label="inprmt066">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000012" label="Configuration"/>
|
||||
<File filePath="../PROYECTOS/indir/inprmt066.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprcs006" dependencies="-801525068,-1026233879,-764824792" id="-900000013" label="inprcs006">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000014" label="Configuration"/>
|
||||
<File filePath="../PROYECTOS/indir/inprcs006.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprrp003" dependencies="-801525068,-1026233879,-764824792" externalDependencies="libgre.42x" id="-900000015" label="inprrp003">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000016" label="Configuration"/>
|
||||
<File compilerOptions="--build-rdd" filePath="../PROYECTOS/indir/inprrp003.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprrp005" dependencies="-801525068,-1026233879,-764824792" externalDependencies="libgre.42x" id="-900000017" label="inprrp005">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000018" label="Configuration"/>
|
||||
<File compilerOptions="--build-rdd" filePath="../PROYECTOS/indir/inprrp005.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprrp008" dependencies="-801525068,-1026233879,-764824792" externalDependencies="libgre.42x" id="-900000019" label="inprrp008">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000020" label="Configuration"/>
|
||||
<File compilerOptions="--build-rdd" filePath="../PROYECTOS/indir/inprrp008.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprrp009" dependencies="-801525068,-1026233879,-764824792" externalDependencies="libgre.42x" id="-900000021" label="inprrp009">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000022" label="Configuration"/>
|
||||
<File compilerOptions="--build-rdd" filePath="../PROYECTOS/indir/inprrp009.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprrp028" dependencies="-801525068,-1026233879,-764824792" externalDependencies="libgre.42x" id="-900000023" label="inprrp028">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000024" label="Configuration"/>
|
||||
<File compilerOptions="--build-rdd" filePath="../PROYECTOS/indir/inprrp028.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="inprrp011" dependencies="-801525068,-1026233879,-764824792" externalDependencies="libgre.42x" id="-900000025" label="inprrp011">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-900000026" label="Configuration"/>
|
||||
<File compilerOptions="--build-rdd" filePath="../PROYECTOS/indir/inprrp011.4gl"/>
|
||||
</Application>
|
||||
</Group>
|
||||
<Group id="1302820616" label="NOMINA">
|
||||
<Library binaryName="FORMULARIOS_NO" id="-335228674" label="FORMULARIOS_NO"/>
|
||||
@@ -370,7 +427,7 @@
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="-974560942" label="Configuration"/>
|
||||
<File compilerOptions="--build-rdd" filePath="PRDIR/prprmt021.4gl"/>
|
||||
</Application>
|
||||
<Application binaryName="prprmt020" dependencies="-837156229,-1026233879,-764824792" id="-358374666" label="prprmt020">
|
||||
<Application binaryName="prprmt020" dependencies="-837156229,-1026233879,-764824792,493047263" id="-358374666" label="prprmt020">
|
||||
<Configuration commandLineArguments="jpeguero Peguero2023" id="240197034" label="Configuration"/>
|
||||
<File filePath="PRDIR/prprmt020.4gl"/>
|
||||
</Application>
|
||||
@@ -387,7 +444,7 @@
|
||||
<File compilerOptions="--build-rdd" filePath="PRDIR/prprrp116.4gl"/>
|
||||
</Application>
|
||||
<Library binaryName="FORMULARIOS_PR" dependencies="-1026233879" id="-956683955" label="FORMULARIOS_PR">
|
||||
<File filePath="PRDIR/prfmrp116.per"/>
|
||||
<File filePath="PRDIR/prfmrp116.4fd"/>
|
||||
<File filePath="PRDIR/prfmmt008.4fd"/>
|
||||
<File filePath="vedir/vefmwd002.4fd"/>
|
||||
<File filePath="ctdir/prfmmt003.per"/>
|
||||
@@ -420,6 +477,7 @@
|
||||
<File filePath="PRDIR/pretiquetas.4gl"/>
|
||||
<File filePath="PRDIR/prempacar.4gl"/>
|
||||
<File filePath="otrodir/bcode128.4gl"/>
|
||||
<File filePath="../PROYECTOS/otrodir/codmov.4gl"/>
|
||||
</Library>
|
||||
</Group>
|
||||
<Group id="46006545" label="RECURSOS HUMANOS">
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<RecordField colName="m_meses" fieldIdRef="0" name="m_meses" sqlTabName="formonly" uid="{a86d2184-b2b8-4d43-9290-5734a571188e}"/>
|
||||
<RecordField colName="dias1" fieldIdRef="1" name="dias1" sqlTabName="formonly" uid="{941f7da0-4442-4cef-a4f2-b5e701ef9adb}"/>
|
||||
<RecordField colName="cod_cat" fieldIdRef="2" name="cod_cat" sqlTabName="formonly" uid="{e66efc0a-8770-4d48-8f6e-35122ee73b09}"/>
|
||||
<RecordField colName="tipo_reporte" fieldIdRef="10" name="tipo_reporte" sqlTabName="formonly" uid="{b1c2d3e4-1013-4a10-9a10-000000000010}"/>
|
||||
<RecordField colName="cod_n" fieldIdRef="6" fieldType="TABLE_COLUMN" name="intb00001.cod_n" sqlTabName="intb00001" uid="{cd27b48c-6a61-412e-99b5-7c46aa76c481}"/>
|
||||
<RecordField colName="cod_grupo" fieldIdRef="7" fieldType="TABLE_COLUMN" name="intb00001.cod_grupo" sqlTabName="intb00001" uid="{494ef5de-3185-48f2-8cc3-b8bd0d5250cf}"/>
|
||||
<RecordField colName="cod_tipo" fieldIdRef="8" fieldType="TABLE_COLUMN" name="intb00001.cod_tipo" sqlTabName="intb00001" uid="{e8caebc6-7e5e-400a-b9b2-6431d073a46f}"/>
|
||||
@@ -37,6 +38,8 @@
|
||||
<Edit colName="cod_tipo" comment="Digite el TIPO" fieldId="8" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="4" name="intb00001.cod_tipo" posX="52" posY="5" sqlTabName="intb00001" tabIndex="9" widget="Edit"/>
|
||||
<Label gridHeight="1" gridWidth="1" name="label10" posX="57" posY="5" text="-"/>
|
||||
<Edit colName="cod_sec" comment="Digite la SECUENCIA" fieldId="9" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="4" name="intb00001.cod_sec" posX="59" posY="5" sqlTabName="intb00001" tabIndex="10" widget="Edit"/>
|
||||
<Label gridHeight="1" gridWidth="12" name="label11" posX="10" posY="7" text="Tipo Reporte"/>
|
||||
<ComboBox colName="tipo_reporte" comment="Detallado (por producto) o Resumen (por clase)" fieldId="10" gridHeight="1" gridWidth="25" items="" name="tipo_reporte" posX="25" posY="7" sqlTabName="formonly" tabIndex="11" widget="ComboBox"/>
|
||||
</Grid>
|
||||
</Form>
|
||||
<DiagramLayout>
|
||||
|
||||
@@ -7,6 +7,7 @@ screen size 24 by 80
|
||||
Dias consumo [p1 ]
|
||||
Categorias [ca1 ]
|
||||
Codigo del Prod. Terminado [a ]-[b ]-[c ]-[d ]
|
||||
Tipo Reporte [tr ]
|
||||
}
|
||||
end
|
||||
tables
|
||||
@@ -15,6 +16,7 @@ attributes
|
||||
ll = formonly.m_meses;
|
||||
p1 = formonly.dias1;
|
||||
COMBOBOX ca1=formonly.cod_cat;
|
||||
COMBOBOX tr=formonly.tipo_reporte;
|
||||
DATEEDIT k1 = formonly.fecha1 type date,format = "dd/mm/yy",
|
||||
comments = "Digite la fecha inicial. Utilice el formato 'DDMMAA'";
|
||||
DATEEDIT k2 = formonly.fecha2 type date,format = "dd/mm/yy",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<RecordField fieldIdRef="10" name="representa" uid="{a33da8bb-5056-4822-9800-277a3e3aff34}"/>
|
||||
<RecordField defaultValue="NO" fieldIdRef="11" name="chexistencia" uid="{de68d342-97e5-4a64-af4d-c31664950aaa}"/>
|
||||
<RecordField fieldIdRef="12" name="progreso" uid="{97aa7412-688e-4594-93e6-9c2366fdee1d}"/>
|
||||
<RecordField colName="tipo_reporte" fieldIdRef="13" name="tipo_reporte" sqlTabName="formonly" uid="{b1c2d3e4-1014-4a14-9a14-000000000014}"/>
|
||||
</Record>
|
||||
<Form gridHeight="24" gridWidth="80" name="ipfmrp013">
|
||||
<Grid gridHeight="24" gridWidth="80" name="grid1" posX="0" posY="0">
|
||||
@@ -44,7 +45,9 @@
|
||||
<Edit colName="cod_grupo" comment="Digite el GRUPO" fieldId="7" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="4" name="intb00001.cod_grupo" posX="45" posY="7" sqlTabName="intb00001" tabIndex="8" widget="Edit"/>
|
||||
<Edit colName="cod_tipo" comment="Digite el TIPO" fieldId="8" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="4" name="intb00001.cod_tipo" posX="52" posY="7" sqlTabName="intb00001" tabIndex="9" widget="Edit"/>
|
||||
<Edit colName="cod_sec" comment="Digite la SECUENCIA" fieldId="9" fieldType="TABLE_COLUMN" gridHeight="1" gridWidth="4" name="intb00001.cod_sec" posX="59" posY="7" sqlTabName="intb00001" tabIndex="10" widget="Edit"/>
|
||||
<ProgressBar fieldId="12" gridHeight="1" gridWidth="27" name="progreso" posX="10" posY="9" title="progressbar1" valueMin="10" widget="ProgressBar"/>
|
||||
<Label gridHeight="1" gridWidth="12" name="label11" posX="10" posY="8" text="Tipo Reporte"/>
|
||||
<ComboBox colName="tipo_reporte" comment="Detallado (por producto) o Resumen (por clase)" fieldId="13" gridHeight="1" gridWidth="25" items="" name="tipo_reporte" posX="25" posY="8" sqlTabName="formonly" tabIndex="11" widget="ComboBox"/>
|
||||
<ProgressBar fieldId="12" gridHeight="1" gridWidth="27" name="progreso" posX="10" posY="10" title="progressbar1" valueMin="10" widget="ProgressBar"/>
|
||||
</Grid>
|
||||
</Form>
|
||||
<DiagramLayout>
|
||||
|
||||
@@ -3319,6 +3319,12 @@ FUNCTION ipprad44()
|
||||
|
||||
PREPARE smt FROM procedimiento
|
||||
|
||||
# Guardia sobre el SP: por defecto WHENEVER ERROR STOP
|
||||
# detiene el programa si el SP lanza un error SQL (p.ej.
|
||||
# -3998 "transaccion no-confirmable"), sin llegar a la
|
||||
# validacion limpia de out_result. Lo capturamos para
|
||||
# revertir y avisar en vez de crashear.
|
||||
WHENEVER ERROR CONTINUE
|
||||
EXECUTE smt
|
||||
USING ordenx IN,
|
||||
--idx IN,
|
||||
@@ -3367,6 +3373,27 @@ FUNCTION ipprad44()
|
||||
out_cantidad_item OUT,
|
||||
out_cantidad_ubicacion OUT,
|
||||
out_msg OUT
|
||||
WHENEVER ERROR STOP
|
||||
|
||||
# Si el EXEC del SP fallo a nivel SQL (STATUS < 0), como el
|
||||
# -3998 que deja la transaccion doomed, revertir y avisar
|
||||
# limpiamente en vez de detener el programa.
|
||||
IF STATUS < 0 THEN
|
||||
DISPLAY "ERROR SQL sp_insert_inventario: ",
|
||||
STATUS, " ", SQLERRMESSAGE
|
||||
DISPLAY "ITEM: ",
|
||||
movi2[idx].cod_n, "-",
|
||||
movi2[idx].cod_grupo, "-",
|
||||
movi2[idx].cod_tipo, "-",
|
||||
movi2[idx].cod_sec
|
||||
DISPLAY "DOCUMENTO: ", otros_mov.num_doc,
|
||||
" MOV: ", otros_mov.cod_mov,
|
||||
" BODEGA: ", otros_mov.bodega
|
||||
ROLLBACK WORK
|
||||
LET numero_msg = 1679
|
||||
CALL msg(numero_msg)
|
||||
NEXT FIELD cod_n
|
||||
END IF
|
||||
|
||||
IF out_result <> 0 THEN
|
||||
|
||||
@@ -3396,7 +3423,13 @@ FUNCTION ipprad44()
|
||||
|
||||
DISPLAY "============================================"
|
||||
|
||||
# El SP pudo haber revertido ya la transaccion si
|
||||
# quedo condenada (CATCH con XACT_STATE = -1). Hacemos
|
||||
# este ROLLBACK tolerante para no crashear si ya no
|
||||
# hay transaccion activa.
|
||||
WHENEVER ERROR CONTINUE
|
||||
ROLLBACK WORK
|
||||
WHENEVER ERROR STOP
|
||||
|
||||
IF out_msg IS NOT NULL THEN
|
||||
ERROR out_msg
|
||||
|
||||
+315
-26
@@ -5,9 +5,40 @@ OBJETIVO : REPORTE DIAS DE INVENTARIOS
|
||||
PROGRAMADOR : Ing. Juan Francisco Soto
|
||||
FECHA REALIZACION : Agosto 19, 1992
|
||||
MODIFICADO POR : Ing. Juan Fco. Soto
|
||||
FECHA ULT. MODIFICA : Julio 19, 1993.
|
||||
FECHA ULT. MODIFICA : Agosto 20, 2026.
|
||||
DESCRIPCION : Agregar Columna Costo Standard para cantidades mayores a
|
||||
una cantidad de dias especificada.
|
||||
|
||||
AGOSTO 20, 2026 - ANALISIS DE MARGEN Y ROTACION:
|
||||
1. MARGEN DE BENEFICIO: se calcula el precio de venta
|
||||
REAL promedio del periodo (ponderado por cantidad,
|
||||
neto del descuento de cabecera) desde vetb00002/
|
||||
vetb00003, y el margen % sobre precio:
|
||||
margen = (precio - costo) / precio * 100
|
||||
El costo es el costo estandar (iptb00004), igual que
|
||||
antes. Se movio el calculo del costo ANTES del calculo
|
||||
del valor de exceso para que ese valor use el costo
|
||||
real (antes usaba costo = 0).
|
||||
2. ROTACION: igual que en ipprrp014:
|
||||
rotacion = consumo / existencia
|
||||
rotacion_anual = rotacion * (365 / dias del periodo)
|
||||
En este reporte el consumo son las SALIDAS del periodo
|
||||
(movs 30,31,55,56,40), que es la base correcta para la
|
||||
rotacion de inventario.
|
||||
3. CLASIFICACION por cuadrante (margen x rotacion):
|
||||
ESTRELLA = alto margen + alta rotacion
|
||||
VOLUMEN = bajo margen + alta rotacion
|
||||
NICHO = alto margen + baja rotacion
|
||||
REVISAR = bajo margen + baja rotacion (candidato
|
||||
a descontinuar / renegociar costo)
|
||||
SIN COSTO = producto sin costo estandar cargado
|
||||
Umbrales configurables (g_margen_min, g_rot_min).
|
||||
4. Se agregan valor_inv (existe*costo), ventas_valor
|
||||
(consumo*precio) y ganancia (consumo*(precio-costo))
|
||||
para poder totalizar el margen PONDERADO por CLASE en
|
||||
el disenio .4rp (grupo por cod_n).
|
||||
NOTA: el layout .4rp debe actualizarse en GST arrastrando
|
||||
los nuevos campos (ver guia adjunta).
|
||||
-------------------------------------------------------------------------------
|
||||
}
|
||||
GLOBALS "ipprgb000.4gl"
|
||||
@@ -19,6 +50,31 @@ DEFINE dias1 SMALLINT,
|
||||
m_meses SMALLINT,
|
||||
conmes,valor1 DECIMAL(12,2)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Umbrales de clasificacion (ajustables aqui, o promover a campos del form).
|
||||
# g_margen_min : margen % sobre precio a partir del cual se considera "alto"
|
||||
# g_rot_min : rotacion ANUALIZADA (veces/anio) a partir de la cual es "alta"
|
||||
# ------------------------------------------------------------------------------
|
||||
DEFINE g_margen_min DECIMAL(6,2)
|
||||
DEFINE g_rot_min DECIMAL(6,2)
|
||||
|
||||
# Acumulador por CLASE para el reporte Resumen (una fila por cod_n).
|
||||
# A nivel de modulo para que emite_clase() y ipprrp013() lo compartan.
|
||||
DEFINE rc RECORD
|
||||
cod_n INTEGER,
|
||||
nombre_clase CHAR(30),
|
||||
categoria CHAR(30),
|
||||
c_prod INTEGER,
|
||||
c_estrella INTEGER,
|
||||
c_revisar INTEGER,
|
||||
c_valor_inv DECIMAL(16,2),
|
||||
c_ventas DECIMAL(16,2),
|
||||
c_ganancia DECIMAL(16,2),
|
||||
c_margen DECIMAL(12,2),
|
||||
c_rot_prom DECIMAL(12,4)
|
||||
END RECORD
|
||||
DEFINE rc_rot_sum DECIMAL(16,4)
|
||||
|
||||
MAIN
|
||||
DEFER INTERRUPT
|
||||
CALL ARG_VAL(1) RETURNING usuarios
|
||||
@@ -33,6 +89,9 @@ FUNCTION ipprrp013()
|
||||
|
||||
# Variable que toma el valor de los dias que se va a valorar el reporte
|
||||
DEFINE c_dias INTEGER
|
||||
# Combo para elegir Detallado / Resumen
|
||||
DEFINE cbtipo ui.ComboBox
|
||||
DEFINE prev_cod_n INTEGER
|
||||
|
||||
# Variables varias para el control de busqueda de las informaciones
|
||||
DEFINE selec1,select_bal string
|
||||
@@ -66,7 +125,16 @@ DEFINE c_dias INTEGER
|
||||
costo DECIMAL(12,4),
|
||||
dias INTEGER,
|
||||
pcodigo char(25),
|
||||
cantidad_orden,pcantidadConduce,transito,existencia,reservado,disponible DEC(12,2)
|
||||
cantidad_orden,pcantidadConduce,transito,existencia,reservado,disponible DEC(12,2),
|
||||
# --- Analisis margen / rotacion (Agosto 2026) ---
|
||||
precio DEC(12,4), -- precio venta real prom. neto del periodo
|
||||
margen DEC(12,2), -- % sobre precio = (precio-costo)/precio*100
|
||||
rotacion DEC(12,4), -- consumo / existencia
|
||||
rotacion_anual DEC(12,4), -- rotacion * (365 / dias del periodo)
|
||||
valor_inv DEC(14,2), -- existencia * costo (valor inventario)
|
||||
ventas_valor DEC(14,2), -- consumo * precio (venta del periodo)
|
||||
ganancia DEC(14,2), -- consumo * (precio - costo)
|
||||
clasificacion CHAR(12) -- ESTRELLA/VOLUMEN/NICHO/REVISAR/SIN COSTO
|
||||
END RECORD
|
||||
DEFINE handler om.SaxDocumentHandler, -- return value from fgl_report_commitCurrentSettings()
|
||||
r_filename STRING, -- filename of Report Design Document including .4rp extension
|
||||
@@ -86,10 +154,28 @@ DEFINE c_dias INTEGER
|
||||
DISPLAY "Dias de Inventarios" AT 6,33 ATTRIBUTE(BLACK)
|
||||
LET tipo_papel = 2
|
||||
CALL msgrp000(tipo_papel)
|
||||
|
||||
|
||||
INPUT BY NAME fecha1,fecha2,c_dias,m_meses
|
||||
|
||||
# Umbrales de clasificacion margen/rotacion (ver DEFINE arriba)
|
||||
LET g_margen_min = 25.00
|
||||
LET g_rot_min = 2.00
|
||||
|
||||
|
||||
INPUT BY NAME fecha1,fecha2,c_dias,m_meses,tipo_reporte
|
||||
|
||||
BEFORE INPUT
|
||||
# Llena el combo Detallado / Resumen (mismo patron que categorias())
|
||||
LET cbtipo = ui.ComboBox.forName("formonly.tipo_reporte")
|
||||
IF cbtipo IS NOT NULL THEN
|
||||
CALL cbtipo.clear()
|
||||
CALL cbtipo.addItem("D","Detallado (por producto)")
|
||||
CALL cbtipo.addItem("R","Resumen (por clase)")
|
||||
END IF
|
||||
# Por defecto el reporte DETALLADO
|
||||
IF tipo_reporte IS NULL OR tipo_reporte = " " THEN
|
||||
LET tipo_reporte = "D"
|
||||
END IF
|
||||
DISPLAY BY NAME tipo_reporte
|
||||
|
||||
AFTER FIELD c_dias
|
||||
IF c_dias is null THEN
|
||||
LET numero_msg = 16
|
||||
@@ -117,6 +203,12 @@ DEFINE c_dias INTEGER
|
||||
CALL msg(numero_msg)
|
||||
NEXT FIELD m_meses
|
||||
END IF
|
||||
|
||||
AFTER FIELD tipo_reporte
|
||||
IF tipo_reporte IS NULL OR tipo_reporte = " " THEN
|
||||
LET tipo_reporte = "D"
|
||||
DISPLAY BY NAME tipo_reporte
|
||||
END IF
|
||||
END INPUT
|
||||
|
||||
IF int_flag THEN
|
||||
@@ -229,9 +321,17 @@ DEFINE c_dias INTEGER
|
||||
DECLARE consu SCROLL CURSOR FOR busca_balan
|
||||
OPEN consu USING fecha2
|
||||
}
|
||||
LET r_filename = "ipprrp013.4rp"
|
||||
|
||||
LET idx = 1
|
||||
# Elige el disenio .4rp segun la opcion del formulario:
|
||||
# D = Detallado (una linea por producto) -> ipprrp013.4rp
|
||||
# R = Resumen (subtotales por CLASE cod_n) -> ipprrp013r.4rp
|
||||
IF tipo_reporte = "R" THEN
|
||||
LET r_filename = "ipprrp013r.4rp"
|
||||
ELSE
|
||||
LET r_filename = "ipprrp013.4rp"
|
||||
END IF
|
||||
|
||||
LET idx = 1
|
||||
LET prev_cod_n = -999999
|
||||
FOREACH accion INTO estadis.*
|
||||
|
||||
LET estadis.pcodigo = estadis.cod_n USING "&&&&","-",
|
||||
@@ -261,10 +361,14 @@ DEFINE c_dias INTEGER
|
||||
END IF
|
||||
--run the report
|
||||
IF handler IS NOT NULL THEN -- report engine was configured ok
|
||||
START REPORT estadistica TO XML HANDLER HANDLER
|
||||
IF tipo_reporte = "R" THEN
|
||||
START REPORT resumen TO XML HANDLER HANDLER
|
||||
ELSE
|
||||
EXIT FOREACH
|
||||
END IF
|
||||
START REPORT estadistica TO XML HANDLER HANDLER
|
||||
END IF
|
||||
ELSE
|
||||
EXIT FOREACH
|
||||
END IF
|
||||
END IF
|
||||
|
||||
{LET sale = "N"
|
||||
@@ -299,7 +403,18 @@ END WHILE
|
||||
valororden
|
||||
|
||||
LET estadis.existe = estadis.existencia
|
||||
# Calculo para los dias de produccion
|
||||
|
||||
# ---- COSTO ESTANDAR (movido aqui para que el valor de exceso Y el margen
|
||||
# usen el costo real; antes se calculaba despues y quedaba en cero) ----
|
||||
LET estadis.costo = 0
|
||||
SELECT AVG(a.material+a.labor+a.gastos) INTO estadis.costo FROM iptb00004 a
|
||||
WHERE a.ano = YEAR(TODAY) AND a.mes_fin = 12
|
||||
AND a.cod_n = estadis.cod_n AND a.cod_grupo = estadis.cod_grupo
|
||||
AND a.cod_tipo = estadis.cod_tipo AND a.cod_sec = estadis.cod_sec
|
||||
AND a.status_t IS NULL
|
||||
IF estadis.costo IS NULL THEN LET estadis.costo = 0 END IF
|
||||
|
||||
# Calculo para los dias de produccion
|
||||
IF estadis.existe > 0 THEN
|
||||
LET estadis.cantidad_orden = estadis.cantidad_orden - estadis.pcantidadConduce
|
||||
LET estadis.disponible=estadis.existe -estadis.cantidad_orden - estadis.reservado
|
||||
@@ -328,30 +443,139 @@ IF estadis.dias >= c_dias THEN
|
||||
LET estadis.valor = 0
|
||||
END IF
|
||||
END IF
|
||||
# Costo STD
|
||||
LET estadis.costo=0
|
||||
SELECT AVG(a.material+a.labor+a.gastos) INTO estadis.costo FROM iptb00004 a
|
||||
WHERE a.ano = YEAR(TODAY) AND a.mes_fin = 12
|
||||
AND a.cod_n = estadis.cod_n AND a.cod_grupo = estadis.cod_grupo AND a.cod_tipo = estadis.cod_tipo AND
|
||||
a.cod_sec = estadis.cod_sec
|
||||
AND a.status_t IS NULL
|
||||
DISPLAY "DATA DESPUES ",estadis.existe
|
||||
|
||||
# ============================================================================
|
||||
# MARGEN DE BENEFICIO Y ROTACION
|
||||
# ============================================================================
|
||||
# Precio de venta REAL promedio del periodo, ponderado por cantidad y neto del
|
||||
# descuento de cabecera (porc_desc). Fuente: facturas vetb00002 + detalle
|
||||
# vetb00003 con fecha_factura dentro del rango [fecha1, fecha2].
|
||||
LET estadis.precio = 0
|
||||
SELECT SUM(d.cantidad * d.precio * (1 - (ISNULL(h.porc_desc,0)/100.0)))
|
||||
/ NULLIF(SUM(d.cantidad),0)
|
||||
INTO estadis.precio
|
||||
FROM vetb00003 d, vetb00002 h
|
||||
WHERE d.factura = h.factura
|
||||
AND d.cod_n = estadis.cod_n AND d.cod_grupo = estadis.cod_grupo
|
||||
AND d.cod_tipo = estadis.cod_tipo AND d.cod_sec = estadis.cod_sec
|
||||
AND h.status_t IS NULL AND d.status_t IS NULL
|
||||
AND h.fecha_factura BETWEEN fecha1 AND fecha2
|
||||
IF estadis.precio IS NULL THEN LET estadis.precio = 0 END IF
|
||||
|
||||
# Margen % sobre precio = (precio - costo) / precio * 100
|
||||
IF estadis.precio > 0 AND estadis.costo > 0 THEN
|
||||
LET estadis.margen = ((estadis.precio - estadis.costo) / estadis.precio) * 100
|
||||
ELSE
|
||||
LET estadis.margen = 0
|
||||
END IF
|
||||
|
||||
# Rotacion (misma formula que ipprrp014): consumo / existencia
|
||||
# anualizada = rotacion * (365 / dias del periodo) -- 365.0 evita div. entera
|
||||
IF estadis.existe > 0 AND estadis.consumo > 0 THEN
|
||||
LET estadis.rotacion = estadis.consumo / estadis.existe
|
||||
LET estadis.rotacion_anual = estadis.rotacion * (365.0 / dias1)
|
||||
ELSE
|
||||
LET estadis.rotacion = 0
|
||||
LET estadis.rotacion_anual = 0
|
||||
END IF
|
||||
|
||||
# Valores para totalizar el margen PONDERADO por CLASE en el .4rp
|
||||
LET estadis.valor_inv = estadis.existe * estadis.costo
|
||||
LET estadis.ventas_valor = estadis.consumo * estadis.precio
|
||||
LET estadis.ganancia = estadis.consumo * (estadis.precio - estadis.costo)
|
||||
|
||||
# Clasificacion por cuadrante (margen x rotacion)
|
||||
CASE
|
||||
WHEN estadis.costo <= 0
|
||||
LET estadis.clasificacion = "SIN COSTO"
|
||||
WHEN estadis.margen >= g_margen_min AND estadis.rotacion_anual >= g_rot_min
|
||||
LET estadis.clasificacion = "ESTRELLA"
|
||||
WHEN estadis.margen < g_margen_min AND estadis.rotacion_anual >= g_rot_min
|
||||
LET estadis.clasificacion = "VOLUMEN"
|
||||
WHEN estadis.margen >= g_margen_min AND estadis.rotacion_anual < g_rot_min
|
||||
LET estadis.clasificacion = "NICHO"
|
||||
OTHERWISE
|
||||
LET estadis.clasificacion = "REVISAR"
|
||||
END CASE
|
||||
|
||||
IF estadis.existe > 0 THEN
|
||||
OUTPUT TO REPORT estadistica(estadis.*,dias1,c_dias)
|
||||
IF tipo_reporte = "R" THEN
|
||||
# --- Agregacion por CLASE: al cambiar cod_n, emite la clase anterior ---
|
||||
IF prev_cod_n <> estadis.cod_n THEN
|
||||
IF prev_cod_n <> -999999 THEN
|
||||
CALL emite_clase()
|
||||
END IF
|
||||
# Nueva clase: reinicia acumuladores
|
||||
LET prev_cod_n = estadis.cod_n
|
||||
LET rc.cod_n = estadis.cod_n
|
||||
LET rc.categoria = estadis.categoria
|
||||
LET rc.nombre_clase = NULL
|
||||
SELECT a.producto INTO rc.nombre_clase
|
||||
FROM iptb00020 a WHERE a.cod_n = estadis.cod_n
|
||||
IF rc.nombre_clase IS NULL THEN LET rc.nombre_clase = " " END IF
|
||||
LET rc.c_prod = 0
|
||||
LET rc.c_estrella = 0
|
||||
LET rc.c_revisar = 0
|
||||
LET rc.c_valor_inv = 0
|
||||
LET rc.c_ventas = 0
|
||||
LET rc.c_ganancia = 0
|
||||
LET rc_rot_sum = 0
|
||||
END IF
|
||||
LET rc.c_prod = rc.c_prod + 1
|
||||
LET rc.c_valor_inv = rc.c_valor_inv + estadis.valor_inv
|
||||
LET rc.c_ventas = rc.c_ventas + estadis.ventas_valor
|
||||
LET rc.c_ganancia = rc.c_ganancia + estadis.ganancia
|
||||
LET rc_rot_sum = rc_rot_sum + estadis.rotacion_anual
|
||||
IF estadis.clasificacion = "REVISAR" THEN LET rc.c_revisar = rc.c_revisar + 1 END IF
|
||||
IF estadis.clasificacion = "ESTRELLA" THEN LET rc.c_estrella = rc.c_estrella + 1 END IF
|
||||
ELSE
|
||||
OUTPUT TO REPORT estadistica(estadis.*,dias1,c_dias)
|
||||
END IF
|
||||
END IF
|
||||
LET idx = idx +1
|
||||
LET estadis.consumo = 0
|
||||
LET estadis.existe = 0
|
||||
END FOREACH
|
||||
LET estadis.precio = 0
|
||||
LET estadis.margen = 0
|
||||
LET estadis.rotacion = 0
|
||||
LET estadis.rotacion_anual = 0
|
||||
END FOREACH
|
||||
IF idx = 1 THEN
|
||||
CALL fgl_winmessage("INFO","NO EXISTEN INFORMACIONES CON ESTOS PARAMETROS","INFO")
|
||||
ELSE
|
||||
FINISH REPORT estadistica
|
||||
IF tipo_reporte = "R" THEN
|
||||
# Emite la ultima clase acumulada
|
||||
IF prev_cod_n <> -999999 THEN
|
||||
CALL emite_clase()
|
||||
END IF
|
||||
FINISH REPORT resumen
|
||||
ELSE
|
||||
FINISH REPORT estadistica
|
||||
END IF
|
||||
END IF
|
||||
#RUN imprime
|
||||
|
||||
|
||||
CLEAR SCREEN
|
||||
|
||||
|
||||
END FUNCTION
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Calcula el margen ponderado y la rotacion promedio de la clase acumulada en
|
||||
# 'rc' y la envia al reporte 'resumen'. Usada por ipprrp013() al cambiar de
|
||||
# CLASE y al terminar el FOREACH.
|
||||
# ------------------------------------------------------------------------------
|
||||
FUNCTION emite_clase()
|
||||
IF rc.c_ventas > 0 THEN
|
||||
LET rc.c_margen = (rc.c_ganancia / rc.c_ventas) * 100
|
||||
ELSE
|
||||
LET rc.c_margen = 0
|
||||
END IF
|
||||
IF rc.c_prod > 0 THEN
|
||||
LET rc.c_rot_prom = rc_rot_sum / rc.c_prod
|
||||
ELSE
|
||||
LET rc.c_rot_prom = 0
|
||||
END IF
|
||||
OUTPUT TO REPORT resumen(rc.*)
|
||||
END FUNCTION
|
||||
|
||||
REPORT estadistica(x,dias2,c_dias)
|
||||
@@ -372,7 +596,16 @@ REPORT estadistica(x,dias2,c_dias)
|
||||
costo DECIMAL(12,4),
|
||||
dias INTEGER,
|
||||
pcodigo char(25),
|
||||
cantidad_orden,pcantidadConduce,transito,existencia,reservado,disponible DEC(12,2)
|
||||
cantidad_orden,pcantidadConduce,transito,existencia,reservado,disponible DEC(12,2),
|
||||
# --- Analisis margen / rotacion (Agosto 2026) - debe reflejar estadis ---
|
||||
precio DEC(12,4),
|
||||
margen DEC(12,2),
|
||||
rotacion DEC(12,4),
|
||||
rotacion_anual DEC(12,4),
|
||||
valor_inv DEC(14,2),
|
||||
ventas_valor DEC(14,2),
|
||||
ganancia DEC(14,2),
|
||||
clasificacion CHAR(12)
|
||||
END RECORD,
|
||||
cantidad_rec,cantidad_or,tcantidad DEC(12,4),
|
||||
fecha_v,fecha_oc DATE
|
||||
@@ -500,3 +733,59 @@ REPORT estadistica(x,dias2,c_dias)
|
||||
|
||||
|
||||
END REPORT
|
||||
|
||||
# ==============================================================================
|
||||
# REPORTE RESUMEN POR CLASE (cod_n) -- version PLANA (sin grupos)
|
||||
# ------------------------------------------------------------------------------
|
||||
# Recibe UN registro ya agregado por CLASE (lo arma el FOREACH principal) y emite
|
||||
# una linea por clase via ON EVERY ROW. El gran total se acumula aqui y se
|
||||
# muestra en el pie del disenio ipprrp013r.4rp (patron identico al footer de
|
||||
# 'total_registros' del reporte de detalle, por eso no usa grupos ni triggers).
|
||||
# ==============================================================================
|
||||
REPORT resumen(r)
|
||||
DEFINE r RECORD
|
||||
cod_n INTEGER,
|
||||
nombre_clase CHAR(30),
|
||||
categoria CHAR(30),
|
||||
c_prod INTEGER,
|
||||
c_estrella INTEGER,
|
||||
c_revisar INTEGER,
|
||||
c_valor_inv DECIMAL(16,2),
|
||||
c_ventas DECIMAL(16,2),
|
||||
c_ganancia DECIMAL(16,2),
|
||||
c_margen DECIMAL(12,2),
|
||||
c_rot_prom DECIMAL(12,4)
|
||||
END RECORD
|
||||
|
||||
DEFINE hora CHAR(5),
|
||||
fecha DATE,
|
||||
g_prod INTEGER,
|
||||
g_valor_inv, g_ventas, g_ganancia DECIMAL(16,2),
|
||||
g_margen DECIMAL(12,2)
|
||||
|
||||
FORMAT
|
||||
FIRST PAGE HEADER
|
||||
LET hora = TIME
|
||||
LET fecha = TODAY
|
||||
SELECT a.* INTO p_companias.* FROM companias a WHERE a.cod_comp = 1
|
||||
LET lj = (120 - LENGTH(p_companias.nombre CLIPPED))/2
|
||||
LET g_prod = 0
|
||||
LET g_valor_inv = 0
|
||||
LET g_ventas = 0
|
||||
LET g_ganancia = 0
|
||||
|
||||
ON EVERY ROW
|
||||
LET g_prod = g_prod + r.c_prod
|
||||
LET g_valor_inv = g_valor_inv + r.c_valor_inv
|
||||
LET g_ventas = g_ventas + r.c_ventas
|
||||
LET g_ganancia = g_ganancia + r.c_ganancia
|
||||
IF g_ventas > 0 THEN
|
||||
LET g_margen = (g_ganancia / g_ventas) * 100
|
||||
ELSE
|
||||
LET g_margen = 0
|
||||
END IF
|
||||
PRINTX r.*,
|
||||
g_prod, g_valor_inv, g_ventas, g_ganancia, g_margen,
|
||||
p_companias.*, fecha, hora, fecha1, fecha2
|
||||
|
||||
END REPORT
|
||||
|
||||
+256
-19
@@ -23,6 +23,23 @@ DESCRIPCION : OPTIMIZACION DE RENDIMIENTO:
|
||||
inventario rota en el periodo). Se agrega ademas
|
||||
la rotacion anualizada = rotacion * (365/dias).
|
||||
DIAS INV se mantiene igual (formula correcta).
|
||||
|
||||
AGOSTO 20, 2026 - MARGEN + DETALLADO/RESUMEN:
|
||||
5. MARGEN DE BENEFICIO: se calcula el precio de venta REAL
|
||||
promedio del periodo (ponderado por cantidad, neto del
|
||||
descuento de cabecera) desde vetb00002/vetb00003, y el
|
||||
COSTO estandar (iptb00004, antes quedaba en 0). Margen %
|
||||
sobre precio = (precio-costo)/precio*100. Clasificacion
|
||||
por cuadrante margen x rotacion (ESTRELLA/VOLUMEN/NICHO/
|
||||
REVISAR/SIN COSTO), umbrales g_margen_min / g_rot_min.
|
||||
6. El formulario permite elegir DETALLADO (una linea por
|
||||
producto -> ipprrp014.4rp) o RESUMEN por CLASE cod_n
|
||||
(subtotales -> ipprrp014r.4rp). La agregacion por clase
|
||||
se hace en el FOREACH (emite_clase) y el reporte
|
||||
'resumen' es PLANO (una fila por clase, total al pie).
|
||||
NOTA: el consumo del 014 es de PRODUCCION
|
||||
(pcantidadConduce); el margen ponderado de la clase pesa
|
||||
por ese consumo.
|
||||
-------------------------------------------------------------------------------
|
||||
}
|
||||
GLOBALS "ipprgb000.4gl"
|
||||
@@ -39,6 +56,29 @@ DEFINE
|
||||
chexistencia CHAR(2),
|
||||
progreso, cuenta_reg, cuenta INT
|
||||
|
||||
# Umbrales de clasificacion margen/rotacion (ajustables aqui)
|
||||
DEFINE g_margen_min DECIMAL(6,2)
|
||||
DEFINE g_rot_min DECIMAL(6,2)
|
||||
|
||||
# Acumulador por CLASE para el reporte Resumen (una fila por cod_n),
|
||||
# a nivel de modulo para que emite_clase() y la funcion principal lo compartan.
|
||||
DEFINE rc RECORD
|
||||
cod_n INTEGER,
|
||||
nombre_clase CHAR(30),
|
||||
categoria CHAR(30),
|
||||
c_prod INTEGER,
|
||||
c_estrella INTEGER,
|
||||
c_revisar INTEGER,
|
||||
c_valor_inv DECIMAL(16,2),
|
||||
c_ventas DECIMAL(16,2),
|
||||
c_ganancia DECIMAL(16,2),
|
||||
c_margen DECIMAL(12,2),
|
||||
c_rot_prom DECIMAL(12,4)
|
||||
END RECORD
|
||||
DEFINE rc_rot_sum DECIMAL(16,4)
|
||||
DEFINE prev_cod_n INTEGER
|
||||
DEFINE cbtipo ui.ComboBox
|
||||
|
||||
MAIN
|
||||
DEFER INTERRUPT
|
||||
CALL ARG_VAL(1) RETURNING usuarios
|
||||
@@ -95,7 +135,14 @@ FUNCTION ipprrp013()
|
||||
disponible,
|
||||
precio,
|
||||
rotacion
|
||||
DEC(12, 2)
|
||||
DEC(12, 2),
|
||||
# --- Analisis margen (Agosto 2026) ---
|
||||
rotacion_anual DEC(12,4),
|
||||
margen DEC(12,2),
|
||||
valor_inv DEC(14,2),
|
||||
ventas_valor DEC(14,2),
|
||||
ganancia DEC(14,2),
|
||||
clasificacion CHAR(12)
|
||||
END RECORD
|
||||
|
||||
DEFINE
|
||||
@@ -111,11 +158,24 @@ FUNCTION ipprrp013()
|
||||
DISPLAY "ipprrp014" AT 4, 3 ATTRIBUTE(RED)
|
||||
DISPLAY "Dias de Inventarios Gerente Marcas" AT 6, 33 ATTRIBUTE(BLACK)
|
||||
|
||||
INPUT BY NAME fecha1, fecha2, c_dias, m_meses, chexistencia
|
||||
INPUT BY NAME fecha1, fecha2, c_dias, m_meses, chexistencia, tipo_reporte
|
||||
BEFORE INPUT
|
||||
LET progreso = 10
|
||||
LET c_dias = 0
|
||||
DISPLAY BY NAME c_dias, progreso
|
||||
# Umbrales de clasificacion margen/rotacion
|
||||
LET g_margen_min = 25.00
|
||||
LET g_rot_min = 2.00
|
||||
# Combo Detallado / Resumen (llenado por codigo)
|
||||
LET cbtipo = ui.ComboBox.forName("formonly.tipo_reporte")
|
||||
IF cbtipo IS NOT NULL THEN
|
||||
CALL cbtipo.clear()
|
||||
CALL cbtipo.addItem("D","Detallado (por producto)")
|
||||
CALL cbtipo.addItem("R","Resumen (por clase)")
|
||||
END IF
|
||||
IF tipo_reporte IS NULL OR tipo_reporte = " " THEN
|
||||
LET tipo_reporte = "D"
|
||||
END IF
|
||||
DISPLAY BY NAME c_dias, progreso, tipo_reporte
|
||||
SELECT DISTINCT RTRIM(a.nom1_emp) + ' ' + RTRIM(a.apell1_emp),
|
||||
a.num_emp
|
||||
INTO representa, num_representa
|
||||
@@ -159,6 +219,11 @@ FUNCTION ipprrp013()
|
||||
CALL msg(numero_msg)
|
||||
NEXT FIELD m_meses
|
||||
END IF
|
||||
AFTER FIELD tipo_reporte
|
||||
IF tipo_reporte IS NULL OR tipo_reporte = " " THEN
|
||||
LET tipo_reporte = "D"
|
||||
DISPLAY BY NAME tipo_reporte
|
||||
END IF
|
||||
AFTER INPUT
|
||||
|
||||
IF int_flag THEN
|
||||
@@ -252,9 +317,15 @@ FUNCTION ipprrp013()
|
||||
PREPARE comando2 FROM select_bal
|
||||
DECLARE accion CURSOR FOR comando2
|
||||
|
||||
LET r_filename = "ipprrp014.4rp"
|
||||
# Detallado (D) -> ipprrp014.4rp ; Resumen por clase (R) -> ipprrp014r.4rp
|
||||
IF tipo_reporte = "R" THEN
|
||||
LET r_filename = "ipprrp014r.4rp"
|
||||
ELSE
|
||||
LET r_filename = "ipprrp014.4rp"
|
||||
END IF
|
||||
|
||||
LET idx = 1
|
||||
LET prev_cod_n = -999999
|
||||
DISPLAY progreso TO progreso
|
||||
CALL ui.Interface.refresh()
|
||||
|
||||
@@ -290,7 +361,11 @@ FUNCTION ipprrp013()
|
||||
EXIT PROGRAM
|
||||
END IF
|
||||
IF handler IS NOT NULL THEN
|
||||
START REPORT estadistica TO XML HANDLER handler
|
||||
IF tipo_reporte = "R" THEN
|
||||
START REPORT resumen TO XML HANDLER handler
|
||||
ELSE
|
||||
START REPORT estadistica TO XML HANDLER handler
|
||||
END IF
|
||||
ELSE
|
||||
EXIT FOREACH
|
||||
END IF
|
||||
@@ -321,6 +396,31 @@ FUNCTION ipprrp013()
|
||||
END IF
|
||||
|
||||
LET estadis.existe = estadis.existencia
|
||||
|
||||
# ---- COSTO ESTANDAR (iptb00004). Antes quedaba en 0; ahora se calcula
|
||||
# para poder obtener el margen y el valor de exceso reales. ----
|
||||
LET estadis.costo = 0
|
||||
SELECT AVG(a.material+a.labor+a.gastos) INTO estadis.costo FROM iptb00004 a
|
||||
WHERE a.ano = YEAR(TODAY) AND a.mes_fin = 12
|
||||
AND a.cod_n = estadis.cod_n AND a.cod_grupo = estadis.cod_grupo
|
||||
AND a.cod_tipo = estadis.cod_tipo AND a.cod_sec = estadis.cod_sec
|
||||
AND a.status_t IS NULL
|
||||
IF estadis.costo IS NULL THEN LET estadis.costo = 0 END IF
|
||||
|
||||
# ---- PRECIO de venta REAL promedio del periodo (ponderado por cantidad,
|
||||
# neto del descuento de cabecera). Fuente vetb00002 + vetb00003. ----
|
||||
LET estadis.precio = 0
|
||||
SELECT SUM(d.cantidad * d.precio * (1 - (ISNULL(h.porc_desc,0)/100.0)))
|
||||
/ NULLIF(SUM(d.cantidad),0)
|
||||
INTO estadis.precio
|
||||
FROM vetb00003 d, vetb00002 h
|
||||
WHERE d.factura = h.factura
|
||||
AND d.cod_n = estadis.cod_n AND d.cod_grupo = estadis.cod_grupo
|
||||
AND d.cod_tipo = estadis.cod_tipo AND d.cod_sec = estadis.cod_sec
|
||||
AND h.status_t IS NULL AND d.status_t IS NULL
|
||||
AND h.fecha_factura BETWEEN fecha1 AND fecha2
|
||||
IF estadis.precio IS NULL THEN LET estadis.precio = 0 END IF
|
||||
|
||||
# Calculo para los dias de produccion
|
||||
IF estadis.existe > 0 THEN
|
||||
LET estadis.cantidad_orden =
|
||||
@@ -329,25 +429,21 @@ FUNCTION ipprrp013()
|
||||
estadis.existe - estadis.cantidad_orden - estadis.reservado
|
||||
IF estadis.consumo > 0 THEN
|
||||
LET estadis.dias = (estadis.existe / estadis.consumo) * dias1
|
||||
# ==============================================================
|
||||
# FORMULA CORREGIDA: indice de rotacion = consumo / existencia
|
||||
# (veces que rota el inventario en el periodo).
|
||||
# La formula anterior (existe/consumo) era la COBERTURA.
|
||||
# Nota: idealmente usar existencia PROMEDIO del periodo:
|
||||
# (existencia a fecha1 + existencia a fecha2) / 2
|
||||
# ==============================================================
|
||||
# indice de rotacion = consumo / existencia (veces en el periodo)
|
||||
LET estadis.rotacion = estadis.consumo / estadis.existe
|
||||
LET rotacion_anual = estadis.rotacion * (365 / dias1)
|
||||
# anualizada: 365.0 (decimal) evita la division entera
|
||||
LET estadis.rotacion_anual = estadis.rotacion * (365.0 / dias1)
|
||||
ELSE
|
||||
LET estadis.rotacion = 0
|
||||
LET rotacion_anual = 0
|
||||
LET estadis.rotacion_anual = 0
|
||||
END IF
|
||||
|
||||
ELSE
|
||||
LET estadis.dias = 0
|
||||
LET estadis.rotacion = 0
|
||||
LET rotacion_anual = 0
|
||||
LET estadis.rotacion_anual = 0
|
||||
END IF
|
||||
LET rotacion_anual = estadis.rotacion_anual
|
||||
|
||||
LET estadis.valor = 0
|
||||
IF estadis.dias >= c_dias THEN
|
||||
@@ -358,15 +454,69 @@ FUNCTION ipprrp013()
|
||||
LET estadis.valor = 0
|
||||
END IF
|
||||
END IF
|
||||
LET estadis.costo = 0
|
||||
|
||||
OUTPUT TO REPORT estadistica(estadis.*, dias1, c_dias, rotacion_anual)
|
||||
# ---- Margen % sobre precio, valores y clasificacion por cuadrante ----
|
||||
IF estadis.precio > 0 AND estadis.costo > 0 THEN
|
||||
LET estadis.margen = ((estadis.precio - estadis.costo) / estadis.precio) * 100
|
||||
ELSE
|
||||
LET estadis.margen = 0
|
||||
END IF
|
||||
LET estadis.valor_inv = estadis.existe * estadis.costo
|
||||
LET estadis.ventas_valor = estadis.consumo * estadis.precio
|
||||
LET estadis.ganancia = estadis.consumo * (estadis.precio - estadis.costo)
|
||||
CASE
|
||||
WHEN estadis.costo <= 0
|
||||
LET estadis.clasificacion = "SIN COSTO"
|
||||
WHEN estadis.margen >= g_margen_min AND estadis.rotacion_anual >= g_rot_min
|
||||
LET estadis.clasificacion = "ESTRELLA"
|
||||
WHEN estadis.margen < g_margen_min AND estadis.rotacion_anual >= g_rot_min
|
||||
LET estadis.clasificacion = "VOLUMEN"
|
||||
WHEN estadis.margen >= g_margen_min AND estadis.rotacion_anual < g_rot_min
|
||||
LET estadis.clasificacion = "NICHO"
|
||||
OTHERWISE
|
||||
LET estadis.clasificacion = "REVISAR"
|
||||
END CASE
|
||||
|
||||
IF tipo_reporte = "R" THEN
|
||||
# Agregacion por CLASE: al cambiar cod_n, emite la clase anterior
|
||||
IF prev_cod_n <> estadis.cod_n THEN
|
||||
IF prev_cod_n <> -999999 THEN
|
||||
CALL emite_clase()
|
||||
END IF
|
||||
LET prev_cod_n = estadis.cod_n
|
||||
LET rc.cod_n = estadis.cod_n
|
||||
LET rc.categoria = estadis.categoria
|
||||
LET rc.nombre_clase = NULL
|
||||
SELECT a.producto INTO rc.nombre_clase
|
||||
FROM iptb00020 a WHERE a.cod_n = estadis.cod_n
|
||||
IF rc.nombre_clase IS NULL THEN LET rc.nombre_clase = " " END IF
|
||||
LET rc.c_prod = 0
|
||||
LET rc.c_estrella = 0
|
||||
LET rc.c_revisar = 0
|
||||
LET rc.c_valor_inv = 0
|
||||
LET rc.c_ventas = 0
|
||||
LET rc.c_ganancia = 0
|
||||
LET rc_rot_sum = 0
|
||||
END IF
|
||||
LET rc.c_prod = rc.c_prod + 1
|
||||
LET rc.c_valor_inv = rc.c_valor_inv + estadis.valor_inv
|
||||
LET rc.c_ventas = rc.c_ventas + estadis.ventas_valor
|
||||
LET rc.c_ganancia = rc.c_ganancia + estadis.ganancia
|
||||
LET rc_rot_sum = rc_rot_sum + estadis.rotacion_anual
|
||||
IF estadis.clasificacion = "REVISAR" THEN LET rc.c_revisar = rc.c_revisar + 1 END IF
|
||||
IF estadis.clasificacion = "ESTRELLA" THEN LET rc.c_estrella = rc.c_estrella + 1 END IF
|
||||
ELSE
|
||||
OUTPUT TO REPORT estadistica(estadis.*, dias1, c_dias, estadis.rotacion_anual)
|
||||
END IF
|
||||
|
||||
LET idx = idx + 1
|
||||
LET estadis.consumo = 0
|
||||
LET estadis.existe = 0
|
||||
LET estadis.dias = 0
|
||||
LET estadis.rotacion = 0
|
||||
LET estadis.rotacion_anual = 0
|
||||
LET estadis.precio = 0
|
||||
LET estadis.margen = 0
|
||||
|
||||
# Refrescar progreso solo cada 50 filas: cada refresh es un
|
||||
# round-trip al GDC y hacerlo por fila cuesta minutos.
|
||||
@@ -380,13 +530,91 @@ FUNCTION ipprrp013()
|
||||
CALL fgl_winmessage(
|
||||
"INFO", "NO EXISTEN INFORMACIONES CON ESTOS PARAMETROS", "INFO")
|
||||
ELSE
|
||||
# Emite la ultima clase acumulada (modo Resumen)
|
||||
IF tipo_reporte = "R" AND prev_cod_n <> -999999 THEN
|
||||
CALL emite_clase()
|
||||
END IF
|
||||
LET progreso = 100
|
||||
DISPLAY progreso TO progreso
|
||||
FINISH REPORT estadistica
|
||||
IF tipo_reporte = "R" THEN
|
||||
FINISH REPORT resumen
|
||||
ELSE
|
||||
FINISH REPORT estadistica
|
||||
END IF
|
||||
END IF
|
||||
|
||||
END FUNCTION
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Calcula margen ponderado y rotacion promedio de la clase acumulada en 'rc' y la
|
||||
# envia al reporte 'resumen'. Usada al cambiar de CLASE y al terminar el FOREACH.
|
||||
# ------------------------------------------------------------------------------
|
||||
FUNCTION emite_clase()
|
||||
IF rc.c_ventas > 0 THEN
|
||||
LET rc.c_margen = (rc.c_ganancia / rc.c_ventas) * 100
|
||||
ELSE
|
||||
LET rc.c_margen = 0
|
||||
END IF
|
||||
IF rc.c_prod > 0 THEN
|
||||
LET rc.c_rot_prom = rc_rot_sum / rc.c_prod
|
||||
ELSE
|
||||
LET rc.c_rot_prom = 0
|
||||
END IF
|
||||
OUTPUT TO REPORT resumen(rc.*)
|
||||
END FUNCTION
|
||||
|
||||
# ==============================================================================
|
||||
# REPORTE RESUMEN POR CLASE (cod_n) -- version PLANA (una fila por clase).
|
||||
# La agregacion la hace el FOREACH (emite_clase); aqui solo se imprime y se
|
||||
# acumula el gran total para el pie. Alimenta ipprrp014r.4rp.
|
||||
# ==============================================================================
|
||||
REPORT resumen(r)
|
||||
DEFINE r RECORD
|
||||
cod_n INTEGER,
|
||||
nombre_clase CHAR(30),
|
||||
categoria CHAR(30),
|
||||
c_prod INTEGER,
|
||||
c_estrella INTEGER,
|
||||
c_revisar INTEGER,
|
||||
c_valor_inv DECIMAL(16,2),
|
||||
c_ventas DECIMAL(16,2),
|
||||
c_ganancia DECIMAL(16,2),
|
||||
c_margen DECIMAL(12,2),
|
||||
c_rot_prom DECIMAL(12,4)
|
||||
END RECORD
|
||||
|
||||
DEFINE hora CHAR(5),
|
||||
fecha DATE,
|
||||
g_prod INTEGER,
|
||||
g_valor_inv, g_ventas, g_ganancia DECIMAL(16,2),
|
||||
g_margen DECIMAL(12,2)
|
||||
|
||||
FORMAT
|
||||
FIRST PAGE HEADER
|
||||
LET hora = TIME
|
||||
LET fecha = TODAY
|
||||
LET lj = (120 - LENGTH(p_companias.nombre CLIPPED)) / 2
|
||||
LET g_prod = 0
|
||||
LET g_valor_inv = 0
|
||||
LET g_ventas = 0
|
||||
LET g_ganancia = 0
|
||||
|
||||
ON EVERY ROW
|
||||
LET g_prod = g_prod + r.c_prod
|
||||
LET g_valor_inv = g_valor_inv + r.c_valor_inv
|
||||
LET g_ventas = g_ventas + r.c_ventas
|
||||
LET g_ganancia = g_ganancia + r.c_ganancia
|
||||
IF g_ventas > 0 THEN
|
||||
LET g_margen = (g_ganancia / g_ventas) * 100
|
||||
ELSE
|
||||
LET g_margen = 0
|
||||
END IF
|
||||
PRINTX r.*,
|
||||
g_prod, g_valor_inv, g_ventas, g_ganancia, g_margen,
|
||||
p_companias.*, fecha, hora, fecha1, fecha2
|
||||
|
||||
END REPORT
|
||||
|
||||
REPORT estadistica(x, dias2, c_dias, rot_anual)
|
||||
DEFINE
|
||||
x RECORD
|
||||
@@ -416,7 +644,14 @@ REPORT estadistica(x, dias2, c_dias, rot_anual)
|
||||
disponible,
|
||||
precio,
|
||||
rotacion
|
||||
DEC(12, 2)
|
||||
DEC(12, 2),
|
||||
# --- Analisis margen (Agosto 2026) - debe reflejar estadis ---
|
||||
rotacion_anual DEC(12,4),
|
||||
margen DEC(12,2),
|
||||
valor_inv DEC(14,2),
|
||||
ventas_valor DEC(14,2),
|
||||
ganancia DEC(14,2),
|
||||
clasificacion CHAR(12)
|
||||
END RECORD,
|
||||
tcantidad DEC(12, 4),
|
||||
|
||||
@@ -491,6 +726,8 @@ REPORT estadistica(x, dias2, c_dias, rot_anual)
|
||||
x.dias,
|
||||
x.rotacion,
|
||||
rot_anual,
|
||||
x.margen,
|
||||
x.clasificacion,
|
||||
x.unidad_med,
|
||||
fecha,
|
||||
hora,
|
||||
|
||||
@@ -38,7 +38,32 @@ DEFINE CheckApi RECORD
|
||||
checkRep BOOLEAN
|
||||
END RECORD
|
||||
|
||||
DEFINE fakeData RECORD LIKE cotb00001.*
|
||||
# fakeData se pasa POR POSICION (fakeData.*) al parametro Data de
|
||||
# ApiMaintainC en api_test.4gl, por lo que su estructura (orden y tipos)
|
||||
# debe ser IDENTICA a ese record. No usar RECORD LIKE cotb00001.* porque
|
||||
# el orden fisico de las columnas de cotb00001 no coincide con ese record
|
||||
# y provoca el error -1260 al convertir los tipos.
|
||||
DEFINE fakeData RECORD
|
||||
area_sp VARCHAR(10),
|
||||
ciu_sp VARCHAR(30),
|
||||
cod_pais VARCHAR(3),
|
||||
cod_sp SMALLINT,
|
||||
cod_sp_sec SMALLINT,
|
||||
cont_sp VARCHAR(30),
|
||||
contactID INTEGER,
|
||||
dir_sp VARCHAR(60),
|
||||
email VARCHAR(60),
|
||||
fax_sp VARCHAR(25),
|
||||
fech_crea DATETIME YEAR TO FRACTION,
|
||||
fech_mod DATETIME YEAR TO FRACTION,
|
||||
id_maintainx INTEGER,
|
||||
nom_sp VARCHAR(41),
|
||||
status_t VARCHAR(1),
|
||||
tel_sp VARCHAR(25),
|
||||
term_sp SMALLINT,
|
||||
us_crea VARCHAR(50),
|
||||
us_mod VARCHAR(50)
|
||||
END RECORD
|
||||
|
||||
DEFINE data RECORD
|
||||
rnumeroDoc,rcodMov,rtipo_cliente,num_oc,tipo_cliente,sec_cliente,bodega,bodega_destino INT,
|
||||
|
||||
Reference in New Issue
Block a user