OPTIONS SHORT CIRCUIT IMPORT com IMPORT util SCHEMA smarmotech DEFINE url, token STRING DEFINE http_req com.HTTPRequest DEFINE http_resp com.HTTPResponse DEFINE json_response STRING DEFINE usuario, clave STRING DEFINE pcompanias RECORD LIKE companias.* DEFINE arr_RESPONSE RECORD count INTEGER, next STRING, previous STRING, msg STRING, code INTEGER, data DYNAMIC ARRAY OF RECORD emp_code STRING, first_name STRING, last_name STRING, nick_name STRING, gender STRING, dept_name STRING, dept_code INT, position_code INT, position_name STRING, att_date STRING, weekday STRING, timetable STRING, check_in STRING, check_out STRING, clock_in STRING, clock_out STRING, total_time STRING, total_worked STRING, normal_wt STRING, normal_ot STRING, weekend_ot STRING, holiday_ot STRING, dayoff_ot STRING, ot_lv1 STRING, ot_lv2 STRING, ot_lv3 STRING END RECORD END RECORD DEFINE arr_novedad DYNAMIC ARRAY OF RECORD num_nomi LIKE notb00007.num_nomi, tipo_emp LIKE notb00007.tipo_emp, num_emp LIKE notb00007.num_emp, departamento LIKE notb00007.departamento, departamento_afecta INT, nivel_emp LIKE notb00007.nivel_emp, cod_puesto LIKE notb00007.cod_puesto, cod_mov LIKE notb00007.cod_mov, cantidad LIKE notb00007.cantidad, valor LIKE notb00007.valor, us_crea LIKE notb00007.us_crea, fech_crea LIKE notb00007.fech_crea END RECORD DEFINE table_data DYNAMIC ARRAY OF RECORD emp_code STRING, first_name STRING, dept_code INT, att_date DATE, timetable STRING, check_in STRING, clock_in STRING, check_out STRING, clock_out STRING, normal_ot STRING, weekend_ot STRING, holiday_ot STRING, dayoff_ot STRING, ot_lv1 STRING END RECORD DEFINE i, num_nomi INT DEFINE MirrorData DYNAMIC ARRAY OF RECORD emp_code STRING, first_name STRING, dept_code INT, normal_ot INTERVAL HOUR TO SECOND, weekend_ot INTERVAL HOUR TO SECOND, holiday_ot INTERVAL HOUR TO SECOND, dayoff_ot INTERVAL HOUR TO SECOND, ot_lv1 INTERVAL HOUR TO SECOND, ot_lvl2 INTERVAL HOUR TO SECOND, ot_lvl3 INTERVAL HOUR TO SECOND END RECORD DEFINE pfecha, fecha1 DATE, sqldate STRING DEFINE empleados_desactivados DYNAMIC ARRAY OF RECORD emp_code INT, num_emp INT, nom1_emp STRING, apell1_emp STRING, departamento STRING END RECORD DEFINE handler om .SaxDocumentHandler, -- return value from fgl_report_commitCurrentSettings() r_filename STRING, -- filename of Report Design Document including .4rp extension r_output STRING, -- output format option preview INTEGER -- TRUE/FALSE, to set preview option MAIN CALL ARG_VAL(1) RETURNING usuario CALL ARG_VAL(2) RETURNING clave CONNECT TO "smarmotech" USER usuario USING clave SELECT * INTO pcompanias.* FROM companias CALL BioTimeForm() END MAIN FUNCTION BioTimeFORM() OPEN WINDOW w1 WITH FORM "OverTimeFORM" CALL data() DIALOG ATTRIBUTE(UNBUFFERED) DISPLAY ARRAY table_data TO dis_record.* ON ACTION Procesar ATTRIBUTES(TEXT = "Procesar H.E.", IMAGE = "calc") LET r_filename ="HorasExtrasRP.4rp" IF fgl_report_loadCurrentSettings(r_filename) THEN LET preview = 1 CALL seleccionarsalida() RETURNING r_output -- load the .4rp file CALL fgl_report_selectDevice(r_output) -- changing default CALL fgl_report_selectPreview(preview) -- changing default LET handler = fgl_report_commitCurrentSettings() -- commit changes END IF START REPORT reporteHoras_rpt TO XML HANDLER HANDLER CALL ProcesarHorasExtras(1) FINISH REPORT reporteHoras_rpt CALL msg(1) ON ACTION getData ATTRIBUTES(TEXT = 'Refrescar data', IMAGE = "refresh") CALL getDATA_from_BIOTIME() CALL table_data.clear() CALL data() CALL msg(13) ON ACTION Salir ATTRIBUTES(TEXT = "Salir", IMAGE = "exit") EXIT DIALOG END DISPLAY DISPLAY ARRAY empleados_desactivados TO d_employees.* ON ACTION desactivar ATTRIBUTES(TEXT = "Limpiar empleados", IMAGE = "Delete") CALL delete_employees() END DISPLAY END DIALOG CLOSE WINDOW w1 END FUNCTION FUNCTION delete_employees() DEFINE metodo STRING, i, j INT DEFINE response RECORD count INTEGER, next STRING, previous STRING, msg STRING, code INTEGER, data RECORD id INTEGER END RECORD END RECORD DISPLAY "START" LET i = 1 WHILE i <= empleados_desactivados.getLength() LET url = "http://192.168.100.11:8088/personnel/api/employees/", empleados_desactivados[i].emp_code LET token = "Token e9f166bbf49c2c7a34ad89b30b6db9303327aa75" LET metodo = 'DELETE' LET http_req = com.HTTPRequest.Create(url) CALL http_req.setConnectionTimeout(10) CALL http_req.setCharset("UTF-8") CALL http_req.setHeader("Authorization", token) CALL http_req.setHeader("Content-Type", "application/json") CALL http_req.setHeader("accept", "application/json") TRY CALL http_req.setMethod(metodo) CALL http_req.doRequest() LET http_resp = http_req.getResponse() IF http_resp.getStatusCode() != 200 THEN #CALL show_sync_err(http_resp.getStatusDescription()) DISPLAY "Something's off..." ELSE LET json_response = http_resp.getTextResponse() CALL util.JSON.parse(json_response, response) DISPLAY response.data.id END IF CATCH DISPLAY SFMT("HTTP request error: STATUS=%1 (%2)", STATUS, SQLCA.SQLERRM) END TRY LET i = i + 1 END WHILE END FUNCTION FUNCTION ProcesarHorasExtras(HEvalor) DEFINE j, HEvalor, cod_mov INT, sueldo_ac DECIMAL(12, 2), Horas35, Horas100, Horas DECIMAL, salario_diario, salario_hora, factor DECIMAL(12, 2), pfecha, fecha1 DATE, HorasExtras INTERVAL HOUR TO FRACTION, SplittedHours DYNAMIC ARRAY OF INT, ArmarHora STRING, actualHours DECIMAL(12,2), query, empleado, depto_nom STRING DEFINE tok base.StringTokenizer CALL mirrorData.clear() LET horas35 = 35.00 LET horas100 = 100.00 CASE HEvalor WHEN 1 --HORAS EXTRAS NORMALES LET query = "SELECT emp_code, first_name, dept_code, CAST(nor_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((nor_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(nor_s%60 AS VARCHAR),2) AS normal_ot, CAST(wkd_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((wkd_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(wkd_s%60 AS VARCHAR),2) AS weekend_ot, CAST(hol_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((hol_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(hol_s%60 AS VARCHAR),2) AS holiday_ot, CAST(dof_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((dof_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(dof_s%60 AS VARCHAR),2) AS dayoff_ot, CAST(lv1_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((lv1_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(lv1_s%60 AS VARCHAR),2) AS ot_lv1, CAST(lv2_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((lv2_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(lv2_s%60 AS VARCHAR),2) AS ot_lv2, CAST(lv3_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((lv3_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(lv3_s%60 AS VARCHAR),2) AS ot_lv3 FROM ( SELECT emp_code, first_name, dept_code, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(normal_ot AS TIME))) AS nor_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(weekend_ot AS TIME))) AS wkd_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(holiday_ot AS TIME))) AS hol_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(dayoff_ot AS TIME))) AS dof_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(ot_lv1 AS TIME))) AS lv1_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(ot_lv2 AS TIME))) AS lv2_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(ot_lv3 AS TIME))) AS lv3_s FROM BioTimeData.dbo.EmployeeAttendance WHERE normal_ot IS NOT NULL AND TRY_CAST(normal_ot AS TIME) IS NOT NULL GROUP BY emp_code, first_name, dept_code HAVING SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(normal_ot AS TIME))) >= 3600 ) CD" WHEN 2 --HORAS EXTRAS DIA LIBRE (DOMINGO) LET query = "SELECT emp_code, first_name, dept_code, CAST(nor_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((nor_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(nor_s%60 AS VARCHAR),2) AS normal_ot, CAST(wkd_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((wkd_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(wkd_s%60 AS VARCHAR),2) AS weekend_ot, CAST(hol_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((hol_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(hol_s%60 AS VARCHAR),2) AS holiday_ot, CAST(dof_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((dof_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(dof_s%60 AS VARCHAR),2) AS dayoff_ot, CAST(lv1_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((lv1_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(lv1_s%60 AS VARCHAR),2) AS ot_lv1, CAST(lv2_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((lv2_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(lv2_s%60 AS VARCHAR),2) AS ot_lv2, CAST(lv3_s/3600 AS VARCHAR)+':'+RIGHT('0'+CAST((lv3_s%3600)/60 AS VARCHAR),2)+':'+RIGHT('0'+CAST(lv3_s%60 AS VARCHAR),2) AS ot_lv3 FROM ( SELECT emp_code, first_name, dept_code, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(normal_ot AS TIME))) AS nor_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(weekend_ot AS TIME))) AS wkd_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(holiday_ot AS TIME))) AS hol_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(dayoff_ot AS TIME))) AS dof_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(ot_lv1 AS TIME))) AS lv1_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(ot_lv2 AS TIME))) AS lv2_s, SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(ot_lv3 AS TIME))) AS lv3_s FROM BioTimeData.dbo.EmployeeAttendance WHERE normal_ot IS NOT NULL AND TRY_CAST(normal_ot AS TIME) IS NOT NULL GROUP BY emp_code, first_name, dept_code HAVING SUM(DATEDIFF(SECOND, '00:00:00', TRY_CAST(dayoff_ot AS TIME))) >= 3600 ) CD" END CASE DECLARE buscar CURSOR FROM query LET i = 1 FOREACH buscar INTO MirrorData[i].* LET i = i + 1 END FOREACH IF HEvalor = 1 THEN LET Horas = Horas35 LET cod_mov = 3 ELSE LET Horas = Horas100 LET cod_mov = 2 END IF PREPARE query FROM "select top 1 num_nomi from notb00010 where fecha_cierre_nomina < getdate() and status_t is null order by fecha_cierre_nomina desc" EXECUTE query INTO num_nomi DISPLAY "NOMINA :", num_nomi PREPARE query FROM "DELETE FROM notb00007 WHERE num_nomi = ? AND cod_mov = ?" EXECUTE query USING num_nomi, cod_mov LET i = 1 WHILE i < MirrorData.getlength() LET salario_diario = 0 LET salario_hora = 0 LET factor = 0 CALL arr_novedad.clear() INITIALIZE tok, SplittedHours TO NULL LET arr_novedad[i].num_emp = MirrorData[i].emp_code DISPLAY "emp_code: ", arr_novedad[i].num_emp PREPARE buscarFicha FROM 'SELECT payroll_num FROM zkbiotime.dbo.personnel_employee WHERE emp_code = ?' EXECUTE buscarFicha USING arr_novedad[i].num_emp INTO arr_novedad[i].num_emp DISPLAY "num_emp: ", arr_novedad[i].num_emp PREPARE buscar2 FROM 'SELECT sueldo_ac, departamento, nivel_emp, cod_puesto, nomina FROM marmotech.dbo.adtb00003 WHERE num_emp = ? and status_t is null' EXECUTE buscar2 USING arr_novedad[i].num_emp INTO sueldo_ac, arr_novedad[i].departamento, arr_novedad[i].nivel_emp, arr_novedad[i].cod_puesto, arr_novedad[i].tipo_emp LET arr_novedad[i].departamento_afecta = arr_novedad[i].departamento LET arr_novedad[i].num_nomi = num_nomi IF HEvalor = 1 THEN LET HorasExtras = MirrorData[i].normal_ot ELSE LET HorasExtras = MirrorData[i].dayoff_ot END IF DISPLAY "Horas extras: ", horasExtras LET tok = base.StringTokenizer.create(HorasExtras, ":") LET j = 1 WHILE tok.hasMoreTokens() LET SplittedHours[j] = tok.nextToken().trim() CLIPPED DISPLAY "Actual hours ", j, ": ", SplittedHours[j] LET j = j + 1 END WHILE LET armarHora = SplittedHours[1] || "." || SplittedHours[2] DISPLAY armarHora LET ActualHours = armarHora DISPLAY ActualHours LET salario_diario = sueldo_ac / 23.83 -- DISPLAY "Salario diario: ",salario_diario LET factor = (Horas/ 100) + 1 LET salario_hora = (salario_diario / 8) * factor --DISPLAY "Salario hora: ",salario_hora LET arr_novedad[i].valor = salario_hora * ActualHours LET arr_novedad[i].cantidad = ActualHours LET arr_novedad[i].cod_mov = cod_mov LET arr_novedad[i].us_crea = usuario LET arr_novedad[i].fech_crea = CURRENT YEAR TO FRACTION PREPARE insertar FROM 'INSERT INTO notb00007 (num_nomi, tipo_emp, num_emp, departamento, departamento_afecta, nivel_emp, cod_puesto, cod_mov, cantidad, valor, us_crea, fech_crea) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)' EXECUTE insertar USING arr_novedad[i].* SELECT CONCAT(rtrim(nom1_emp),' ',rtrim(apell1_emp)) INTO empleado FROM adtb00003 WHERE num_emp = arr_novedad[i].num_emp SELECT nom_dpto INTO depto_nom FROM adtb00001 WHERE departamento = arr_novedad[i].departamento LET empleado = "("CLIPPED||arr_novedad[i].num_emp CLIPPED||") "|| empleado CLIPPED LET depto_nom = "("CLIPPED||arr_novedad[i].departamento CLIPPED||") "|| depto_nom CLIPPED DISPLAY "DEPARTAMENTO: ", depto_nom OUTPUT TO REPORT reporteHoras_rpt(arr_novedad[i].*, empleado, depto_nom) DISPLAY "SUCCESS" DISPLAY " " DISPLAY "----------------------------------------------------------" DISPLAY " " LET i = i + 1 END WHILE IF HEvalor != 2 THEN CALL ProcesarHorasExtras(2) ELSE DISPLAY "FINISHED" END IF END FUNCTION FUNCTION data() DEFINE i INT DEFINE query STRING LET query = "SELECT emp_code, first_name,dept_code, att_date, timetable, check_in, clock_in, check_out, clock_out, normal_ot, weekend_ot, holiday_ot, dayoff_ot, ot_lv1 FROM BioTimeData.dbo.EmployeeAttendance" DECLARE buscar1 CURSOR FROM query LET i = 1 FOREACH buscar1 INTO table_data[i].emp_code, table_data[i].first_name, table_data[i].dept_code, table_data[i].att_date, table_data[i].timetable, table_data[i].check_in, table_data[i].clock_in, table_data[i].check_out, table_data[i].clock_out, table_data[i].normal_ot, table_data[i].weekend_ot, table_data[i].holiday_ot, table_data[i].dayoff_ot, table_data[i].ot_lv1 LET i = i + 1 END FOREACH DECLARE find_unactive_employees CURSOR FROM "select distinct b.emp_code, a.num_emp, a.nom1_emp, a.apell1_emp,c.nom_dpto from marmotech.dbo.adtb00003 a inner join zkbiotime.dbo.personnel_employee b on a.num_emp = b.payroll_num inner join BioTimeData.dbo.employeeattendance d on b.emp_code = d.emp_code left join marmotech.dbo.adtb00001 c on a.departamento = c.departamento where a.status_t is not null" LET i = 1 FOREACH find_unactive_employees INTO empleados_desactivados[i].* LET i = i + 1 END FOREACH END FUNCTION FUNCTION getDATA_from_BIOTIME() DEFINE metodo STRING, i, j INT DEFINE entrada, salida, query STRING DEFINE response RECORD count INTEGER, next STRING, previous STRING, msg STRING, code INTEGER, data DYNAMIC ARRAY OF RECORD id INTEGER, dept_code STRING, dept_name STRING, parent_dept STRING END RECORD END RECORD DISPLAY "START" #Primero obtenemos todos los ID de los departamentos en BIOTIME LET url = "http://192.168.100.11:8088/personnel/api/departments/?page=1&page_size=1000" LET token = "Token e9f166bbf49c2c7a34ad89b30b6db9303327aa75" LET metodo = 'GET' LET http_req = com.HTTPRequest.Create(url) CALL http_req.setConnectionTimeout(10) CALL http_req.setCharset("UTF-8") CALL http_req.setHeader("Authorization", token) CALL http_req.setHeader("Content-Type", "application/json") CALL http_req.setHeader("accept", "application/json") TRY CALL http_req.setMethod(metodo) CALL http_req.doRequest() LET http_resp = http_req.getResponse() IF http_resp.getStatusCode() != 200 THEN CALL show_sync_err(http_resp.getStatusDescription()) ELSE LET json_response = http_resp.getTextResponse() CALL util.JSON.parse(json_response, response) #DISPLAY "Departamentos:", json_Response END IF CATCH DISPLAY SFMT("HTTP request error: STATUS=%1 (%2)", STATUS, SQLCA.SQLERRM) END TRY #Obtenemos las fechas de cierre correspondientes { LET sqldate = TODAY USING "yyyy-mm-dd" DISPLAY sqldate} PREPARE query2 FROM "select top 1 num_nomi from notb00010 where fecha_cierre_nomina < getdate() and status_t is null order by fecha_cierre_nomina desc" EXECUTE query2 INTO num_nomi DISPLAY "NOMINA :", num_nomi LET num_nomi = num_nomi - 1 PREPARE query3 FROM "SELECT DATEADD(day, 1, MAX(a.fecha_cierre_nomina)) FROM notb00010 a WHERE a.num_nomi = ?" EXECUTE query3 INTO pfecha USING num_nomi DISPLAY pfecha IF pfecha IS NULL THEN CALL fgl_Winmessage("ERROR", "NO EXISTE FECHA CIERRE NOMINA", "INFO") EXIT PROGRAM END IF LET num_nomi = num_nomi + 1 SELECT MIN(a.fecha_cierre_nomina) INTO fecha1 FROM notb00010 a WHERE a.num_nomi = num_nomi DISPLAY fecha1 #Las volvemos string con el formato correspondiente para la url de la API LET entrada = pfecha USING "yyyy-mm-dd" LET salida = fecha1 USING "yyyy-mm-dd" DISPLAY entrada,"--",salida DISPLAY "Busqueda de departamentos y fechas de cierre obtenidas" PREPARE limpiar_data FROM 'delete from BioTimeData.dbo.employeeattendance' EXECUTE limpiar_data LET i = 1 WHILE i <= response.data.getLength() LET url = "http://192.168.100.11:8088/att/api/overtimeReport/?page=1&page_size=200&start_date=", entrada, "&end_date=", salida, "&departments=", response.data[i].id #Creamos nuevamente el request para la api LET http_req = com.HTTPRequest.Create(url) CALL http_req.setConnectionTimeout(10) CALL http_req.setCharset("UTF-8") CALL http_req.setHeader("Authorization", token) CALL http_req.setHeader("Content-Type", "application/json") CALL http_req.setHeader("accept", "application/json") DISPLAY url TRY CALL http_req.setMethod(metodo) CALL http_req.doRequest() LET http_resp = http_req.getResponse() IF http_resp.getStatusCode() != 200 THEN CALL show_sync_err(http_resp.getStatusDescription()) ELSE LET json_response = http_resp.getTextResponse() #DISPLAY "respuesta: ",json_response CALL util.JSON.parse(json_response, arr_RESPONSE) #DISPLAY arr_RESPONSE.data[1].* END IF CATCH DISPLAY SFMT("HTTP request error: STATUS=%1 (%2)", STATUS, SQLCA.SQLERRM) END TRY LET j = 1 #Insertamos la data en SQL SERVER WHILE j <= arr_response.data.getLength() LET query = "INSERT INTO BioTimeData.dbo.employeeattendance values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" PREPARE accion FROM query DISPLAY arr_response.data[j].* EXECUTE accion USING arr_response.data[j].* LET j = j + 1 END WHILE DISPLAY "SUCCESS #", i LET i = i + 1 END WHILE DISPLAY "FINISHED" END FUNCTION REPORT reporteHoras_rpt(x,z,y) DEFINE x RECORD num_nomi LIKE notb00007.num_nomi, tipo_emp LIKE notb00007.tipo_emp, num_emp LIKE notb00007.num_emp, departamento LIKE notb00007.departamento, departamento_afecta INT, nivel_emp LIKE notb00007.nivel_emp, cod_puesto LIKE notb00007.cod_puesto, cod_mov LIKE notb00007.cod_mov, cantidad LIKE notb00007.cantidad, valor LIKE notb00007.valor, us_crea LIKE notb00007.us_crea, fech_crea LIKE notb00007.fech_crea END RECORD, fecha_reporte CHAR(30), fecha CHAR(30), movimiento VARCHAR(100) DEFINE z VARCHAR(100) DEFINE y VARCHAR(100) DEFINE total_horas, total_valor_horas DECIMAL(12,2) ORDER BY x.cod_mov DESC, y ASC FORMAT BEFORE GROUP OF x.departamento SELECT descrip_mov INTO movimiento FROM notb00002 WHERE cod_mov = x.cod_mov AND status_t IS NULL LET movimiento = "("CLIPPED ||x.cod_mov CLIPPED||")"|| movimiento PRINTX movimiento, x.num_nomi, y PREPARE query4 FROM "select top 1 num_nomi from notb00010 where fecha_cierre_nomina < getdate() and status_t is null order by fecha_cierre_nomina desc" EXECUTE query4 INTO num_nomi DISPLAY "NOMINA :", num_nomi LET num_nomi = num_nomi - 1 PREPARE query5 FROM "SELECT DATEADD(day, 1, MAX(a.fecha_cierre_nomina)) FROM notb00010 a WHERE a.num_nomi = ?" EXECUTE query5 INTO pfecha USING num_nomi DISPLAY pfecha LET num_nomi = num_nomi + 1 SELECT MIN(a.fecha_cierre_nomina) INTO fecha1 FROM notb00010 a WHERE a.num_nomi = num_nomi ON EVERY ROW LET fecha_reporte = TODAY USING "mm/dd/yyyy" LET fecha = pfecha USING "mm/dd/yyyy",' -- ',fecha1 USING "mm/dd/yyyy" DISPLAY pcompanias.nombre PRINTX fecha, fecha_reporte, pcompanias.nombre, z, x.cantidad, x.valor ON LAST ROW LET total_horas = SUM(x.cantidad) LET total_valor_horas = SUM(x.valor) PRINTX total_horas, total_valor_horas END REPORT FUNCTION msg(numero_msg) DEFINE numero_msg SMALLINT DEFINE descripcion CHAR (60) SELECT desc_msg INTO descripcion FROM msgtable WHERE cod_msg = numero_msg IF status = NOTFOUND THEN SELECT desc_msg INTO descripcion FROM msgtable WHERE cod_msg = 22 LET descripcion = descripcion CLIPPED,numero_msg using "<<<<" ERROR descripcion ATTRIBUTE(BOLD) ELSE ERROR descripcion ATTRIBUTE(BOLD) LET numero_msg = 0 END IF END FUNCTION