Modulo de Asistencia y Marcaciones (Horas Extras)

Obtiene descarga boleta de pago (3) - [getDownloadBoletaPago]

🧾 Descripción

Valida si un empleado debe descargar su boleta de pago del mes anterior antes de poder registrar marcaciones o realizar solicitudes en el sistema.
La validación se aplica únicamente dentro de un periodo permitido (del día 1 al 3 del mes).

Este servicio combina datos entre:

Permite determinar si el usuario:


🚀 Endpoint

POST /get-download-boleta-pago

📥 Parámetros

Campo Tipo Requerido Descripción
empleado string ID del empleado (Employee.name)

🔐 Seguridad

El servicio requiere:


🧠 Flujo del Servicio (resumen real)

1️⃣ Verifica si está dentro del rango permitido

2️⃣ Obtiene datos del empleado

Consulta: 

GET tabEmployee fields = ["fecha_de_ingreso_real", "status"]

Si el empleado está PreActivo, no se valida boleta.

3️⃣ Determina el mes anterior

Se calcula:

Se verifica que el empleado haya ingresado antes del fin del mes anterior.

4️⃣ Verifica si existe boleta del mes anterior

Consulta a ERP: 

tabSalary Slip WHERE employee = empleado AND posting_date BETWEEN primer_día_mes_pasado AND último_día_mes_pasado

Si no tiene boleta, no se valida nada.

5️⃣ Valida si el mes está habilitado para descarga

Consulta: 

tabEstado Boleta Mensual WHERE mes = <mes anterior en texto> AND año = <año> AND habilitado = 1

6️⃣ Consulta si el usuario ya descargó la boleta

Busca en MySQL: 

historial_procesos_app WHERE empleado = empleado AND proceso = 'NOMINA' AND month = mes AND year = año

Si no existe descarga previa y el mes está habilitado → debe descargar.


📤 Respuestas Posibles

✔️ 1. No está en rango de validación

{ "status": true, "msn": "No está dentro del rango de fecha de validación" }

✔️ 2. Empleado PreActivo

{ "status": true, "msn": "No validar descarga de boleta en PreActivo" }

✔️ 3. No tiene boleta del mes

{ "status": true, "msn": "No tiene boleta de pago por lo tanto no se valida" }

❌ 4. Debe descargar la boleta (regla principal)

{ "status": false, "msn": "Para poder registrar su marcación o realizar alguna solicitud, descargar su boleta pendiente del mes" }

✔️ 5. Ya descargó la boleta

{ "status": true, "msn": "Se ha descargado la boleta de pago" }

✔️ 6. Error controlado

{ "status": true, "msn": "Se ha descargado el contrato de trabajo" }


📚 Tablas y esquemas usados

🔹 Employee (ERP)

Campos utilizados:

fecha_de_ingreso_real status

🔹 Salary Slip (ERP)

Campo utilizado: posting_date

🔹 Estado Boleta Mensual (ERP)

Campos utilizados:

mes año habilitado

🔹 historial_procesos_app (MySQL)

Campos usados:

empleado proceso month year

🗃 Lógica en pseudocódigo

if dia > 3: return OK empleado = GET Employee[name] if empleado.status == PreActivo: return OK fecha_ingreso < fin_mes_anterior ? if no tiene SalarySlip en mes anterior: return OK mes_habilitado = GET EstadoBoletaMensual[mes,año] descarga = buscar en historial_procesos_app if mes_habilitado AND no descarga: return OBLIGAR DESCARGA return OK

Obtiene descarga Renovación de contrato (3) - [getRenovacionContrato]

🧾 Descripción

Valida si un empleado debe descargar la renovación de contrato antes de poder registrar marcaciones o realizar solicitudes dentro del aplicativo.

El servicio evalúa:

Este servicio actúa como una regla de negocio obligatoria para habilitar o bloquear el uso del aplicativo.


🚀 Endpoint

POST /get-renovacion-contrato

📌 Recibe un único parámetro:

{ "empleado": "EMP-0001" }

🔐 Seguridad


🧠 Flujo del Servicio (Resumen Real)

1️⃣ Validación inicial por fecha

{ "status": true, "msn": "No es el día correcto para la renovación de contrato" }

2️⃣ Obtener fecha real de ingreso del empleado

Consulta al ERP:

SELECT fecha_de_ingreso_real FROM `tabEmployee` WHERE name = <empleado>

Si no existe → el servicio simplemente finaliza sin error.


3️⃣ Determinar si el empleado ya debería tener renovación


4️⃣ Consultar renovación en ERP (contratos validados)

Busca registros de:

Consulta ejecutada:

SELECT doc.name FROM `tabSolicitud de Renovaciones` doc LEFT JOIN `tabTrabajadores pendiete de renovar` tab ON doc.name = tab.parent WHERE doc.data_12 = <mes_actual_texto> AND doc.año = <year> AND tab.codigo = <empleado> AND tab.renueva = 'Si' AND doc.estado_de_documento = 'Validado'

5️⃣ Validar si el empleado YA descargó la renovación

Consulta en base de datos interna:

historial_procesos_app WHERE proceso = 'descargaContratoRenovacion' AND empleado = <empleado>
{ "status": false, "msn": "Para poder registrar su marcación o realizar alguna solicitud, descargar su renovación de contrato" }

