666 lines
26 KiB
Plaintext
666 lines
26 KiB
Plaintext
{
|
|
-------------------------------------------------------------------------------
|
|
PROGRAMA : NOPRRP045
|
|
OBJETIVO : Informe para el Ministerio de Trabajo.
|
|
Genera (en el server, via motor de reportes) el
|
|
cuadro de:
|
|
- Monto en RD$ (SUELDO del mes) por NIVEL
|
|
EDUCATIVO, por mes y por sexo.
|
|
- Cantidad de empleados por mes y por sexo.
|
|
Se muestra en el visor de reportes; desde ahi el
|
|
usuario lo exporta a EXCEL o PDF.
|
|
FUENTES DE DATOS : Nivel educativo -> adtb00003.nivel_emp -> adtb00005
|
|
Sexo -> adtb00021.sexo ('M'/'F', titular
|
|
con cod_par IS NULL)
|
|
Sueldo -> notb00008.valor WHERE cod_mov = 1
|
|
(solo sueldo, sin horas extras)
|
|
DISENO : noprrp045.4rp (datos: noprrp045.rdd, rutina r_min)
|
|
PROGRAMADOR : Ing. Juan F. Soto
|
|
FECHA REALIZACION : Julio 30, 2026
|
|
-------------------------------------------------------------------------------
|
|
}
|
|
GLOBALS "noprgb000.4gl"
|
|
|
|
DEFINE p_anio INTEGER -- ano a reportar
|
|
|
|
|
|
MAIN
|
|
DEFER INTERRUPT
|
|
CALL ARG_VAL(1) RETURNING usuarios
|
|
CALL ARG_VAL(2) RETURNING clave
|
|
CALL startlog("noprrp045.log")
|
|
CONNECT TO "smarmotech" USER usuarios USING clave
|
|
SELECT a.* INTO p_companias.* FROM companias a
|
|
CALL noprrp045()
|
|
END MAIN
|
|
|
|
|
|
FUNCTION noprrp045()
|
|
DEFINE monto ARRAY[12,25] OF DECIMAL(16,2) -- [fila 6..12, col 2..25]
|
|
DEFINE conteo ARRAY[25] OF INTEGER -- [col 2..25]
|
|
DEFINE f, c, m SMALLINT
|
|
DEFINE r_nom CHAR(30)
|
|
DEFINE r_mes SMALLINT
|
|
DEFINE r_sexo CHAR(1)
|
|
DEFINE r_monto DECIMAL(16,2)
|
|
DEFINE r_cant INTEGER
|
|
DEFINE fila_e SMALLINT
|
|
DEFINE sin_edu DECIMAL(16,2)
|
|
DEFINE sin_sex DECIMAL(16,2)
|
|
DEFINE th, tm DECIMAL(18,2) -- totales de monto por mes (H, M)
|
|
DEFINE hay_datos SMALLINT
|
|
DEFINE niveles ARRAY[7] OF CHAR(35)
|
|
DEFINE vals DYNAMIC ARRAY OF VARCHAR(24)
|
|
|
|
LET niveles[1] = "NINGUNO"
|
|
LET niveles[2] = "PRIMARIA"
|
|
LET niveles[3] = "SECUNDARIA"
|
|
LET niveles[4] = "TECNICO SUPERIOR"
|
|
LET niveles[5] = "ESTUDIANTE UNIVERSITARIO"
|
|
LET niveles[6] = "GRADO UNIVERSITARIO (LICENCIATURA)"
|
|
LET niveles[7] = "POSGRADO"
|
|
|
|
OPTIONS FORM LINE 8, ERROR LINE 23, COMMENT LINE 21
|
|
CLEAR SCREEN
|
|
OPEN FORM nofmrp045 FROM "nofmrp045"
|
|
DISPLAY FORM nofmrp045
|
|
DISPLAY "noprrp045" AT 4,3 ATTRIBUTE(RED)
|
|
DISPLAY "Informe Ministerio de Trabajo" AT 6,25 ATTRIBUTE(BLACK)
|
|
|
|
LET p_anio = YEAR(TODAY)
|
|
|
|
INPUT BY NAME p_anio WITHOUT DEFAULTS
|
|
AFTER FIELD p_anio
|
|
IF p_anio IS NULL OR p_anio < 1990 OR p_anio > 2100 THEN
|
|
CALL fgl_winmessage("Aviso", "Digite un ano valido.", "stop")
|
|
NEXT FIELD p_anio
|
|
END IF
|
|
ON ACTION cancel
|
|
RETURN
|
|
AFTER INPUT
|
|
IF int_flag THEN
|
|
LET int_flag = FALSE
|
|
RETURN
|
|
END IF
|
|
END INPUT
|
|
|
|
------------------------------------------------------------------
|
|
-- Inicializa acumuladores
|
|
------------------------------------------------------------------
|
|
FOR f = 1 TO 12
|
|
FOR c = 1 TO 25
|
|
LET monto[f,c] = 0
|
|
END FOR
|
|
END FOR
|
|
FOR c = 1 TO 25
|
|
LET conteo[c] = 0
|
|
END FOR
|
|
LET sin_edu = 0
|
|
LET sin_sex = 0
|
|
LET hay_datos = FALSE
|
|
|
|
DISPLAY "Buscando informacion... Espere por favor" AT 19,14
|
|
ATTRIBUTE(REVERSE, BOLD)
|
|
|
|
------------------------------------------------------------------
|
|
-- (1) Monto RD$ = SUELDO (cod_mov=1) por nivel educativo / mes / sexo
|
|
------------------------------------------------------------------
|
|
LET selec =
|
|
"SELECT RTRIM(ISNULL(ed.nom_educa,'')) AS nom_educa, ",
|
|
" MONTH(n.fecha) AS mes, ",
|
|
" ISNULL(dep.sexo,'') AS sexo, ",
|
|
" SUM(n.valor) AS monto ",
|
|
"FROM notb00008 n ",
|
|
" JOIN adtb00003 e ON e.num_emp = n.num_emp ",
|
|
" LEFT JOIN adtb00005 ed ON ed.cod_educa = e.nivel_emp ",
|
|
" LEFT JOIN (SELECT num_emp, MAX(sexo) AS sexo ",
|
|
" FROM adtb00021 WHERE cod_par IS NULL ",
|
|
" GROUP BY num_emp) dep ON dep.num_emp = e.num_emp ",
|
|
"WHERE YEAR(n.fecha) = ", p_anio, " ",
|
|
" AND n.cod_mov = 1 ", -- SOLO SUELDO (sin horas extras ni otros ingresos)
|
|
"GROUP BY RTRIM(ISNULL(ed.nom_educa,'')), MONTH(n.fecha), ISNULL(dep.sexo,'') "
|
|
|
|
PREPARE q_monto FROM selec
|
|
DECLARE cur_monto CURSOR FOR q_monto
|
|
FOREACH cur_monto INTO r_nom, r_mes, r_sexo, r_monto
|
|
LET hay_datos = TRUE
|
|
LET c = col_grid(r_mes, r_sexo)
|
|
IF c = 0 THEN
|
|
LET sin_sex = sin_sex + r_monto
|
|
CONTINUE FOREACH
|
|
END IF
|
|
LET fila_e = fila_educa(r_nom)
|
|
IF fila_e = 0 THEN
|
|
LET sin_edu = sin_edu + r_monto
|
|
CONTINUE FOREACH
|
|
END IF
|
|
LET monto[fila_e,c] = monto[fila_e,c] + r_monto
|
|
END FOREACH
|
|
|
|
------------------------------------------------------------------
|
|
-- (2) Cantidad de empleados por mes / sexo (solo con SUELDO, cod_mov=1)
|
|
------------------------------------------------------------------
|
|
LET selec =
|
|
"SELECT MONTH(n.fecha) AS mes, ",
|
|
" ISNULL(dep.sexo,'') AS sexo, ",
|
|
" COUNT(DISTINCT n.num_emp) AS cant ",
|
|
"FROM notb00008 n ",
|
|
" JOIN adtb00003 e ON e.num_emp = n.num_emp ",
|
|
" LEFT JOIN (SELECT num_emp, MAX(sexo) AS sexo ",
|
|
" FROM adtb00021 WHERE cod_par IS NULL ",
|
|
" GROUP BY num_emp) dep ON dep.num_emp = e.num_emp ",
|
|
"WHERE YEAR(n.fecha) = ", p_anio, " ",
|
|
" AND n.cod_mov = 1 ", -- solo empleados con SUELDO en el mes
|
|
"GROUP BY MONTH(n.fecha), ISNULL(dep.sexo,'') "
|
|
|
|
PREPARE q_cant FROM selec
|
|
DECLARE cur_cant CURSOR FOR q_cant
|
|
FOREACH cur_cant INTO r_mes, r_sexo, r_cant
|
|
LET c = col_grid(r_mes, r_sexo)
|
|
IF c = 0 THEN
|
|
CONTINUE FOREACH
|
|
END IF
|
|
LET conteo[c] = conteo[c] + r_cant
|
|
END FOREACH
|
|
|
|
IF NOT hay_datos THEN
|
|
CALL fgl_winmessage("Informe Ministerio",
|
|
"No existe nomina procesada para el ano "||p_anio USING "&&&&"||".",
|
|
"stop")
|
|
RETURN
|
|
END IF
|
|
|
|
------------------------------------------------------------------
|
|
-- Motor de reportes: carga el diseno y arranca el visor (preview).
|
|
-- Desde el visor el usuario exporta a EXCEL o PDF.
|
|
------------------------------------------------------------------
|
|
LET r_filename = "noprrp045.4rp"
|
|
IF NOT fgl_report_loadCurrentSettings(r_filename) THEN
|
|
CALL fgl_winmessage("Error",
|
|
"No se encontro el diseno del reporte (noprrp045.4rp).", "stop")
|
|
RETURN
|
|
END IF
|
|
-- El usuario elige el formato de salida (EXCEL / PDF / SVG) con la
|
|
-- funcion compartida seleccionarSalida() (otrodir/seleccionarsalida.4gl).
|
|
LET preview = 1
|
|
CALL seleccionarSalida() RETURNING r_output
|
|
CALL fgl_report_selectDevice(r_output)
|
|
CALL fgl_report_selectPreview(preview)
|
|
LET handler = fgl_report_commitCurrentSettings()
|
|
|
|
START REPORT r_min TO XML HANDLER handler
|
|
|
|
-- fila de titulo con empresa y ano
|
|
FOR c = 1 TO 36
|
|
LET vals[c] = " "
|
|
END FOR
|
|
CALL emite_fila("T",
|
|
p_companias.nombre CLIPPED||" - ANO "||(p_anio USING "&&&&"), vals)
|
|
|
|
-- 7 filas de monto (grid 6..12 -> niveles 1..7).
|
|
-- Por cada mes se emiten 3 columnas: Hombre, Mujer, Total (H+M).
|
|
FOR f = 6 TO 12
|
|
FOR m = 1 TO 12
|
|
LET vals[3*m-2] = monto[f,2*m] USING "-###,###,##&.&&"
|
|
LET vals[3*m-1] = monto[f,2*m+1] USING "-###,###,##&.&&"
|
|
LET vals[3*m] = (monto[f,2*m]+monto[f,2*m+1]) USING "-###,###,##&.&&"
|
|
END FOR
|
|
CALL emite_fila("A", niveles[f-5], vals)
|
|
END FOR
|
|
|
|
-- fila TOTAL MONTO EMPLEADO: suma de todos los niveles por mes.
|
|
-- (Hombre = suma de todos los H; Mujer = suma de todas las M; Total = H+M)
|
|
-- Sirve para cuadrar con el total de la nomina pagada.
|
|
FOR m = 1 TO 12
|
|
LET th = 0
|
|
LET tm = 0
|
|
FOR f = 6 TO 12
|
|
LET th = th + monto[f,2*m]
|
|
LET tm = tm + monto[f,2*m+1]
|
|
END FOR
|
|
LET vals[3*m-2] = th USING "-###,###,##&.&&"
|
|
LET vals[3*m-1] = tm USING "-###,###,##&.&&"
|
|
LET vals[3*m] = (th+tm) USING "-###,###,##&.&&"
|
|
END FOR
|
|
CALL emite_fila("M", "TOTAL MONTO EMPLEADO", vals)
|
|
|
|
-- fila de conteo total de empleados (Hombre, Mujer, Total por mes)
|
|
FOR m = 1 TO 12
|
|
LET vals[3*m-2] = conteo[2*m] USING "-###,###,##&"
|
|
LET vals[3*m-1] = conteo[2*m+1] USING "-###,###,##&"
|
|
LET vals[3*m] = (conteo[2*m]+conteo[2*m+1]) USING "-###,###,##&"
|
|
END FOR
|
|
CALL emite_fila("C", "TOTAL EMPLEADOS", vals)
|
|
|
|
-- Secciones 4-8: foto demografica de empleados activos (status_t IS NULL) a hoy
|
|
CALL emite_demografia()
|
|
|
|
FINISH REPORT r_min
|
|
|
|
CLEAR SCREEN
|
|
|
|
------------------------------------------------------------------
|
|
-- Aviso de datos que no se pudieron clasificar (no se pierden en
|
|
-- silencio: se informa para corregir el maestro)
|
|
------------------------------------------------------------------
|
|
IF sin_edu > 0 OR sin_sex > 0 THEN
|
|
CALL fgl_winmessage("Datos sin clasificar",
|
|
"Monto sin nivel educativo mapeado: "||(sin_edu USING "-#,###,###,##&.&&")||
|
|
"\nMonto de empleados sin sexo en adtb00021: "||(sin_sex USING "-#,###,###,##&.&&")||
|
|
"\n\nRevise el nivel educativo (nivel_emp/adtb00005) y el sexo de "||
|
|
"esos empleados en la maestra.", "exclamation")
|
|
END IF
|
|
|
|
END FUNCTION
|
|
|
|
|
|
------------------------------------------------------------------------
|
|
-- Emite una fila al reporte. tipo: 'A'=monto RD$, 'C'=conteo
|
|
------------------------------------------------------------------------
|
|
FUNCTION emite_fila(p_tipo, p_nivel, p_vals)
|
|
DEFINE p_tipo CHAR(1)
|
|
DEFINE p_nivel CHAR(60)
|
|
DEFINE p_vals DYNAMIC ARRAY OF VARCHAR(24)
|
|
DEFINE reg RECORD
|
|
tipo CHAR(1),
|
|
nivel CHAR(60),
|
|
v01 VARCHAR(24), v02 VARCHAR(24), v03 VARCHAR(24), v04 VARCHAR(24),
|
|
v05 VARCHAR(24), v06 VARCHAR(24), v07 VARCHAR(24), v08 VARCHAR(24),
|
|
v09 VARCHAR(24), v10 VARCHAR(24), v11 VARCHAR(24), v12 VARCHAR(24),
|
|
v13 VARCHAR(24), v14 VARCHAR(24), v15 VARCHAR(24), v16 VARCHAR(24),
|
|
v17 VARCHAR(24), v18 VARCHAR(24), v19 VARCHAR(24), v20 VARCHAR(24),
|
|
v21 VARCHAR(24), v22 VARCHAR(24), v23 VARCHAR(24), v24 VARCHAR(24),
|
|
v25 VARCHAR(24), v26 VARCHAR(24), v27 VARCHAR(24), v28 VARCHAR(24),
|
|
v29 VARCHAR(24), v30 VARCHAR(24), v31 VARCHAR(24), v32 VARCHAR(24),
|
|
v33 VARCHAR(24), v34 VARCHAR(24), v35 VARCHAR(24), v36 VARCHAR(24)
|
|
END RECORD
|
|
|
|
LET reg.tipo = p_tipo
|
|
LET reg.nivel = p_nivel
|
|
LET reg.v01 = p_vals[1] LET reg.v02 = p_vals[2]
|
|
LET reg.v03 = p_vals[3] LET reg.v04 = p_vals[4]
|
|
LET reg.v05 = p_vals[5] LET reg.v06 = p_vals[6]
|
|
LET reg.v07 = p_vals[7] LET reg.v08 = p_vals[8]
|
|
LET reg.v09 = p_vals[9] LET reg.v10 = p_vals[10]
|
|
LET reg.v11 = p_vals[11] LET reg.v12 = p_vals[12]
|
|
LET reg.v13 = p_vals[13] LET reg.v14 = p_vals[14]
|
|
LET reg.v15 = p_vals[15] LET reg.v16 = p_vals[16]
|
|
LET reg.v17 = p_vals[17] LET reg.v18 = p_vals[18]
|
|
LET reg.v19 = p_vals[19] LET reg.v20 = p_vals[20]
|
|
LET reg.v21 = p_vals[21] LET reg.v22 = p_vals[22]
|
|
LET reg.v23 = p_vals[23] LET reg.v24 = p_vals[24]
|
|
LET reg.v25 = p_vals[25] LET reg.v26 = p_vals[26]
|
|
LET reg.v27 = p_vals[27] LET reg.v28 = p_vals[28]
|
|
LET reg.v29 = p_vals[29] LET reg.v30 = p_vals[30]
|
|
LET reg.v31 = p_vals[31] LET reg.v32 = p_vals[32]
|
|
LET reg.v33 = p_vals[33] LET reg.v34 = p_vals[34]
|
|
LET reg.v35 = p_vals[35] LET reg.v36 = p_vals[36]
|
|
|
|
OUTPUT TO REPORT r_min(reg.*)
|
|
END FUNCTION
|
|
|
|
|
|
------------------------------------------------------------------------
|
|
-- Rutina de reporte. Un registro por fila del cuadro.
|
|
------------------------------------------------------------------------
|
|
REPORT r_min(x)
|
|
DEFINE x RECORD
|
|
tipo CHAR(1),
|
|
nivel CHAR(60),
|
|
v01 VARCHAR(24), v02 VARCHAR(24), v03 VARCHAR(24), v04 VARCHAR(24),
|
|
v05 VARCHAR(24), v06 VARCHAR(24), v07 VARCHAR(24), v08 VARCHAR(24),
|
|
v09 VARCHAR(24), v10 VARCHAR(24), v11 VARCHAR(24), v12 VARCHAR(24),
|
|
v13 VARCHAR(24), v14 VARCHAR(24), v15 VARCHAR(24), v16 VARCHAR(24),
|
|
v17 VARCHAR(24), v18 VARCHAR(24), v19 VARCHAR(24), v20 VARCHAR(24),
|
|
v21 VARCHAR(24), v22 VARCHAR(24), v23 VARCHAR(24), v24 VARCHAR(24),
|
|
v25 VARCHAR(24), v26 VARCHAR(24), v27 VARCHAR(24), v28 VARCHAR(24),
|
|
v29 VARCHAR(24), v30 VARCHAR(24), v31 VARCHAR(24), v32 VARCHAR(24),
|
|
v33 VARCHAR(24), v34 VARCHAR(24), v35 VARCHAR(24), v36 VARCHAR(24)
|
|
END RECORD
|
|
DEFINE fecha_actual DATE
|
|
|
|
FORMAT
|
|
FIRST PAGE HEADER
|
|
LET fecha_actual = TODAY
|
|
PRINTX p_companias.nombre, p_anio, fecha_actual
|
|
|
|
ON EVERY ROW
|
|
PRINTX x.tipo, x.nivel,
|
|
x.v01, x.v02, x.v03, x.v04, x.v05, x.v06,
|
|
x.v07, x.v08, x.v09, x.v10, x.v11, x.v12,
|
|
x.v13, x.v14, x.v15, x.v16, x.v17, x.v18,
|
|
x.v19, x.v20, x.v21, x.v22, x.v23, x.v24,
|
|
x.v25, x.v26, x.v27, x.v28, x.v29, x.v30,
|
|
x.v31, x.v32, x.v33, x.v34, x.v35, x.v36
|
|
|
|
END REPORT
|
|
|
|
|
|
------------------------------------------------------------------------
|
|
-- Devuelve la fila del formato (6..12) segun el nombre del nivel
|
|
-- educativo (catalogo adtb00005). 0 = no mapeado.
|
|
-- BASICA->7 SECUNDARIA/BACHILLER->8 TECNICO->9
|
|
-- ESTUDIANTE UNIVERSITARIO->10 PROFESIONAL->11
|
|
-- DIPLOMADO/POSTGRADO/MAESTRIA/ESPECIALIDAD/DOCTORADO->12
|
|
-- El orden importa: POSTGRADO antes que GRADO; ESTUDIANTE antes que
|
|
-- UNIVERSITARIO.
|
|
------------------------------------------------------------------------
|
|
FUNCTION fila_educa(p_nom)
|
|
DEFINE p_nom STRING
|
|
DEFINE s CHAR(40)
|
|
|
|
LET s = UPSHIFT(p_nom CLIPPED)
|
|
IF s CLIPPED = "" THEN RETURN 0 END IF
|
|
|
|
IF s MATCHES "*NINGUN*" THEN RETURN 6 END IF
|
|
IF s MATCHES "*PRIMARIA*" OR s MATCHES "*BASICA*"
|
|
THEN RETURN 7 END IF
|
|
IF s MATCHES "*SECUNDAR*" OR s MATCHES "*BACHILLER*"
|
|
THEN RETURN 8 END IF
|
|
IF s MATCHES "*TECNIC*" THEN RETURN 9 END IF
|
|
IF s MATCHES "*ESTUDIANTE*" THEN RETURN 10 END IF
|
|
IF s MATCHES "*POSGRAD*" OR s MATCHES "*POSTGRAD*"
|
|
OR s MATCHES "*MAESTR*" OR s MATCHES "*DOCTORAD*"
|
|
OR s MATCHES "*ESPECIALIDAD*" OR s MATCHES "*DIPLOM*"
|
|
THEN RETURN 12 END IF
|
|
IF s MATCHES "*LICENCIAT*" OR s MATCHES "*GRADO*"
|
|
OR s MATCHES "*UNIVERSITARI*" OR s MATCHES "*PROFESIONAL*"
|
|
THEN RETURN 11 END IF
|
|
|
|
RETURN 0
|
|
END FUNCTION
|
|
|
|
|
|
------------------------------------------------------------------------
|
|
-- Columna del grid (2..25) segun mes (1..12) y sexo.
|
|
-- Hombre ('M') -> 2*mes Mujer ('F') -> 2*mes+1 0 = invalido
|
|
------------------------------------------------------------------------
|
|
FUNCTION col_grid(p_mes, p_sexo)
|
|
DEFINE p_mes SMALLINT
|
|
DEFINE p_sexo CHAR(1)
|
|
|
|
IF p_mes < 1 OR p_mes > 12 THEN RETURN 0 END IF
|
|
CASE UPSHIFT(p_sexo)
|
|
WHEN "M" RETURN 2 * p_mes
|
|
WHEN "F" RETURN 2 * p_mes + 1
|
|
OTHERWISE RETURN 0
|
|
END CASE
|
|
END FUNCTION
|
|
|
|
|
|
------------------------------------------------------------------------
|
|
-- Secciones 4-8: foto demografica de los empleados ACTIVOS (status_t IS
|
|
-- NULL) al dia de hoy. Cuenta empleados (sec 8 = promedio de sueldo_ac).
|
|
-- Edad -> adtb00003.fech_nac a hoy
|
|
-- Antiguedad -> adtb00003.fech_efec a hoy
|
|
-- Sexo -> adtb00021 (titular, cod_par IS NULL)
|
|
-- Nivel -> adtb00005 via nivel_emp
|
|
-- E.civil -> adtb00003.estado_civil
|
|
------------------------------------------------------------------------
|
|
FUNCTION emite_demografia()
|
|
DEFINE e_sexo CHAR(1)
|
|
DEFINE e_ecivil CHAR(1)
|
|
DEFINE e_fnac DATE
|
|
DEFINE e_fefec DATE
|
|
DEFINE e_sueldo DECIMAL(12,2)
|
|
DEFINE e_nom CHAR(30)
|
|
DEFINE si, nf, ageg, teng, mi SMALLINT
|
|
DEFINE edad, tanios INTEGER
|
|
DEFINE i, g SMALLINT
|
|
DEFINE tot, th_, tm_ INTEGER
|
|
DEFINE prom DECIMAL(16,2)
|
|
DEFINE gsum DECIMAL(18,2)
|
|
DEFINE gcnt INTEGER
|
|
DEFINE vals DYNAMIC ARRAY OF VARCHAR(24)
|
|
DEFINE c4 ARRAY[7,2] OF INTEGER -- nivel x (H,M)
|
|
DEFINE c5 ARRAY[7,5] OF INTEGER -- nivel x grupo edad
|
|
DEFINE c6 ARRAY[6,7] OF INTEGER -- e.civil x (H,M,edad1..5)
|
|
DEFINE c7 ARRAY[5,7] OF INTEGER -- antiguedad x (H,M,edad1..5)
|
|
DEFINE s8sum ARRAY[6,5] OF DECIMAL(18,2) -- suma sueldo por (estado civil, grupo edad)
|
|
DEFINE s8cnt ARRAY[6,5] OF INTEGER
|
|
DEFINE csum DECIMAL(18,2)
|
|
DEFINE ccnt INTEGER
|
|
DEFINE niv ARRAY[7] OF CHAR(35)
|
|
DEFINE agl ARRAY[5] OF CHAR(8)
|
|
DEFINE mar ARRAY[6] OF CHAR(20)
|
|
DEFINE ten ARRAY[5] OF CHAR(14)
|
|
|
|
LET niv[1]="NINGUNO" LET niv[2]="PRIMARIA"
|
|
LET niv[3]="SECUNDARIA" LET niv[4]="TECNICO SUPERIOR"
|
|
LET niv[5]="ESTUDIANTE UNIVERSITARIO" LET niv[6]="GRADO UNIVERSIT. (LIC.)"
|
|
LET niv[7]="POSGRADO"
|
|
LET agl[1]="18-25" LET agl[2]="26-30" LET agl[3]="31-40"
|
|
LET agl[4]="41-50" LET agl[5]="51+"
|
|
LET mar[1]="SOLTERO(A)" LET mar[2]="CASADO(A)" LET mar[3]="UNION LIBRE"
|
|
LET mar[4]="DIVORCIADO(A)" LET mar[5]="VIUDO(A)" LET mar[6]="NO INDICADO"
|
|
LET ten[1]="MENOS DE 1" LET ten[2]="1 A 5" LET ten[3]="6 A 10"
|
|
LET ten[4]="11 A 20" LET ten[5]="MAS DE 20"
|
|
|
|
FOR i=1 TO 7 LET c4[i,1]=0 LET c4[i,2]=0 END FOR
|
|
FOR i=1 TO 7 FOR g=1 TO 5 LET c5[i,g]=0 END FOR END FOR
|
|
FOR i=1 TO 6 FOR g=1 TO 7 LET c6[i,g]=0 END FOR END FOR
|
|
FOR i=1 TO 5 FOR g=1 TO 7 LET c7[i,g]=0 END FOR END FOR
|
|
FOR i=1 TO 6 FOR g=1 TO 5 LET s8sum[i,g]=0 LET s8cnt[i,g]=0 END FOR END FOR
|
|
|
|
LET selec =
|
|
"SELECT ISNULL(dep.sexo,''), ISNULL(e.estado_civil,''), e.fech_nac, ",
|
|
" e.fech_efec, ISNULL(e.sueldo_ac,0), RTRIM(ISNULL(ed.nom_educa,'')) ",
|
|
"FROM adtb00003 e ",
|
|
" LEFT JOIN adtb00005 ed ON ed.cod_educa = e.nivel_emp ",
|
|
" LEFT JOIN (SELECT num_emp, MAX(sexo) AS sexo FROM adtb00021 ",
|
|
" WHERE cod_par IS NULL GROUP BY num_emp) dep ON dep.num_emp = e.num_emp ",
|
|
"WHERE e.status_t IS NULL "
|
|
|
|
PREPARE q_demo FROM selec
|
|
DECLARE cur_demo CURSOR FOR q_demo
|
|
FOREACH cur_demo INTO e_sexo, e_ecivil, e_fnac, e_fefec, e_sueldo, e_nom
|
|
LET si = 0
|
|
IF UPSHIFT(e_sexo) = "M" THEN LET si = 1 END IF
|
|
IF UPSHIFT(e_sexo) = "F" THEN LET si = 2 END IF
|
|
LET nf = fila_educa(e_nom)
|
|
IF nf > 0 THEN LET nf = nf - 5 END IF -- 1..7 (0 si no mapea)
|
|
LET edad = anios_hasta_hoy(e_fnac)
|
|
LET ageg = 0
|
|
IF edad >= 0 THEN LET ageg = grupo_edad(edad) END IF
|
|
LET tanios = anios_hasta_hoy(e_fefec)
|
|
LET teng = 0
|
|
IF tanios >= 0 THEN LET teng = rango_antig(tanios) END IF
|
|
LET mi = grupo_marital(e_ecivil)
|
|
|
|
IF nf > 0 AND si > 0 THEN LET c4[nf,si] = c4[nf,si] + 1 END IF
|
|
IF nf > 0 AND ageg > 0 THEN LET c5[nf,ageg] = c5[nf,ageg] + 1 END IF
|
|
IF si > 0 THEN LET c6[mi,si] = c6[mi,si] + 1 END IF
|
|
IF ageg > 0 THEN LET c6[mi,2+ageg] = c6[mi,2+ageg] + 1 END IF
|
|
IF teng > 0 THEN
|
|
IF si > 0 THEN LET c7[teng,si] = c7[teng,si] + 1 END IF
|
|
IF ageg > 0 THEN LET c7[teng,2+ageg] = c7[teng,2+ageg] + 1 END IF
|
|
END IF
|
|
IF ageg > 0 THEN
|
|
LET s8sum[mi,ageg] = s8sum[mi,ageg] + e_sueldo
|
|
LET s8cnt[mi,ageg] = s8cnt[mi,ageg] + 1
|
|
END IF
|
|
END FOREACH
|
|
|
|
---------------- 4- Nivel academico por genero ----------------
|
|
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
|
|
CALL emite_fila("S", "4- NIVEL ACADEMICO POR GENERO", vals)
|
|
CALL limpia_vals(vals)
|
|
LET vals[1]="HOMBRE" LET vals[2]="MUJER" LET vals[3]="TOTAL"
|
|
CALL emite_fila("H", "NIVEL ACADEMICO", vals)
|
|
LET th_=0 LET tm_=0
|
|
FOR i=1 TO 7
|
|
CALL limpia_vals(vals)
|
|
LET vals[1] = c4[i,1] USING "-###,###,##&"
|
|
LET vals[2] = c4[i,2] USING "-###,###,##&"
|
|
LET vals[3] = (c4[i,1]+c4[i,2]) USING "-###,###,##&"
|
|
CALL emite_fila("D", niv[i], vals)
|
|
LET th_=th_+c4[i,1] LET tm_=tm_+c4[i,2]
|
|
END FOR
|
|
CALL limpia_vals(vals)
|
|
LET vals[1]=th_ USING "-###,###,##&" LET vals[2]=tm_ USING "-###,###,##&"
|
|
LET vals[3]=(th_+tm_) USING "-###,###,##&"
|
|
CALL emite_fila("D", "TOTAL", vals)
|
|
|
|
---------------- 5- Nivel academico por grupo de edad ----------------
|
|
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
|
|
CALL emite_fila("S", "5- NIVEL ACADEMICO POR GRUPO EDAD", vals)
|
|
CALL limpia_vals(vals)
|
|
FOR g=1 TO 5 LET vals[g]=agl[g] END FOR
|
|
LET vals[6]="TOTAL"
|
|
CALL emite_fila("H", "NIVEL ACADEMICO", vals)
|
|
FOR i=1 TO 7
|
|
CALL limpia_vals(vals)
|
|
LET tot=0
|
|
FOR g=1 TO 5
|
|
LET vals[g]=c5[i,g] USING "-###,###,##&"
|
|
LET tot=tot+c5[i,g]
|
|
END FOR
|
|
LET vals[6]=tot USING "-###,###,##&"
|
|
CALL emite_fila("D", niv[i], vals)
|
|
END FOR
|
|
CALL limpia_vals(vals)
|
|
LET tot=0
|
|
FOR g=1 TO 5
|
|
LET th_=0
|
|
FOR i=1 TO 7 LET th_=th_+c5[i,g] END FOR
|
|
LET vals[g]=th_ USING "-###,###,##&"
|
|
LET tot=tot+th_
|
|
END FOR
|
|
LET vals[6]=tot USING "-###,###,##&"
|
|
CALL emite_fila("D", "TOTAL", vals)
|
|
|
|
---------------- 6- Estatus marital por genero y grupo de edad ----------------
|
|
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
|
|
CALL emite_fila("S", "6- ESTADO CIVIL POR GENERO Y EDAD", vals)
|
|
CALL limpia_vals(vals)
|
|
LET vals[1]="HOMBRE" LET vals[2]="MUJER"
|
|
FOR g=1 TO 5 LET vals[2+g]=agl[g] END FOR
|
|
LET vals[8]="TOTAL"
|
|
CALL emite_fila("H", "ESTADO CIVIL", vals)
|
|
FOR i=1 TO 6
|
|
CALL limpia_vals(vals)
|
|
FOR g=1 TO 7 LET vals[g]=c6[i,g] USING "-###,###,##&" END FOR
|
|
LET vals[8]=(c6[i,1]+c6[i,2]) USING "-###,###,##&"
|
|
CALL emite_fila("D", mar[i], vals)
|
|
END FOR
|
|
|
|
---------------- 7- Tiempo en la empresa por genero y grupo de edad ----------------
|
|
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
|
|
CALL emite_fila("S", "7- ANTIGUEDAD POR GENERO Y EDAD (anos)", vals)
|
|
CALL limpia_vals(vals)
|
|
LET vals[1]="HOMBRE" LET vals[2]="MUJER"
|
|
FOR g=1 TO 5 LET vals[2+g]=agl[g] END FOR
|
|
LET vals[8]="TOTAL"
|
|
CALL emite_fila("H", "ANTIGUEDAD", vals)
|
|
FOR i=1 TO 5
|
|
CALL limpia_vals(vals)
|
|
FOR g=1 TO 7 LET vals[g]=c7[i,g] USING "-###,###,##&" END FOR
|
|
LET vals[8]=(c7[i,1]+c7[i,2]) USING "-###,###,##&"
|
|
CALL emite_fila("D", ten[i], vals)
|
|
END FOR
|
|
|
|
---------------- 8- Sueldo promedio por estado civil y grupo de edad ----------------
|
|
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
|
|
CALL emite_fila("S", "8- SUELDO PROMEDIO POR ESTADO CIVIL Y GRUPO EDAD", vals)
|
|
CALL limpia_vals(vals)
|
|
FOR g=1 TO 5 LET vals[g]=agl[g] END FOR
|
|
LET vals[6]="GENERAL"
|
|
CALL emite_fila("H", "ESTADO CIVIL", vals)
|
|
-- una fila por estado civil: promedio de sueldo por grupo de edad
|
|
FOR i=1 TO 6
|
|
CALL limpia_vals(vals)
|
|
LET gsum=0 LET gcnt=0
|
|
FOR g=1 TO 5
|
|
IF s8cnt[i,g] > 0 THEN
|
|
LET prom = s8sum[i,g] / s8cnt[i,g]
|
|
ELSE
|
|
LET prom = 0
|
|
END IF
|
|
LET vals[g] = prom USING "-###,###,##&.&&"
|
|
LET gsum = gsum + s8sum[i,g]
|
|
LET gcnt = gcnt + s8cnt[i,g]
|
|
END FOR
|
|
IF gcnt > 0 THEN LET prom = gsum / gcnt ELSE LET prom = 0 END IF
|
|
LET vals[6] = prom USING "-###,###,##&.&&"
|
|
CALL emite_fila("D", mar[i], vals)
|
|
END FOR
|
|
-- fila GENERAL: promedio por grupo de edad (todos los estados civiles)
|
|
CALL limpia_vals(vals)
|
|
LET gsum=0 LET gcnt=0
|
|
FOR g=1 TO 5
|
|
LET csum=0 LET ccnt=0
|
|
FOR i=1 TO 6
|
|
LET csum = csum + s8sum[i,g]
|
|
LET ccnt = ccnt + s8cnt[i,g]
|
|
END FOR
|
|
IF ccnt > 0 THEN LET prom = csum / ccnt ELSE LET prom = 0 END IF
|
|
LET vals[g] = prom USING "-###,###,##&.&&"
|
|
LET gsum = gsum + csum
|
|
LET gcnt = gcnt + ccnt
|
|
END FOR
|
|
IF gcnt > 0 THEN LET prom = gsum / gcnt ELSE LET prom = 0 END IF
|
|
LET vals[6] = prom USING "-###,###,##&.&&"
|
|
CALL emite_fila("D", "GENERAL", vals)
|
|
|
|
END FUNCTION
|
|
|
|
|
|
-- Limpia las 36 columnas de valores (las deja en blanco)
|
|
FUNCTION limpia_vals(v)
|
|
DEFINE v DYNAMIC ARRAY OF VARCHAR(24)
|
|
DEFINE i SMALLINT
|
|
FOR i = 1 TO 36
|
|
LET v[i] = " "
|
|
END FOR
|
|
END FUNCTION
|
|
|
|
|
|
-- Anos completos desde p_desde hasta hoy (-1 si es nulo)
|
|
FUNCTION anios_hasta_hoy(p_desde)
|
|
DEFINE p_desde DATE
|
|
DEFINE a INTEGER
|
|
IF p_desde IS NULL THEN RETURN -1 END IF
|
|
LET a = YEAR(TODAY) - YEAR(p_desde)
|
|
IF MONTH(TODAY) < MONTH(p_desde)
|
|
OR (MONTH(TODAY) = MONTH(p_desde) AND DAY(TODAY) < DAY(p_desde)) THEN
|
|
LET a = a - 1
|
|
END IF
|
|
RETURN a
|
|
END FUNCTION
|
|
|
|
|
|
-- Grupo de edad: 1=18-25 2=26-30 3=31-40 4=41-50 5=51+
|
|
FUNCTION grupo_edad(p_edad)
|
|
DEFINE p_edad INTEGER
|
|
IF p_edad <= 25 THEN RETURN 1 END IF
|
|
IF p_edad <= 30 THEN RETURN 2 END IF
|
|
IF p_edad <= 40 THEN RETURN 3 END IF
|
|
IF p_edad <= 50 THEN RETURN 4 END IF
|
|
RETURN 5
|
|
END FUNCTION
|
|
|
|
|
|
-- Rango antiguedad: 1=<1 2=1-5 3=6-10 4=11-20 5=20+
|
|
FUNCTION rango_antig(p_anos)
|
|
DEFINE p_anos INTEGER
|
|
IF p_anos < 1 THEN RETURN 1 END IF
|
|
IF p_anos <= 5 THEN RETURN 2 END IF
|
|
IF p_anos <= 10 THEN RETURN 3 END IF
|
|
IF p_anos <= 20 THEN RETURN 4 END IF
|
|
RETURN 5
|
|
END FUNCTION
|
|
|
|
|
|
-- Grupo estado civil: 1=S 2=C 3=U 4=D 5=V 6=otro/blanco
|
|
FUNCTION grupo_marital(p_ec)
|
|
DEFINE p_ec CHAR(1)
|
|
CASE UPSHIFT(p_ec)
|
|
WHEN "S" RETURN 1
|
|
WHEN "C" RETURN 2
|
|
WHEN "U" RETURN 3
|
|
WHEN "D" RETURN 4
|
|
WHEN "V" RETURN 5
|
|
OTHERWISE RETURN 6
|
|
END CASE
|
|
END FUNCTION
|