Plataforma técnica · Orchestrator
WorkingDay Service
Remuneraciones Jornadas Asistencia
WorkingDayService administra el catálogo de jornadas laborales del tenant. Cada jornada define un horario específico por día de la semana, tolerancias para llegada/salida, límites de horas normales y de horas extra al 50%, y reglas de recargo automático para domingos y feriados.
El contrato referencia una jornada vía jornada_id y AttendanceService la lee para generar la grilla mensual esperada. Una jornada no se elimina (no hay delete) — se desactiva con activa = false para preservar referencias históricas.
Ubicación
Section titled “Ubicación”Directoryorchestrator/src/domain/working_day/
- WorkingDayService.ts
- WorkingDayRepository.ts
- types.ts
Tabla: remuneraciones.jornadas.
API pública
Section titled “API pública”| Método | Firma | Resultado |
|---|---|---|
findById | (ctx, id) => Promise<WorkingDay | null> | Jornada completa. |
findAll | (ctx, filter: WorkingDayCatalogFilter) => Promise<WorkingDay[]> | Lista con filtros (activa, tipo). |
create | (ctx, data: WorkingDayInput) => Promise<ServiceResult<WorkingDay>> | Inserta y devuelve el registro completo. |
update | (ctx, id, data: WorkingDayInput) => Promise<ServiceResult<WorkingDay>> | Update parcial. |
No expone delete. Las jornadas se “retiran” actualizando activa = false.
Tipo (extracto)
Section titled “Tipo (extracto)”type JornadaTipo = "COMPLETA" | "PARCIAL" | "ESPECIAL";
interface WorkingDay { id: string; codigo: string; nombre: string; tipo_jornada: JornadaTipo; horas_diarias_standard: number | null; horas_semanales: number | null; dias_laborales_semana: number | null;
// Almuerzo (sujeto a chk_almuerzo_coherente) hora_inicio_almuerzo: string | null; hora_fin_almuerzo: string | null; duracion_almuerzo_minutos: number | null;
// Límites y recargos limite_horas_normales_dia: number | null; limite_horas_extra_50_dia: number | null; todas_extra_100_domingos: boolean; todas_extra_100_feriados: boolean;
// Tolerancias tolerancia_atraso_minutos: number | null; tolerancia_salida_temprana_minutos: number | null;
// Horario por día (× 7 días) trabaja_lunes: boolean; hora_entrada_lunes: string | null; hora_salida_lunes: string | null; // ... idem martes, miercoles, jueves, viernes, sabado, domingo
// Atributos es_turno_nocturno: boolean; turno_rotativo: boolean; requiere_registro_biometrico: boolean;
// Versionado version: number | null; fecha_vigencia_desde: string | null; fecha_vigencia_hasta: string | null; activa: boolean;}Validaciones
Section titled “Validaciones”En create
Section titled “En create”| Campo | Regla |
|---|---|
codigo, nombre | Obligatorios. validateRequired. |
tipo_jornada | Uppercase ∈ ["COMPLETA", "PARCIAL", "ESPECIAL"]. |
En update (parcial)
Section titled “En update (parcial)”| Campo | Regla |
|---|---|
id | Obligatorio en path. |
codigo (si se envía) | No vacío. |
nombre (si se envía) | No vacío. |
tipo_jornada (si se envía) | Mismo enum que en create. |
En base de datos
Section titled “En base de datos”Constraint chk_almuerzo_coherente: si una jornada tiene hora_inicio_almuerzo, también debe tener hora_fin_almuerzo, y hora_fin > hora_inicio. O ambos NULL. El service captura e.constraint === "chk_almuerzo_coherente" y devuelve:
"Almuerzo inválido: define ambos horarios y fin > inicio, o deja ambos en blanco."Errores
Section titled “Errores”| Origen | Mensaje | Cuándo |
|---|---|---|
validateRequired | "<campo> es requerido" | Falta codigo o nombre. |
| Service | "tipo_jornada inválido" | tipo_jornada fuera del enum. |
| Service | "Falta id" | Update sin id. |
| Service | "Código no puede estar vacío" / "Nombre no puede estar vacío" | Update enviando estos campos como string vacío. |
| Constraint DB | "Almuerzo inválido: ..." | Violación de chk_almuerzo_coherente. |
| Service | notFound("Jornada no encontrada") | Update con id inexistente. |
Recargos automáticos
Section titled “Recargos automáticos”PayrollEngine aplica recargo del 100% sobre las horas trabajadas en días donde la jornada marca:
| Flag | Efecto |
|---|---|
todas_extra_100_domingos = true | Las horas trabajadas en domingo se pagan al 100% (no al 50%). |
todas_extra_100_feriados = true | Idem para feriados nacionales (consultados al calendario). |
limite_horas_normales_dia define el corte donde inicia el recargo del 50%; limite_horas_extra_50_dia define el techo de horas extras autorizadas por día.
Consumidores
Section titled “Consumidores”| Service | Cómo consume |
|---|---|
ContractService | jornada_id obligatorio en el contrato; getJornadaData valida que exista. |
AttendanceService | Lee la jornada del contrato para armar la grilla esperada (qué días + qué horarios). |
PayrollEngine (vía Payroll context) | Aplica límites, tolerancias y recargos para calcular descuentos por atraso y haberes por horas extra. |
ContractFormatters.formatSchedule | Lee trabaja_* y hora_entrada_*/hora_salida_* para imprimir “Lunes a Viernes: de 09:00 a 19:00 horas.” en el PDF del contrato. |