Modulo de Asistencia y Marcaciones (Marcaciones)
- Obtiene descarga boleta de pago (1,2,3,4,5,6,7,8) - [getDownloadBoletaPago]
- Obtiene descarga Renovación de contrato (1,2,3,4,5,6,7,8) - [getRenovacionContrato]
- Consulta si existe documento del puesto (1, 2,3) - [getDocumentPuesto]
- Verifica los documentos descargados (1, 2) - [verifyDownloadedDocuments]
- Lista de marcaciones generada (1) - [listMarkingsApp45]
- Obtener Usuario (3) - [getUser3]
- Lista de Sucursales - [listOfErpBranchs]
- Intento de Marcación (1) - [intentMarca]
- Validar Marcación (1) - [validar]
- Crear Marcación (1) - [crear]
Obtiene descarga boleta de pago (1,2,3,4,5,6,7,8) - [getDownloadBoletaPago]
🧾 Descripción General
Este servicio valida si un empleado debe descargar su boleta de pago (Salary Slip) correspondiente al mes anterior.
La validación depende:
-
Del día del mes actual
-
Del estado del empleado
-
De si existe o no una boleta generada
-
De si dicha boleta está habilitada
-
De si ya registró una descarga previa
La lógica se usa para bloquear marcaciones o solicitudes cuando un trabajador tiene una boleta pendiente por descargar.
🚀 Endpoint
Parámetro Path:
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| empleado | string | Sí | Código del empleado (Employee.name en ERPNext). |
🔐 Seguridad
No usa autenticación dentro de esta función, pero depende de endpoints internos ERPNext vía dbErp.
Se recomienda incluirlo dentro de rutas protegidas.
🧠 Flujo Lógico (Resumen Ejecutivo)
-
Validación de fechas
-
Si el día actual es mayor a 3, no se hace validación → se retorna éxito.
-
-
Consultar datos del empleado
-
Obtiene desde ERP:
-
fecha_de_ingreso_real -
status
-
-
-
Casos especiales por estado
-
Si el empleado está en PreActivo, no se valida.
-
-
Determinar si corresponde validar
-
Calcula el último día del mes anterior.
-
Si el ingreso del trabajador es posterior a ese mes → no se valida.
-
-
Validar si existe boleta generada
-
Consulta Salary Slip del mes anterior.
-
Si no existe boleta → no corresponde validar.
-
-
Validar si la boleta mensual está habilitada (Estado Boleta Mensual)
-
Revisa si está habilitada para ese mes.
-
-
Verificar si ya descargó boleta
-
Revisa tabla
historial_procesos_appen MySQL. -
Si no descargó → retorna mensaje de pendiente.
-
-
Caso final
-
Si todo está correcto → retorna éxito.
-
📥 Request
Sin body.
Solo recibe el parámetro {empleado} en la URL.
📤 Responses
✔️ 200 – No corresponde validación (día mayor a 3)
{
"status": true,
"msn": "No está dentro del rango de fecha de validación"
} |
✔️ 200 – Empleado en PreActivo
{
"status": true,
"msn": "No validar descarga de boleta en PreActivo"
} |
✔️ 200 – No corresponde validación (ingresó después)
{
"status": true,
"msn": "No tiene boleta de pago por lo tanto no se valida"
} |
❌ 200 – Boleta pendiente por descargar (validación negativa)
{
"status": false,
"msn": "Para poder registrar su marcación o realizar alguna solicitud, descargar su boleta pendiente del mes"
} |
✔️ 200 – Boleta descargada previamente
{
"status": true,
"msn": "Se ha descargado la boleta de pago"
} |
✔️ 200 – Error capturado (retorna como éxito)
Este mensaje parece incorrecto para el contexto (habla de contrato en vez de boleta), pero se documenta tal como el código lo retorna.
📚 Lógica de Consultas Usadas
1. Obtener datos del empleado
Consulta a ERP:
2. Validar Salary Slip del mes anterior
3. Validar estado de boleta (habilitado)
4. Validar si el empleado ya descargó su boleta
Tabla: historial_procesos_app (mysql2)
Filtro:
-
proceso = NOMINA
-
employee
-
month
-
year
🧩 Posibles Errores de Diseño (para tu control interno)
-
El
catchretorna mensaje incorrecto: “Se ha descargado el contrato de trabajo”. -
En validación final siempre retorna “status: true” aunque haya fallas.
-
Se usa
POSTen algunas consultas SQL cuando debería serGET.
(Solo informativo; no se incluye en documentación oficial si no lo deseas.)
Obtiene descarga Renovación de contrato (1,2,3,4,5,6,7,8) - [getRenovacionContrato]
🧾 Descripción
Valida si un trabajador tiene pendiente la descarga de su renovación de contrato, lo cual puede bloquear el registro de marcaciones o solicitudes dentro del aplicativo.
El servicio evalúa fechas, estado del trabajador y el registro interno en base MySQL donde se guarda el historial de descargas realizadas.
🚀 Endpoint
{empleado}corresponde al código del empleado (Employee.name en ERPNext).
🔐 Seguridad
-
Requiere que el cliente esté autenticado (según arquitectura de la app).
-
Accede a ERP (Frappe) mediante un servicio interno (
dbErp).
📥 Parámetros
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| empleado | string | Sí | Código único del empleado en ERPNext. |
📤 Responses
✔️ 200 – No corresponde validar renovación (fuera de fecha)
El proceso solo se ejecuta si día >= 26.
Si es antes, devuelve:
{
"status": true,
"msn": "No es el día correcto para la renovación de contrato"
} |
✔️ 200 – Validación NO necesaria (no aplica por antigüedad)
Si el empleado ingresó después del mes previo:
{
"status": true,
"msn": "Se ha descargado el contrato de trabajo"
} |
❌ 200 – Debe descargar el contrato de renovación (pendiente)
El empleado tiene renovación generada y habilitada, pero no tiene registro de descarga:
{
"status": false,
"msn": "Para poder registrar su marcación o realizar alguna solicitud, descargar su renovación de contrato"
} |
✔️ 200 – Renovación ya descargada
La base MySQL registra descarga previa:
{
"status": true,
"msn": "Se ha descargado el contrato de trabajo"
} |
✔️ 200 – Error controlado
Ante cualquier excepción:
{
"status": true,
"msn": "Se ha descargado el contrato de trabajo"
} |
🧩 Flujo del Servicio
-
Verifica el día actual
-
Si día < 26 → no corresponde validar
-
-
Obtiene datos del empleado desde ERP (
fecha_de_ingreso_real) -
Calcula:
-
Último día del mes anterior
-
Mes actual (texto)
-
-
Si el ingreso del empleado es anterior al último día del mes previo, aplica validación.
-
Consulta en ERP:
-
Solicitudes de renovación para este empleado
-
Con criterios:
-
Mes
-
Año
-
Código del empleado
-
renueva = "Si" -
documento validado
-
-
-
Si tiene renovación pendiente:
-
Consulta base MySQL2 → tabla
historial_procesos_app -
Busca registro del proceso
descargaContratoRenovacion -
Si no existe → debe descargar renovación
-
-
Si ya está registrado → permitir normal funcionamiento.
📚 Consultas utilizadas
A. Obtener datos del empleado
SELECT fecha_de_ingreso_real
FROM `tabEmployee`
WHERE name = {empleado} |
B. Consulta de renovaciones
C. Validación de descarga
🧪 Ejemplo de consumo (HTTP)
Request:
Response (pendiente):
Consulta si existe documento del puesto (1, 2,3) - [getDocumentPuesto]
🧾 Descripción
Permite obtener el documento MOF (Manual de Organización y Funciones) asociado a un puesto específico registrado en el ERP, consultando el Doctype Designation.
Este servicio se utiliza para mostrar o validar documentación laboral relacionada al cargo del trabajador.
🚀 Endpoint
También puede enviarse como parámetro directo según cómo se defina en routes:
🔐 Seguridad
-
El endpoint no exige autenticación explícita en el código.
-
Se recomienda protegerlo mediante API Token o Middleware según la arquitectura.
📥 Parámetros de Entrada
Query / Path Parameter
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| puesto | string | Sí | Nombre del Designation cuyo MOF se desea obtener. |
📤 Responses
✔️ 200 – Documento encontrado
-
datacontiene el valor del campomofdel Doctype Designation.
❌ 404 – Documento no encontrado
Se devuelve cuando el puesto no existe o no tiene MOF asociado.
🧠 Lógica Interna (Resumen)
-
Verifica que se haya enviado un nombre de puesto.
-
Construye una consulta GET hacia:
resource/DesignationCon:
-
filters:[["name","=", puesto]] -
fields:["mof"]
-
-
Envía la solicitud mediante:
ServiceErp("GET", null, body, APICAPACITACION."resource/Designation") -
Evalúa la respuesta:
-
Si encuentra registros → devuelve el
mof. -
Si no encuentra → error.
-
📚 Schema
Response
🧪 Ejemplo de Uso (curl)
Respuesta esperada:
Verifica los documentos descargados (1, 2) - [verifyDownloadedDocuments]
Descripción
Este servicio valida si un empleado ha completado la descarga obligatoria de documentos institucionales dentro del aplicativo.
Además, verifica si el empleado ha registrado previamente sus documentos de ingreso (elección de banco, declaración de AFP/ONP, etc.).
El proceso consulta tanto ERPNext como la base de datos MySQL2 para construir un resumen de los documentos descargados y determinar si el empleado tiene todos los documentos obligatorios descargados.
Parámetros
| Parámetro | Tipo | Descripción |
|---|---|---|
$employee |
string | Código del empleado (Employee.name) que se va a validar. |
Proceso general
-
Validación inicial de datos del empleado
-
Realiza una consulta a ERPNext para obtener los campos:
-
eleccion_banco -
afiliado_fondo_pensiones -
elección_fondo_pensiones
-
-
Si el empleado no existe, devuelve un error.
-
-
Validación de documentos de ingreso
-
Antes de validar documentos descargados, se comprueba que el empleado ya subió sus documentos de ingreso.
-
Si falta alguno de estos:
-
Elección de banco
-
Si está afiliado o no al fondo de pensiones
-
Selección AFP u ONP
→ Se retorna:
"Primero suba los documentos de ingreso" -
-
-
Obtención del historial de descargas
-
Consulta la tabla
historial_procesos_appen MySQL2. -
Se recuperan registros para los procesos:
-
descargaContratoTrabajo
-
descargaReglamentoInternoTrabajo
-
descargaRecomentacionesSST
-
descargaConvenioDescuento
-
descargaDeclaracionJuradaDomicilio
-
descargadeclaracionJuradaSNPSPP
-
descargaPoliticasSalariales
-
registroEPP
-
descargaPETSAlmacenamiento
-
descargaPETSManipulacion
-
descargaMOF
-
descargaPoliticasDescuentosPorDanios
-
-
-
Construcción del resumen por empleado
-
Cada documento es asignado como:
-
1→ descargado -
0→ pendiente
-
-
-
Validación del 100% de documentos
-
Si todos los procesos están registrados →
total_documentos = true -
Si falta alguno →
total_documentos = false
-
-
Validación adicional: Cambio de modalidad
-
Si el empleado tiene alguna "Solicitud de Cambio de Modalidad" aprobada (
docstatus != 2), se considera descargado automáticamente el contrato de trabajo.
-
-
Retorno final del estado del empleado
Respuesta exitosa
Posibles respuestas con error
● Empleado no encontrado
● Documentos de ingreso no completados
Lista de marcaciones generada (1) - [listMarkingsApp45]
🧾 Descripción
Este servicio obtiene y consolida todas las marcaciones de asistencia de un empleado en una fecha específica, combinando información de:
-
Employee Checkin (Entradas, salidas, refrigerios)
-
Attendance (Estado del día)
-
Cortes (Fechas especiales donde cambia el criterio de consulta)
-
Turnos del empleado (Shift Type)
Entrega una estructura lista para mostrar en una app móvil o web con:
-
Entrada
-
Salida a refrigerio
-
Retorno de refrigerio
-
Salida
-
Estado del día (Presente, Ausente, Teletrabajo, etc.)
-
Información del día: nombre, mes, fecha formateada.
El servicio también calcula dinámicamente si debe tomar estado_reporte o status, según si la fecha consultada pertenece al rango generado desde el último corte del mes.
🚀 Endpoint
POST /list-markings-app45
📥 Parámetros de Entrada (Request Body)
| Campo | Tipo | Descripción |
|---|---|---|
| usuario | string | Usuario que solicita información (no se usa en lógica interna). |
| empleado | string | ID del empleado a consultar. |
| cookie | string | Cookie de sesión para consultas al ERP. |
| date | string | Fecha de la marcación. |
🔐 Seguridad
-
dbErp() -
ServiceErp()
🧠 Flujo del Servicio (Resumen Real)
1️⃣ Obtiene filtros según fecha
-
Si la fecha es >= 2022-11-10, consulta por
fecha_consolidado. -
Si es menor, consulta por rango horario (00:00:00 – 23:59:59).
2️⃣ Trae las marcaciones del empleado
Consulta tabEmployee Checkin (Entrada, Refrigerio, Salida).
3️⃣ Consulta estado de asistencia
Desde tabAttendance, validando solo documentos aprobados (docstatus = 1).
4️⃣ Obtiene configuración de cortes del mes
Sirve para determinar si el estado válido es:
-
estado_reporte(cuando está dentro del rango posterior al corte), ó -
status(estado normal de Attendance)
5️⃣ Genera un rango de fechas desde el corte hasta fin de mes
Se usa para validar cambios de lógica.
6️⃣ Procesa marcaciones y las estructura así:
7️⃣ Traduce estados a texto legible
Ejemplo:
| ERP | Texto entregado |
|---|---|
| Present | Presente |
| Absent | Ausente |
| Work From Home | Trabajar desde casa |
| Half Day | Medio día |
📤 Response 200 – Ejemplo
❗ Posibles Errores
1. Error al obtener marcaciones
2. Error al consultar Attendance o Cortes
3. Error interno del servidor
{
"valor": false,
"msn": "Error en listMarkingsApp45: <mensaje>",
"error": "<stacktrace>"
} |
📚 Tablas / Recursos Usados
🔹 tabEmployee Checkin
Campos:
-
name
-
employee
-
employee_name
-
log_type
-
time
-
tardanza
-
salida_temprana
🔹 tabAttendance
-
status
-
estado_reporte
-
attendance_date
-
employee
🔹 tabCortes
-
dia_inicio
-
dia_final
🔹 tabShift Type
-
start_time
-
end_time
🧩 Lógica en Pseudocódigo
Obtener Usuario (3) - [getUser3]
🧾 Descripción
Este servicio permite obtener la información completa de un usuario, ya sea Empleado o Estudiante, usando cualquiera de los siguientes identificadores:
-
Correo (user_id)
-
DNI / Pasaporte (passport_number)
La función consulta múltiples tablas del ERP y retorna la información enriquecida del usuario, incluyendo:
-
Datos personales
-
Datos laborales
-
Contratos
-
Imagen de usuario
-
Estado actual
-
Sucursal, puesto, departamento
-
Datos adicionales (PETS, tipo de jornada, fondo de pensiones, etc.)
Si el usuario no es empleado, se intenta validar como estudiante.
El servicio aplica múltiples reglas de negocio internas sobre estado, tipo de usuario y permisos.
🚀 Endpoint
POST /get-user-3
📥 Body esperado
O también:
🔐 Seguridad
Este servicio requiere autenticación interna contra el ERP mediante dbErp() y ServiceErp() con token válido del sistema.
🧠 Flujo del Servicio (Resumen Real)
1. Determinar tipo de búsqueda
Si username contiene @, se asume que es user_id.
Si no contiene, se usa como passport_number (DNI).
Se arma el filtro dinámicamente:
| Caso | Campo filtrado |
|---|---|
| Correo | emp.user_id |
| DNI / Pasaporte | emp.passport_number |
2. Buscar al usuario como Empleado
Consulta principal: POST method/send-query-database
Incluye joins a:
-
tabUser
-
tabBranch
-
tabContrato de Trabajo
-
tabDepartment
Si existe un registro válido:
-
Se valida que NO esté inactivo.
-
Se formatea fecha de nacimiento.
-
Se determina si el contrato es renovación o primer contrato.
-
Se normalizan campos (pets, cuenta haberes, vigencia del contrato, tipo_usuario = "Empleado").
📌 Si todo está correcto, el servicio termina aquí retornando la data del empleado.
3. Si NO existe empleado → Buscar como Estudiante
Filtros dependen de correo o DNI.
Validaciones aplicadas:
-
Debe estar habilitado (
enabled = 1). -
Si no existe → acceso denegado.
-
Si está deshabilitado → retorno con error.
Datos retornados incluyen:
-
Nombre completo
-
Sucursal, departamento
-
Tipo de puesto (convertido desde convocatoria si aplica)
-
Imagen de usuario
-
Tipo_usuario = “Estudiante”
4. Retornar la data final
Si es empleado → retorna información laboral con contratos.
Si es estudiante → retorna información básica educativa.
📤 Response 200 – Ejemplo (Empleado)
❗ Posibles Errores
1. No existe como empleado ni estudiante
2. Empleado Inactivo
3. Usuario deshabilitado (estudiante)
4. Error al consultar ERP
📚 Tablas consultadas
Empleado
-
tabEmployee -
tabUser -
tabBranch -
tabContrato de Trabajo -
tabDepartment
Estudiante
-
tabStudent -
tabUser -
tabBranch -
tabJob Applicant -
tabRequerimiento de Personal -
tabDesignation -
tabDepartment
🗃 Resultado Final (Estructura General)
Para empleados:
Para estudiantes:
🧩 Pseudocódigo del servicio
Lista de Sucursales - [listOfErpBranchs]
🧾 Descripción
Obtiene la lista completa de sucursales registradas en el ERP, filtrando únicamente aquellas que:
-
No sean concesionarios (
concesionario = 0) -
Tengan un identificador válido (
ideentificador != "0")
El servicio consulta directamente el ERP a través del método apiService() y devuelve las sucursales ordenadas alfabéticamente por su nombre.
También realiza un post-proceso convirtiendo el campo ideentificador en string, garantizando consistencia en el frontend (evita problemas cuando el ERP envía valores numéricos).
🚀 Endpoint
GET /list-of-erp-branchs
No recibe parámetros.
Toda la data proviene del ERP mediante:
🔐 Seguridad
Requiere autenticación del ERP mediante apiService().
El token se gestiona internamente (servicio backend–backend).
🧠 Flujo del Servicio
-
Llama al ERP solicitando todas las sucursales:
-
Sin límite (
limit=None) -
Ordenadas (
order_by=name asc) -
Filtradas por:
-
concesionario = 0
-
ideentificador ≠ "0"
-
-
Campos solicitados:
-
name -
ideentificador
-
-
-
Decodifica la respuesta.
-
Valida que exista el campo
"data"en la respuesta del ERP.-
Si no existe, retorna error.
-
-
Recorre cada registro y convierte
ideentificadora string. -
Retorna la lista final de sucursales.
📥 Request Body
No tiene body.
📤 Response 200 – Ejemplo
❗ Posibles Errores
1. Error al obtener data del ERP
2. Excepción interna del servidor
📚 Esquema de datos (Branch)
Branch (GET)
Campos utilizados:
🗃 Pseudocódigo del servicio
Intento de Marcación (1) - [intentMarca]
🧾 Descripción
Registra y actualiza los intentos de marcación que realiza un empleado en una agencia durante el día.
Este servicio controla cuántas veces un colaborador intenta marcar asistencia, creando o actualizando un registro diario en el ERP.
Se basa en el Doctype:
-
Intento de marcacion
Y utiliza los campos:
-
empleado
-
agencia
-
intento
-
creacion (fecha del intento)
🚀 Endpoint
POST /intent-marca
El servicio recibe datos desde el body mediante Request.
📥 Request Body
Campos requeridos:
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| empleado | string | ✔ | Código del empleado |
| agencia | string | ✔ | Agencia en la que intenta marcar |
| intento | int | ✔ | Intento actual enviado desde la app |
🔐 Seguridad
Utiliza autenticación interna del ERP a través de:
-
dbErp() para consultas SQL
-
ServiceErp() para creación y actualización de documentos en el ERP
Requiere credenciales internas del sistema.
🧠 Flujo del Servicio (resumen real)
-
Valida que existan los parámetros obligatorios: empleado, agencia e intento.
Si falta alguno → retorna error. -
Determina la fecha actual (
Y-m-d).
Este valor se usa para registrar un intento por día. -
Consulta si el empleado ya tiene un registro de Intento de marcacion para el día actual:
-
Si existe un registro previo:
-
Se suma el intento nuevo al intento existente:
-
Se actualiza el Doctype:
-
-
Si NO existe un registro previo:
-
Se crea un nuevo documento Intento de marcacion:
-
-
Devuelve la respuesta directa del ERP.
📤 Response 200 – Ejemplo (actualizado)
✔ Caso actualización
✔ Caso creación
❗ Posibles Errores
1. Falta de parámetros requeridos
2. Error en la consulta DB → dbErp
3. Error en creación o actualización en ERP
📚 Doctype utilizado
Intento de marcacion
Campos usados:
🗃 Lógica en pseudo-código
Validar Marcación (1) - [validar]
🧾 Descripción
Este servicio ejecuta toda la lógica de validación previa para permitir que un empleado realice una marcación (asistencia).
El servicio centraliza más de 10 validaciones críticas, verificando:
-
Campos obligatorios
-
Licencias activas
-
Restricciones por puesto
-
Validación de firma de documentos obligatorios
-
Descarga de contratos y documentos requeridos
-
Datos incompletos del empleado
-
Tipo de marcación permitido
-
Esquema de fiscalización
-
Reglas por empresa (Shalom Express vs Shalom Empresarial)
Es un servicio de control que determina si el empleado puede realizar una marcación y qué mensaje debe mostrarse al usuario.
🚀 Endpoint
POST /validar
📥 Request Body (resumen)
🔐 Seguridad
-
Requiere usuario autenticado.
-
Usa datos precargados del empleado (
$this->employee_detail). -
Internamente utiliza múltiples servicios ERP y validadores internos.
🧠 Flujo del Servicio (Resumen Real)
1️⃣ Validar campos obligatorios
Llama a verifyFields().
Si falta algún parámetro → retorna error inmediato.
2️⃣ Cargar datos principales
-
empleado
-
tipo de marcación
-
fecha de asistencia
-
datos del empleado desde sesión previa
3️⃣ Validar restricciones por puesto
Si el empleado NO es "PreActivo", llama a:validateRestrictedDesignation(designation)
4️⃣ Validar licencia activaverifyLicencia(empleado, fechaIngreso)
5️⃣ Validar nuevos ingresos
Solo para empleados activos, ingreso reciente, y NO Express:verifySignedNewAdmissionRegistrations()
6️⃣ Validar descarga de documentos obligatorios
Obtiene documentos descargados:verifyDownloadedDocumentsBd()
Y valida contrato pendiente:verifyContractDownload()
7️⃣ Validar documentos de cambio de modalidadverifyModalityChangeDocument()
8️⃣ Validar información del empleado (horarios, jornada, etc.)verifyEmployeeData()
9️⃣ Obtener últimas marcacionesgetMarkingsByEmployee()
🔟 Validación de “No sujeto a fiscalización”verifyEmployeeNotSubjectToInspection()
1️⃣1️⃣ Validación de refrigerio
Si type == llegada_refrigerio:verifyStartOfLunch()
1️⃣2️⃣ Validar coherencia del tipo de marcación
Ejemplo: que no marque salida sin marcar ingreso.verifyTypeOfMarking()
📌 Si todas las validaciones son correctas → retorna éxito.
📤 Response 200 – Ejemplo (OK)
❗ Posibles Errores devueltos por este servicio
1. Campos obligatorios faltantes
2. Puesto restringido
3. Empleado con licencia activa
4. Documentos de ingreso no firmados
5. Contrato pendiente por descargar
6. Error en la lógica de marcación (orden incorrecta)
7. No sujeto a fiscalización
🗃 Funciones internas utilizadas
| Nombre | Descripción |
|---|---|
| verifyFields | Valida campos requeridos del request |
| validateRestrictedDesignation | Controla puestos con restricciones |
| verifyLicencia | Evalúa si el empleado tiene licencia activa |
| verifySignedNewAdmissionRegistrations | Valida firmas de ingreso |
| verifyDownloadedDocumentsBd | Valida documentos descargados |
| verifyContractDownload | Revisa si falta descargar contrato |
| verifyModalityChangeDocument | Valida documentos de cambios de modalidad |
| verifyEmployeeData | Verifica datos del empleado necesarios para marcar |
| getMarkingsByEmployee | Obtiene último registro de marcación |
| verifyEmployeeNotSubjectToInspection | Revisa si está sujeto a fiscalización |
| verifyStartOfLunch | Valida inicio del refrigerio |
| verifyTypeOfMarking | Controla coherencia de marcaciones |
🗃 Pseudo-código real del servicio
Crear Marcación (1) - [crear]
🧾 Descripción
Registra una marcación de entrada o salida para un empleado, validando previamente:
-
Datos obligatorios del request.
-
Duplicidad de marcaciones.
-
Estado del empleado (Activo / PreActivo).
-
Horario asignado (tardanza y horas extra).
-
Reglas especiales según modalidad (offline / online).
-
Registro simultáneo en:
-
ERP (Employee Checkin)
-
Base de datos interna (tabla marcaciones)
-
Es uno de los servicios centrales del módulo de asistencia.
🚀 Endpoint
POST /marcaciones/store
Este servicio sí recibe parámetros en el request.
📥 Request Body (Campos usados)
Campos relevantes
| Campo | Tipo | Descripción |
|---|---|---|
| empleado | string | ID del empleado |
| image | string | URL base64 o imagen enviada |
| fecha_asistencia | date | Fecha de la marcación |
| type | string | “entrada” o “salida” |
| passport_number | string | Documento del empleado |
| coordinates | string | Lat/Lon opcional |
| isOfline | int | 1 si se marcó offline |
🔐 Seguridad
El servicio requiere:
-
Token válido via middleware Laravel.
-
Acceso interno al ERP mediante
general->insertERPNew()ygeneral->dbErp().
🧠 Flujo del Servicio (resumen real)
1. Validación de campos
Se ejecuta verifyFields($request) y si falla, retorna de inmediato.
2. Prevención de fechas inválidas
Si la marcación es online y la fecha es mayor al día actual → rechaza.
3. Validación de duplicidad
Se construye:
Luego: validateDuplicateDialing()
Si ya existe marcación → error.
4. Obtención del turno del empleado
Consulta ERP:
-
Hora de inicio (
start_time) -
Hora de salida (
end_time) -
Datos básicos del empleado
Si es “entrada” → valida que pase de PreActivo → Activo.
5. Cálculo de tardanza u horas extra
-
Si el empleado marca entrada más de 5 min tarde → genera tardanza
"HH:MM". -
Si marca salida con +60 minutos → horas extra.
6. Registro en ERP
Crea documento:
Employee Checkin
7. Registro en base de datos interna
Inserta en tabla marcaciones:
8. Generación de asistencia
Si la marcación es salida, ejecuta: storeAttendance($request)
y devuelve datos adicionales.