6️⃣ Si todo está correcto

Retorna éxito:

{ "status": true, "msn": "Se ha descargado el contrato de trabajo" }

📥 Request Body

{ "empleado": "EMP-0001" }

📤 Response 200 – Ejemplos

✔ Caso correcto (ya descargó renovación)

{ "status": true, "msn": "Se ha descargado el contrato de trabajo" }

❌ Debe descargar renovación antes de usar el app

{ "status": false, "msn": "Para poder registrar su marcación o realizar alguna solicitud, descargar su renovación de contrato" }

✔ Aún no es día válido

{ "status": true, "msn": "No es el día correcto para la renovación de contrato" }

❗ Posibles Errores

Error Respuesta
Día inválido para la operación "No es el día correcto para la renovación de contrato"
Empleado sin renovación validada "Para poder registrar su marcación..."
Error inesperado en ejecución Se devuelve mensaje genérico, pero siempre con status: true
No existe el empleado El flujo simplemente finaliza sin error explícito

📚 Consultas y estructuras usadas

✔ ERP — Employee

Campos consultados:

{ "fecha_de_ingreso_real": "date" }

✔ ERP — Solicitud de Renovaciones

Consulta combinada mediante JOIN:

✔ Base interna MySQL (mysql2)

Tabla: historial_procesos_app

Campo crítico: proceso = 'descargaContratoRenovacion'


🗃 Lógica en Pseudo-código

if (dia_actual < 26) return "No es el día correcto" empleado = GET fecha_ingreso_real FROM Employee if fecha_ingreso < ultimo_dia_mes_anterior: renovacion = GET renovacion_validada FROM SolicitudRenovaciones if renovacion existe: descarga = buscar en historial_procesos_app if no hay descarga: return "Debe descargar renovación" return "OK"

Horas Extras del Mes (1) - [getMarkingsForEmployeePerMonth2]

🧾 Descripción

Obtiene y calcula todas las horas extras registradas para un empleado en un mes específico, detallando:

El servicio consulta información desde varios recursos del ERP:


🚀 Endpoint

POST /get-markings-employee-month

📥 Parámetros en el body

{ "employee": "EMP-0001", "month": "02", "year": "2025" }

🔐 Seguridad


🧠 Flujo del Servicio (resumen real)

1️⃣ Obtiene el corte mensual

Consulta el recurso:

GET /resource/Cortes filters: año = year, mes = month

Si no existe corte → retorna error "No hay corte mensual para este mes".


2️⃣ Obtiene las horas extras acumuladas del mes

GET /resource/Horas Extras fields: ["hhee_al_25","hhee_al_35","hhee_al_100"] filters: año, mes, empleado

3️⃣ Obtiene las marcaciones dentro del periodo del corte

GET /resource/Marcaciones filters: user_id = employee date BETWEEN corte.inicio AND corte.fin hours != 0

Si no hay marcaciones → retorna mensaje informativo.


4️⃣ Carga feriados desde archivo local

public/recursos_humanos/holidays.json

Feriados + domingos se consideran jornada al 100%.


5️⃣ Procesa cada marcación

Por cada registro:

Cada día se estructura como:

{ "fecha": "05 DE ENERO", "porcentaje": "35%", "horas_completadas": "3H" }

6️⃣ Arma la respuesta final:

Incluye:


📤 Response 200 – Ejemplo

{ "valor": true, "msn": "Lista de horas extras generado correctamente", "data": { "marcaciones": [ { "fecha": "03 DE ENERO", "porcentaje": "25%", "horas_completadas": "2H" }, { "fecha": "03 DE ENERO", "porcentaje": "35%", "horas_completadas": "1H" } ], "horas25": "12", "horas35": "4", "horas100": "2", "horas_acumuladas": "15" } }

❗ Posibles Errores

1. Corte mensual no configurado

{ "valor": false, "msn": "No hay corte mensual para este mes", "data": [] }

2. Error al traer horas extras

{ "valor": false, "msn": "Surgió un error, al obtener las horas extras", "data": [] }

3. Marcaciones vacías

{ "valor": false, "msn": "No hay horas extras registradas para este mes", "data": { "marcaciones": [], "horas25": "0", "horas35": "0", "horas100": "0", "horas_acumuladas": "0" } }

4. Error en servicio del ERP

{ "valor": false, "msn": "Surgió un error, al obtener las marcaciones.", "data": [] }

📚 Schemas utilizados

Cortes

{ "dia_inicio": "2025-01-01", "dia_final": "2025-01-31" }

Horas Extras

{ "hhee_al_25": "10", "hhee_al_35": "5", "hhee_al_100": "2" }

Marcaciones

{ "fecha": "2025-01-03", "horas": 3 }


🗃 Lógica en pseudo-código

corte = GET Cortes where año=year and mes=month if corte empty → return error hours = GET Horas Extras where año, mes, empleado markings = GET Marcaciones where user_id=employee and date between corte feriados = cargar holidays.json foreach marking: if fecha in feriados → 100% else if horas <= 2 → 25% else: agregar 2h al 25% agregar horas-2 al 35% sumar horas acumuladas return { marcaciones procesadas, horas25, horas35, horas100, horas_acumuladas }