JSOTO ELIMINE LOS NOMBRES DEL PROYECTO DUPLICADOS

This commit is contained in:
2026-10-05 15:03:14 -04:00
parent f414a150d9
commit ccf12198ba
30 changed files with 7547 additions and 5802 deletions
+734 -36
View File
@@ -44,6 +44,38 @@ DEFINE vacacion RECORD
tipo_sueldo CHAR(20),
proporcion_vacaciones,salario_quincenal DEC(12,2)
#### VARIABLES PARA MODULO DE CAPACITACION (2026-10-05) ##########
#### tipo_mov 'CAPACITACION REQUERIDA' / 'CAPACITACION TOMADA'
#### detalle en adtb00060, catalogo en adtb00059 (adprmt017_capacitacion.sql)
DEFINE capac RECORD
tipo_desc VARCHAR(30),
id_requerida INTEGER,
cod_cap INTEGER,
evento SMALLINT,
horas_req DEC(6,2),
fecha_ini DATE,
fecha_fin DATE,
horas_tom DEC(6,2),
institucion VARCHAR(100),
costo DEC(12,2)
END RECORD
DEFINE cap_tot RECORD
trq, ttm, tpd DEC(8,2)
END RECORD
#### VARIABLES PARA DESVINCULACION (2026-10-05) ##########
#### tipo_mov 'CANCELAR' (mov. 4 DESVINCULAR) / 'DESVINCULAR' / 'TERMINO'
#### detalle en adtb00062, causas en adtb00061 (adprmt017_desvinculacion.sql)
DEFINE desv RECORD
fecha_salida DATE,
cod_causa SMALLINT,
clase_desc VARCHAR(20),
recontratable CHAR(1),
detalle VARCHAR(200)
END RECORD
DEFINE realiza_desvinculacion BOOLEAN
DEFINE realiza_capacitacion BOOLEAN,
cap_sql STRING
#### MODULO MENU GENERAL DE ACCION DE NOMINA #####
MAIN
@@ -479,6 +511,28 @@ FUNCTION adpcad017()
END IF
END IF
## LLAMA LA VENTANA DE CAPACITACION (REQUERIDA / TOMADA)
IF xtipo = "CAPACITACION REQUERIDA" OR xtipo = "CAPACITACION TOMADA" THEN
CALL capacitacion('A') RETURNING realiza_capacitacion
IF NOT realiza_capacitacion THEN
RETURN
END IF
NEXT FIELD observacion
END IF
## LLAMA LA VENTANA DE DESVINCULACION (CAUSA DE SALIDA)
IF es_desvinculacion(xtipo) THEN
IF empleado_desactivado(acc_per.num_emp) THEN
CALL fgl_winmessage("INFO","ESTE EMPLEADO YA ESTA DESACTIVADO","info")
NEXT FIELD num_emp
END IF
CALL desvinculacion('A') RETURNING realiza_desvinculacion
IF NOT realiza_desvinculacion THEN
RETURN
END IF
NEXT FIELD observacion
END IF
AFTER FIELD sueldo_ac
IF acc_per.sueldo_ac IS NULL OR acc_per.sueldo_ac < 0 THEN
LET numero_msg = 16
@@ -666,9 +720,18 @@ FUNCTION adpcad017()
RETURN
END IF
## SE ASEGURA DE QUE TODA LA INFORMACION ESTE CORRECTA
PROMPT "Informacion Correcta? (S/N).." FOR CHAR opt
LET opt = UPSHIFT(opt)
## SE ASEGURA DE QUE TODA LA INFORMACION ESTE CORRECTA
IF fgl_winquestion("ACCION DE PERSONAL","La informacion esta correcta? Desea grabar la accion?",
"YES","YES|NO","question",0) = "YES" THEN
LET opt = "S"
ELSE
LET opt = "N"
# Antes de 2026-10-05 un "N" seguia de largo: mensaje de grabado,
# UPDATE de adtb00028 con num_trx nulo y pregunta de impresion.
LET numero_msg = 2
CALL msg(numero_msg)
RETURN
END IF
## SI NO HA OCURRIDO NINGUN PROBLEMA SE PROCEDE A INSERTAR LA INFORMACION
## EN LA TABLA DE ACCION DE PERSONAL
@@ -751,8 +814,17 @@ FUNCTION adpcad017()
VALUES (vacacion.num_nomi,acc_per.nomina,acc_per.num_emp,acc_per.departamento,acc_per.departamento,acc_per.nivel_emp,
acc_per.cod_puesto,vacacion.cod_mov2,salario_quincenal,usuarios,getdate(),
acc_per.num_trx,acc_per.cod_mto)
END IF
END IF
END IF
IF xtipo = "CAPACITACION REQUERIDA" OR xtipo = "CAPACITACION TOMADA" THEN
CALL graba_capacitacion()
END IF
## DESVINCULACION: DESACTIVA AL EMPLEADO (status_t = 'D') Y GUARDA LA CAUSA
IF es_desvinculacion(xtipo) THEN
CALL graba_desvinculacion()
END IF
################## DATOS PARA INSERTAR O MODIFICAR PETB00003 ############
@@ -877,16 +949,9 @@ FUNCTION adpcad017()
COMMIT WORK
END IF
## ACTUALIZA LA TABLA DE EMPLEADOS EN CUANTO AL MOVIMIENTO DE LAS TERMINACIONES
## DE LA ACCION DE PERSONAL
IF xtipo = "TERMINO" THEN
UPDATE adtb00003 SET status_t = "T"
WHERE num_emp = acc_per.num_emp
UPDATE adtb00021 SET status_t = "T"
WHERE num_emp = acc_per.num_emp
END IF
## LAS TERMINACIONES (TERMINO/CANCELAR/DESVINCULAR) SE GRABAN DENTRO DE LA
## TRANSACCION EN graba_desvinculacion() (2026-10-05). Antes ponia status_t='T'
## pero el movimiento existente es 'CANCELAR' y nunca entraba aqui.
## ACTUALIZA LA TABLA DE SECUENCIA NUMERICA
UPDATE adtb00028 SET num_trx = acc_per.num_trx
@@ -895,19 +960,28 @@ FUNCTION adpcad017()
LET numero_msg = 1
CALL msg(numero_msg)
CLEAR FORM
LABEL preg:
PROMPT "Desea Imprimir Este Documento (S/N)?..." FOR CHAR optt
LET optt = UPSHIFT(optt)
IF optt IS NULL OR (optt != "S" AND optt != "N") THEN
GOTO preg
END IF
IF fgl_winquestion("ACCION DE PERSONAL","Accion grabada. Desea imprimir el documento?",
"NO","YES|NO","question",0) = "YES" THEN
LET optt = "S"
ELSE
LET optt = "N"
END IF
IF optt = "S" THEN
CALL configureoutput("PDF") RETURNING handler
START REPORT imp_accion TO XML HANDLER handler
OUTPUT TO REPORT imp_accion()
FINISH REPORT imp_accion
RUN imprime
# 2026-10-05: antes usaba configureoutput("PDF"), que carga el motor
# SIN diseno (loadCurrentSettings(NULL)) -> PDF en blanco. Ahora usa
# el mismo adprmt017.4rp que la consulta.
IF fgl_report_loadCurrentSettings("adprmt017.4rp") THEN
CALL fgl_report_selectDevice("PDF")
CALL fgl_report_selectPreview(TRUE)
LET handler = fgl_report_commitCurrentSettings()
IF handler IS NOT NULL THEN
START REPORT imp_accion TO XML HANDLER handler
OUTPUT TO REPORT imp_accion()
FINISH REPORT imp_accion
END IF
ELSE
CALL fgl_winmessage("INFO","No se pudo cargar el diseno adprmt017.4rp","stop")
END IF
END IF
END FUNCTION
@@ -1559,7 +1633,13 @@ FUNCTION adpcmf017()
UPDATE notb00007 SET status_t ="E",
us_mod = usuarios,
fech_mod = getdate()
WHERE num_trx = acc_per.num_trx AND cod_mto = acc_per.cod_mto
WHERE num_trx = acc_per.num_trx AND cod_mto = acc_per.cod_mto
IF xtipo = "CAPACITACION REQUERIDA" OR xtipo = "CAPACITACION TOMADA" THEN
CALL anula_capacitacion(acc_per.num_trx)
END IF
IF es_desvinculacion(xtipo) THEN
CALL anula_desvinculacion(acc_per.num_trx, acc_per.num_emp)
END IF
COMMIT WORK
LET numero_msg = 39
CALL msg(numero_msg)
@@ -1704,8 +1784,19 @@ nombre5 clipped," ",nombre6 clipped," ",apellido5 clipped," ",apellido6 clipped
END IF
CALL vacaciones('C') RETURNING realiza_vacaciones # CUANDO ESTA CONSULTANDO ES 'C' Y ADICIONANDO ES 'A'
END IF
## DATOS CAPACITACION
IF xtipo = "CAPACITACION REQUERIDA" OR xtipo = "CAPACITACION TOMADA" THEN
CALL carga_capacitacion(acc_per.num_trx)
CALL capacitacion('C') RETURNING realiza_capacitacion
END IF
## DATOS DESVINCULACION
IF es_desvinculacion(xtipo) THEN
IF carga_desvinculacion(acc_per.num_trx) THEN
CALL desvinculacion('C') RETURNING realiza_desvinculacion
END IF
END IF
@@ -1946,7 +2037,574 @@ FUNCTION vacaciones(operacion)
END IF
END FUNCTION
## VENTANA DE LOS NIVELES DEL LOS EMPLEADOS
##################################################################
## CAPACITACION (2026-10-05)
## 'CAPACITACION REQUERIDA' : plan de horas por empleado (tipo_reg 'R')
## 'CAPACITACION TOMADA' : horas ejecutadas (tipo_reg 'T'), puede
## cubrir una requerida (id_requerida)
## Tablas adtb00059/adtb00060 via SQL dinamico (no estan en smarmotech.sch)
##################################################################
FUNCTION capacitacion(operacion)
DEFINE operacion VARCHAR(1),
es_requerida BOOLEAN,
pend DEC(8,2),
xcod INTEGER,
xnum INTEGER
LET int_flag = FALSE
LET es_requerida = (xtipo = "CAPACITACION REQUERIDA")
OPEN WINDOW adwindow17 AT 10,12 WITH FORM "adfmwd017"
ATTRIBUTE(BORDER,FORM LINE FIRST + 2)
CALL combo_capacitaciones()
CALL combo_requeridas(acc_per.num_emp, operacion = 'C')
CALL totales_capacitacion(acc_per.num_emp)
IF operacion = 'A' THEN
INITIALIZE capac.* TO NULL
LET capac.tipo_desc = xtipo
LET capac.fecha_ini = acc_per.fech_efec
INPUT BY NAME capac.* WITHOUT DEFAULTS ATTRIBUTE(UNBUFFERED)
BEFORE INPUT
DISPLAY BY NAME cap_tot.*
IF es_requerida THEN
CALL DIALOG.setFieldActive("id_requerida", FALSE)
CALL DIALOG.setFieldActive("horas_tom", FALSE)
CALL DIALOG.setFieldActive("fecha_fin", FALSE)
ELSE
CALL DIALOG.setFieldActive("horas_req", FALSE)
END IF
ON CHANGE id_requerida
IF capac.id_requerida IS NOT NULL THEN
CALL datos_requerida(capac.id_requerida)
RETURNING capac.cod_cap, capac.evento, pend
LET capac.horas_req = pend
IF capac.horas_tom IS NULL THEN
LET capac.horas_tom = pend
END IF
CALL DIALOG.setFieldActive("cod_cap", FALSE)
ELSE
LET capac.cod_cap = NULL
LET capac.evento = NULL
LET capac.horas_req = NULL
CALL DIALOG.setFieldActive("cod_cap", TRUE)
END IF
ON CHANGE cod_cap
IF capac.cod_cap IS NOT NULL THEN
CALL datos_curso(capac.cod_cap) RETURNING capac.evento, pend
IF es_requerida THEN
LET capac.horas_req = pend
ELSE
IF capac.horas_tom IS NULL THEN
LET capac.horas_tom = pend
END IF
END IF
END IF
ON ACTION nuevo_curso
CALL nuevo_curso() RETURNING xcod
IF xcod IS NOT NULL THEN
CALL combo_capacitaciones()
LET capac.cod_cap = xcod
CALL datos_curso(capac.cod_cap) RETURNING capac.evento, pend
IF es_requerida THEN
LET capac.horas_req = pend
ELSE
LET capac.horas_tom = pend
END IF
END IF
AFTER INPUT
IF int_flag THEN
EXIT INPUT
END IF
IF capac.cod_cap IS NULL THEN
CALL fgl_winmessage("INFO","DEBE SELECCIONAR LA CAPACITACION","info")
NEXT FIELD cod_cap
END IF
IF es_requerida THEN
IF capac.horas_req IS NULL OR capac.horas_req <= 0 THEN
CALL fgl_winmessage("INFO","DEBE INDICAR LAS HORAS REQUERIDAS","info")
NEXT FIELD horas_req
END IF
# Evita duplicar una requerida que todavia esta pendiente
LET xnum = 0
LET cap_sql =
"SELECT COUNT(*) FROM adtb00060 r WHERE r.num_emp = ? AND r.cod_cap = ? ",
" AND r.tipo_reg = 'R' AND r.status_t IS NULL ",
" AND r.horas_req > ISNULL((SELECT SUM(t.horas_tom) FROM adtb00060 t ",
" WHERE t.id_requerida = r.id_cap AND t.status_t IS NULL),0)"
PREPARE p_cap_dup FROM cap_sql
EXECUTE p_cap_dup INTO xnum USING acc_per.num_emp, capac.cod_cap
IF xnum > 0 THEN
IF fgl_winquestion("INFO",
"ESTE EMPLEADO YA TIENE ESTA CAPACITACION REQUERIDA PENDIENTE. DESEA REGISTRARLA DE NUEVO?",
"NO","YES|NO","QUESTION",0) = "NO" THEN
NEXT FIELD cod_cap
END IF
END IF
ELSE
IF capac.horas_tom IS NULL OR capac.horas_tom <= 0 THEN
CALL fgl_winmessage("INFO","DEBE INDICAR LAS HORAS TOMADAS","info")
NEXT FIELD horas_tom
END IF
IF capac.fecha_ini IS NULL THEN
CALL fgl_winmessage("INFO","DEBE INDICAR LA FECHA DE INICIO","info")
NEXT FIELD fecha_ini
END IF
IF capac.fecha_fin IS NOT NULL AND capac.fecha_fin < capac.fecha_ini THEN
CALL fgl_winmessage("INFO","LA FECHA FIN NO PUEDE SER MENOR QUE LA FECHA INICIO","info")
NEXT FIELD fecha_fin
END IF
IF capac.id_requerida IS NOT NULL AND capac.horas_tom > capac.horas_req THEN
IF fgl_winquestion("INFO",
"LAS HORAS TOMADAS EXCEDEN LAS HORAS PENDIENTES DE LA REQUERIDA. CONTINUAR?",
"NO","YES|NO","QUESTION",0) = "NO" THEN
NEXT FIELD horas_tom
END IF
END IF
END IF
END INPUT
ELSE
LET capac.tipo_desc = xtipo
DISPLAY BY NAME capac.*, cap_tot.*
MENU "Capacitacion"
COMMAND "Cerrar" "Cierra la ventana de capacitacion"
EXIT MENU
ON ACTION close
EXIT MENU
END MENU
END IF
CLOSE WINDOW adwindow17
IF int_flag THEN
LET numero_msg = 2
CALL msg(numero_msg)
LET int_flag = FALSE
INITIALIZE capac.* TO NULL
RETURN FALSE
END IF
RETURN TRUE
END FUNCTION
## LLENA EL COMBO DEL CATALOGO DE CAPACITACIONES
FUNCTION combo_capacitaciones()
DEFINE cb ui.ComboBox,
xcod INTEGER,
xnom VARCHAR(100)
LET cb = ui.ComboBox.forName("formonly.cod_cap")
IF cb IS NULL THEN
RETURN
END IF
CALL cb.clear()
LET cap_sql =
"SELECT cod_cap, nom_cap FROM adtb00059 WHERE status_t IS NULL ORDER BY nom_cap"
PREPARE p_cap_cat FROM cap_sql
DECLARE c_cap_cat CURSOR FOR p_cap_cat
FOREACH c_cap_cat INTO xcod, xnom
CALL cb.addItem(xcod, xnom CLIPPED)
END FOREACH
FREE c_cap_cat
END FUNCTION
## LLENA EL COMBO DE CAPACITACIONES REQUERIDAS DEL EMPLEADO
## p_todas = FALSE solo las que tienen horas pendientes (captura)
FUNCTION combo_requeridas(p_num_emp, p_todas)
DEFINE p_num_emp INTEGER,
p_todas BOOLEAN,
cb ui.ComboBox,
xid INTEGER,
xnom VARCHAR(100),
pend DEC(8,2)
LET cb = ui.ComboBox.forName("formonly.id_requerida")
IF cb IS NULL THEN
RETURN
END IF
CALL cb.clear()
LET cap_sql =
"SELECT r.id_cap, c.nom_cap, ",
" ISNULL(r.horas_req,0) - ISNULL((SELECT SUM(t.horas_tom) FROM adtb00060 t ",
" WHERE t.id_requerida = r.id_cap AND t.status_t IS NULL),0) ",
"FROM adtb00060 r JOIN adtb00059 c ON c.cod_cap = r.cod_cap ",
"WHERE r.num_emp = ? AND r.tipo_reg = 'R' AND r.status_t IS NULL ",
"ORDER BY c.nom_cap"
PREPARE p_cap_req FROM cap_sql
DECLARE c_cap_req CURSOR FOR p_cap_req
FOREACH c_cap_req USING p_num_emp INTO xid, xnom, pend
IF NOT p_todas AND pend <= 0 THEN
CONTINUE FOREACH
END IF
CALL cb.addItem(xid, xnom CLIPPED || " (" || (pend USING "<<<&.&&") || " h pend.)")
END FOREACH
FREE c_cap_req
END FUNCTION
## TOTALES DE HORAS DEL EMPLEADO: REQUERIDAS, TOMADAS Y PENDIENTES
FUNCTION totales_capacitacion(p_num_emp)
DEFINE p_num_emp INTEGER
LET cap_tot.trq = 0
LET cap_tot.ttm = 0
LET cap_sql =
"SELECT ISNULL(SUM(CASE WHEN tipo_reg = 'R' THEN horas_req END),0), ",
" ISNULL(SUM(CASE WHEN tipo_reg = 'T' THEN horas_tom END),0) ",
"FROM adtb00060 WHERE num_emp = ? AND status_t IS NULL"
PREPARE p_cap_tot FROM cap_sql
EXECUTE p_cap_tot INTO cap_tot.trq, cap_tot.ttm USING p_num_emp
# Pendiente = lo requerido que falta por cubrir (las tomadas sin requerida no restan)
LET cap_sql =
"SELECT ISNULL(SUM(CASE WHEN x.pend > 0 THEN x.pend ELSE 0 END),0) FROM ( ",
" SELECT ISNULL(r.horas_req,0) - ISNULL((SELECT SUM(t.horas_tom) FROM adtb00060 t ",
" WHERE t.id_requerida = r.id_cap AND t.status_t IS NULL),0) pend ",
" FROM adtb00060 r WHERE r.num_emp = ? AND r.tipo_reg = 'R' AND r.status_t IS NULL) x"
PREPARE p_cap_pend FROM cap_sql
EXECUTE p_cap_pend INTO cap_tot.tpd USING p_num_emp
END FUNCTION
## TIPO DE EVENTO Y HORAS ESTANDAR DE UN CURSO DEL CATALOGO
FUNCTION datos_curso(p_cod)
DEFINE p_cod INTEGER,
xev SMALLINT,
xhoras DEC(8,2)
LET cap_sql = "SELECT evento, horas FROM adtb00059 WHERE cod_cap = ?"
PREPARE p_cap_cur FROM cap_sql
EXECUTE p_cap_cur INTO xev, xhoras USING p_cod
RETURN xev, xhoras
END FUNCTION
## CURSO, EVENTO Y HORAS PENDIENTES DE UNA CAPACITACION REQUERIDA
FUNCTION datos_requerida(p_id)
DEFINE p_id INTEGER,
xcod INTEGER,
xev SMALLINT,
pend DEC(8,2)
LET cap_sql =
"SELECT r.cod_cap, c.evento, ",
" ISNULL(r.horas_req,0) - ISNULL((SELECT SUM(t.horas_tom) FROM adtb00060 t ",
" WHERE t.id_requerida = r.id_cap AND t.status_t IS NULL),0) ",
"FROM adtb00060 r JOIN adtb00059 c ON c.cod_cap = r.cod_cap WHERE r.id_cap = ?"
PREPARE p_cap_dreq FROM cap_sql
EXECUTE p_cap_dreq INTO xcod, xev, pend USING p_id
RETURN xcod, xev, pend
END FUNCTION
## AGREGA UN CURSO AL CATALOGO adtb00059 Y DEVUELVE SU CODIGO
FUNCTION nuevo_curso()
DEFINE nc RECORD
nom_cap VARCHAR(100),
evento SMALLINT,
horas DEC(6,2)
END RECORD,
xnom VARCHAR(100),
xev SMALLINT,
xhoras DEC(6,2),
xcod INTEGER
# Ventana adfmwd019: nombre, tipo y horas en un solo paso
LET int_flag = FALSE
LET nc.nom_cap = NULL
LET nc.evento = 2
LET nc.horas = NULL
OPEN WINDOW adwindow19 AT 12,14 WITH FORM "adfmwd019"
ATTRIBUTE(BORDER,FORM LINE FIRST + 2)
INPUT BY NAME nc.* WITHOUT DEFAULTS ATTRIBUTE(UNBUFFERED)
AFTER INPUT
IF int_flag THEN
EXIT INPUT
END IF
IF nc.nom_cap IS NULL OR length(nc.nom_cap CLIPPED) = 0 THEN
CALL fgl_winmessage("INFO","DEBE INDICAR EL NOMBRE DE LA CAPACITACION","info")
NEXT FIELD nom_cap
END IF
IF nc.horas IS NOT NULL AND nc.horas < 0 THEN
CALL fgl_winmessage("INFO","LAS HORAS NO PUEDEN SER NEGATIVAS","info")
NEXT FIELD horas
END IF
END INPUT
CLOSE WINDOW adwindow19
IF int_flag THEN
LET int_flag = FALSE
RETURN NULL
END IF
LET xnom = upshift(nc.nom_cap CLIPPED)
LET xev = nc.evento
IF xev IS NULL OR xev < 1 OR xev > 4 THEN
LET xev = 2
END IF
LET xhoras = nc.horas
IF xhoras IS NULL THEN
LET xhoras = 0
END IF
LET xcod = NULL
LET cap_sql = "SELECT cod_cap FROM adtb00059 WHERE nom_cap = ? AND status_t IS NULL"
PREPARE p_cap_bnom FROM cap_sql
EXECUTE p_cap_bnom INTO xcod USING xnom
IF xcod IS NOT NULL THEN
CALL fgl_winmessage("INFO","ESA CAPACITACION YA EXISTE EN EL CATALOGO, SE SELECCIONA","info")
RETURN xcod
END IF
LET cap_sql =
"INSERT INTO adtb00059 (nom_cap, evento, horas, us_crea, fech_crea) ",
"VALUES (?, ?, ?, SUSER_SNAME(), GETDATE())"
PREPARE p_cap_ins_cat FROM cap_sql
EXECUTE p_cap_ins_cat USING xnom, xev, xhoras
EXECUTE p_cap_bnom INTO xcod USING xnom
RETURN xcod
END FUNCTION
## GRABA EL DETALLE DE CAPACITACION DE LA ACCION (dentro de la transaccion)
FUNCTION graba_capacitacion()
DEFINE xtipo_reg CHAR(1)
IF xtipo = "CAPACITACION REQUERIDA" THEN
LET xtipo_reg = "R"
LET capac.id_requerida = NULL
LET capac.horas_tom = NULL
LET capac.fecha_fin = NULL
ELSE
LET xtipo_reg = "T"
LET capac.horas_req = NULL
END IF
LET cap_sql =
"INSERT INTO adtb00060 (num_trx, num_emp, tipo_reg, cod_cap, id_requerida, ",
" horas_req, horas_tom, fecha_ini, fecha_fin, institucion, costo, us_crea, fech_crea) ",
"VALUES (?,?,?,?,?,?,?,?,?,?,?, SUSER_SNAME(), GETDATE())"
PREPARE p_cap_ins FROM cap_sql
EXECUTE p_cap_ins USING acc_per.num_trx, acc_per.num_emp, xtipo_reg, capac.cod_cap,
capac.id_requerida, capac.horas_req, capac.horas_tom,
capac.fecha_ini, capac.fecha_fin, capac.institucion, capac.costo
END FUNCTION
## CARGA EL DETALLE DE CAPACITACION DE UNA ACCION PARA CONSULTA
FUNCTION carga_capacitacion(p_trx)
DEFINE p_trx INTEGER
INITIALIZE capac.* TO NULL
LET cap_sql =
"SELECT a.id_requerida, a.cod_cap, c.evento, a.horas_req, a.fecha_ini, a.fecha_fin, ",
" a.horas_tom, a.institucion, a.costo ",
"FROM adtb00060 a JOIN adtb00059 c ON c.cod_cap = a.cod_cap WHERE a.num_trx = ?"
PREPARE p_cap_sel FROM cap_sql
EXECUTE p_cap_sel INTO capac.id_requerida, capac.cod_cap, capac.evento, capac.horas_req,
capac.fecha_ini, capac.fecha_fin, capac.horas_tom,
capac.institucion, capac.costo
USING p_trx
END FUNCTION
## ANULA EL DETALLE DE CAPACITACION JUNTO CON LA ACCION
FUNCTION anula_capacitacion(p_trx)
DEFINE p_trx INTEGER
LET cap_sql =
"UPDATE adtb00060 SET status_t = 'E', us_mod = ?, fech_mod = GETDATE() WHERE num_trx = ?"
PREPARE p_cap_anu FROM cap_sql
EXECUTE p_cap_anu USING usuarios, p_trx
END FUNCTION
##################################################################
## DESVINCULACION (2026-10-05)
## La desactivacion del empleado (adtb00003.status_t = 'D') se hace
## por la accion de personal; noprmt016 ya no desactiva.
## Causa codificada en adtb00062 (catalogo adtb00061) para Rotacion.
##################################################################
FUNCTION es_desvinculacion(p_tipo)
DEFINE p_tipo VARCHAR(25)
LET p_tipo = p_tipo CLIPPED
RETURN (p_tipo = "CANCELAR" OR p_tipo = "DESVINCULAR" OR p_tipo = "TERMINO")
END FUNCTION
FUNCTION empleado_desactivado(p_num_emp)
DEFINE p_num_emp INTEGER,
xst CHAR(1)
LET xst = NULL
SELECT a.status_t INTO xst FROM adtb00003 a WHERE a.num_emp = p_num_emp
RETURN (xst = "D")
END FUNCTION
FUNCTION desvinculacion(operacion)
DEFINE operacion VARCHAR(1),
cb ui.ComboBox,
xcod SMALLINT,
xdesc VARCHAR(60),
xingreso DATE
LET int_flag = FALSE
OPEN WINDOW adwindow18 AT 10,12 WITH FORM "adfmwd018"
ATTRIBUTE(BORDER,FORM LINE FIRST + 2)
LET cb = ui.ComboBox.forName("formonly.cod_causa")
CALL cb.clear()
LET cap_sql = "SELECT cod_causa, desc_causa FROM adtb00061 WHERE status_t IS NULL ORDER BY cod_causa"
PREPARE p_desv_cat FROM cap_sql
DECLARE c_desv_cat CURSOR FOR p_desv_cat
FOREACH c_desv_cat INTO xcod, xdesc
CALL cb.addItem(xcod, xdesc CLIPPED)
END FOREACH
FREE c_desv_cat
IF operacion = 'A' THEN
INITIALIZE desv.* TO NULL
LET desv.fecha_salida = acc_per.fech_efec
LET desv.recontratable = "S"
INPUT BY NAME desv.* WITHOUT DEFAULTS ATTRIBUTE(UNBUFFERED)
ON CHANGE cod_causa
LET desv.clase_desc = clase_causa(desv.cod_causa)
AFTER INPUT
IF int_flag THEN
EXIT INPUT
END IF
IF desv.fecha_salida IS NULL THEN
CALL fgl_winmessage("INFO","DEBE INDICAR LA FECHA DE SALIDA","info")
NEXT FIELD fecha_salida
END IF
LET xingreso = NULL
SELECT a.fech_efec INTO xingreso FROM adtb00003 a WHERE a.num_emp = acc_per.num_emp
IF xingreso IS NOT NULL AND desv.fecha_salida < xingreso THEN
CALL fgl_winmessage("INFO","LA FECHA DE SALIDA ES MENOR QUE LA FECHA DE INGRESO","info")
NEXT FIELD fecha_salida
END IF
IF desv.cod_causa IS NULL THEN
CALL fgl_winmessage("INFO","DEBE SELECCIONAR LA CAUSA DE LA SALIDA","info")
NEXT FIELD cod_causa
END IF
IF desv.recontratable IS NULL THEN
CALL fgl_winmessage("INFO","INDIQUE SI EL EMPLEADO ES RECONTRATABLE","info")
NEXT FIELD recontratable
END IF
END INPUT
ELSE
LET desv.clase_desc = clase_causa(desv.cod_causa)
DISPLAY BY NAME desv.*
MENU "Desvinculacion"
COMMAND "Cerrar" "Cierra la ventana de desvinculacion"
EXIT MENU
ON ACTION close
EXIT MENU
END MENU
END IF
CLOSE WINDOW adwindow18
IF int_flag THEN
LET numero_msg = 2
CALL msg(numero_msg)
LET int_flag = FALSE
INITIALIZE desv.* TO NULL
RETURN FALSE
END IF
RETURN TRUE
END FUNCTION
## DESCRIPCION DE LA CLASE DE LA CAUSA (VOLUNTARIA / INVOLUNTARIA / OTRA)
FUNCTION clase_causa(p_cod)
DEFINE p_cod SMALLINT,
xclase CHAR(1)
LET xclase = NULL
LET cap_sql = "SELECT clase FROM adtb00061 WHERE cod_causa = ?"
PREPARE p_desv_clase FROM cap_sql
EXECUTE p_desv_clase INTO xclase USING p_cod
CASE xclase
WHEN "V" RETURN "VOLUNTARIA"
WHEN "I" RETURN "INVOLUNTARIA"
WHEN "O" RETURN "OTRA"
END CASE
RETURN NULL
END FUNCTION
## GRABA LA DESVINCULACION Y DESACTIVA AL EMPLEADO (dentro de la transaccion)
FUNCTION graba_desvinculacion()
DEFINE xdep, xpuesto SMALLINT,
xtipo_emp VARCHAR(20),
xingreso DATE,
xdesc VARCHAR(60),
xmotivo VARCHAR(255)
SELECT a.departamento, a.cod_puesto, a.tipo_empleado, a.fech_efec
INTO xdep, xpuesto, xtipo_emp, xingreso
FROM adtb00003 a
WHERE a.num_emp = acc_per.num_emp
LET cap_sql =
"INSERT INTO adtb00062 (num_trx, num_emp, fecha_salida, cod_causa, recontratable, detalle, ",
" departamento, cod_puesto, tipo_empleado, fech_ingreso, origen, us_crea, fech_crea) ",
"VALUES (?,?,?,?,?,?,?,?,?,?,'A', SUSER_SNAME(), GETDATE())"
PREPARE p_desv_ins FROM cap_sql
EXECUTE p_desv_ins USING acc_per.num_trx, acc_per.num_emp, desv.fecha_salida, desv.cod_causa,
desv.recontratable, desv.detalle, xdep, xpuesto, xtipo_emp, xingreso
# Motivo al inicio de adtb00003.observacion (lo que ya habia se conserva detras)
LET xdesc = NULL
LET cap_sql = "SELECT desc_causa FROM adtb00061 WHERE cod_causa = ?"
PREPARE p_desv_desc FROM cap_sql
EXECUTE p_desv_desc INTO xdesc USING desv.cod_causa
LET xmotivo = xdesc CLIPPED, " ", desv.fecha_salida USING "dd/mm/yyyy"
IF desv.detalle IS NOT NULL THEN
LET xmotivo = xmotivo CLIPPED, " ", desv.detalle CLIPPED
END IF
IF desv.recontratable = "N" THEN
LET xmotivo = xmotivo CLIPPED, " NO REINGRESO"
END IF
LET cap_sql =
"UPDATE adtb00003 SET status_t = 'D', fecha_salida = ?, ",
" observacion = LEFT(? + CASE WHEN observacion IS NULL OR LTRIM(observacion) = '' ",
" THEN '' ELSE ' | ' + observacion END, 255), ",
" us_mod = SUSER_SNAME(), fech_mod = GETDATE() ",
"WHERE num_emp = ?"
PREPARE p_desv_emp FROM cap_sql
EXECUTE p_desv_emp USING desv.fecha_salida, xmotivo, acc_per.num_emp
END FUNCTION
## CARGA LA DESVINCULACION DE UNA ACCION PARA CONSULTA
FUNCTION carga_desvinculacion(p_trx)
DEFINE p_trx INTEGER
INITIALIZE desv.* TO NULL
LET cap_sql =
"SELECT fecha_salida, cod_causa, recontratable, detalle FROM adtb00062 WHERE num_trx = ?"
PREPARE p_desv_sel FROM cap_sql
EXECUTE p_desv_sel INTO desv.fecha_salida, desv.cod_causa, desv.recontratable, desv.detalle
USING p_trx
# Las desvinculaciones anteriores a 2026-10-05 no tienen detalle
RETURN (desv.cod_causa IS NOT NULL)
END FUNCTION
## ANULA LA DESVINCULACION Y REACTIVA AL EMPLEADO SI NO TIENE OTRA SALIDA VIGENTE
FUNCTION anula_desvinculacion(p_trx, p_num_emp)
DEFINE p_trx, p_num_emp INTEGER
LET cap_sql =
"UPDATE adtb00062 SET status_t = 'E', us_mod = ?, fech_mod = GETDATE() WHERE num_trx = ?"
PREPARE p_desv_anu FROM cap_sql
EXECUTE p_desv_anu USING usuarios, p_trx
# Acciones anteriores a 2026-10-05 no tienen detalle: no se reactiva al empleado
IF sqlca.sqlerrd[3] = 0 THEN
RETURN
END IF
LET cap_sql =
"UPDATE adtb00003 SET status_t = NULL, fecha_salida = NULL, us_mod = ?, fech_mod = GETDATE() ",
"WHERE num_emp = ? AND status_t = 'D' ",
" AND NOT EXISTS (SELECT 1 FROM adtb00062 d WHERE d.num_emp = ? AND d.status_t IS NULL)"
PREPARE p_desv_react FROM cap_sql
EXECUTE p_desv_react USING usuarios, p_num_emp, p_num_emp
END FUNCTION
## VENTANA DE LOS NIVELES DEL LOS EMPLEADOS
FUNCTION busca_nivel()
OPEN WINDOW busqueda AT 10,10 WITH FORM "adfmwd008"
ATTRIBUTE (BORDER,FORM LINE FIRST + 2, comment line last)
@@ -2036,8 +2694,13 @@ DEFINE doble_of,doble_on,doble_off,negrillas_on,negrillas_off,comp_on,comp_of,
depende,codigo_s,cod_provincia,codigo_n,serie SMALLINT,
fecha_nac DATE,
provincia,nombre_nac CHAR(30),
hoy VARCHAR(25)
hoy VARCHAR(25),
# Bloque de detalle para CAPACITACION / DESVINCULACION (2026-10-05).
# es_vac = 1 muestra el bloque de vacaciones del .4rp; 0 muestra el detalle.
es_vac SMALLINT,
det_tit, det1, det2, det3 VARCHAR(150),
xnom_det VARCHAR(100)
OUTPUT
TOP MARGIN 4
LEFT MARGIN 0
@@ -2085,9 +2748,43 @@ ON EVERY ROW
SELECT @desc_mto INTO mov_emp.desc_mto
FROM adtb00009
WHERE @cod_mto = acc_per.cod_mto
WHERE @cod_mto = acc_per.cod_mto
## DETALLE SEGUN EL MOVIMIENTO (CAPACITACION / DESVINCULACION)
LET es_vac = 1
LET det_tit = NULL LET det1 = NULL LET det2 = NULL LET det3 = NULL
IF xtipo = "CAPACITACION REQUERIDA" OR xtipo = "CAPACITACION TOMADA" THEN
LET es_vac = 0
LET xnom_det = NULL
LET cap_sql = "SELECT nom_cap FROM adtb00059 WHERE cod_cap = ?"
PREPARE p_imp_cap FROM cap_sql
EXECUTE p_imp_cap INTO xnom_det USING capac.cod_cap
LET det_tit = xtipo CLIPPED
LET det1 = "CAPACITACION: ", xnom_det CLIPPED
IF xtipo = "CAPACITACION REQUERIDA" THEN
LET det2 = "HORAS REQUERIDAS: ", capac.horas_req USING "<<<&.&&",
" FECHA INICIO: ", capac.fecha_ini USING "dd/mm/yyyy"
ELSE
LET det2 = "HORAS TOMADAS: ", capac.horas_tom USING "<<<&.&&",
" DEL ", capac.fecha_ini USING "dd/mm/yyyy",
" AL ", capac.fecha_fin USING "dd/mm/yyyy"
END IF
LET det3 = "INSTITUCION/FACILITADOR: ", capac.institucion CLIPPED,
" COSTO: ", capac.costo USING "<<<,<<&.&&"
END IF
IF es_desvinculacion(xtipo) THEN
LET es_vac = 0
LET xnom_det = NULL
LET cap_sql = "SELECT desc_causa FROM adtb00061 WHERE cod_causa = ?"
PREPARE p_imp_desv FROM cap_sql
EXECUTE p_imp_desv INTO xnom_det USING desv.cod_causa
LET det_tit = "DESVINCULACION"
LET det1 = "FECHA DE SALIDA: ", desv.fecha_salida USING "dd/mm/yyyy",
" CAUSA: ", xnom_det CLIPPED, " (", clase_causa(desv.cod_causa) CLIPPED, ")"
LET det2 = "RECONTRATABLE: ", desv.recontratable
LET det3 = "DETALLE: ", desv.detalle CLIPPED
END IF
PRINTX acc_per.num_trx,mov_emp.desc_mto,
acc_per.fecha ,acc_per.fech_efec,apellido9,nombre9 ,
direccion,dias2,
@@ -2107,5 +2804,6 @@ ON EVERY ROW
nombre_dpto,
acc_per.cod_mto ,
mov_emp.desc_mto,
acc_per.observacion,vacacion.*,p_companias.nombre,hoy,descrip3,descrip4,descrip5
acc_per.observacion,vacacion.*,p_companias.nombre,hoy,descrip3,descrip4,descrip5,
es_vac,det_tit,det1,det2,det3
END REPORT