From 913d7581d443d60e637dd45042d774560a1cd038 Mon Sep 17 00:00:00 2001 From: nicolasarana <90768149+nicolasarana@users.noreply.github.com> Date: Wed, 7 Jan 2026 11:31:20 -0300 Subject: [PATCH 1/2] feat(RUP):"Guardar datos de auditoria por registro" --- modules/rup/routes/prestacion.ts | 141 +++++++++++++++++++++++++++++- modules/rup/schemas/prestacion.ts | 11 +++ 2 files changed, 149 insertions(+), 3 deletions(-) diff --git a/modules/rup/routes/prestacion.ts b/modules/rup/routes/prestacion.ts index 0a9d5d490a..bc3d034a1c 100755 --- a/modules/rup/routes/prestacion.ts +++ b/modules/rup/routes/prestacion.ts @@ -583,6 +583,111 @@ router.post('/prestaciones', async (req, res, next) => { } }); +/** + * Mergea registros nuevos con existentes, preservando datos de auditoría + * + * @param registrosExistentes - Registros actuales en la base de datos + * @param registrosNuevos - Registros que vienen en el request + * @returns Registros mergeados con auditoría preservada + */ +function mergeRegistrosPreservandoAuditoria(registrosExistentes: any[], registrosNuevos: any[]): any[] { + if (!registrosExistentes || registrosExistentes.length === 0) { + // Si no hay registros existentes, retornamos los nuevos tal cual + return registrosNuevos; + } + + if (!registrosNuevos || registrosNuevos.length === 0) { + // Si no hay registros nuevos, mantenemos los existentes + return registrosExistentes; + } + + // Crear un mapa de registros existentes por _id para búsqueda rápida + const registrosExistentesMap = new Map(); + registrosExistentes.forEach(reg => { + if (reg._id) { + registrosExistentesMap.set(reg._id.toString(), reg); + } + }); + + // Procesar los registros nuevos + const registrosMergeados = registrosNuevos.map(regNuevo => { + const idNuevo = regNuevo._id ? regNuevo._id.toString() : null; + + // Si el registro nuevo tiene _id y existe en los registros actuales + if (idNuevo && registrosExistentesMap.has(idNuevo)) { + const regExistente = registrosExistentesMap.get(idNuevo); + + // Preservar datos de auditoría del registro existente + const registroMergeado = { + ...regNuevo, + createdAt: regExistente.createdAt, + createdBy: regExistente.createdBy, + // updatedAt y updatedBy serán actualizados por el AuditPlugin automáticamente + }; + + // Si el registro tiene registros anidados (secciones), mergear recursivamente + if (regNuevo.registros && regNuevo.registros.length > 0) { + registroMergeado.registros = mergeRegistrosPreservandoAuditoria( + regExistente.registros || [], + regNuevo.registros + ); + } + + return registroMergeado; + } else { + // Es un registro completamente nuevo, no tiene datos de auditoría previos + // El AuditPlugin de Mongoose agregará createdAt/createdBy automáticamente + + // Si tiene registros anidados y alguno podría ser existente, procesarlos también + if (regNuevo.registros && regNuevo.registros.length > 0) { + const registrosAnidadosExistentes = []; + // Intentar encontrar registros anidados existentes en todos los registros existentes + registrosExistentes.forEach(regEx => { + if (regEx.registros && regEx.registros.length > 0) { + registrosAnidadosExistentes.push(...regEx.registros); + } + }); + + regNuevo.registros = mergeRegistrosPreservandoAuditoria( + registrosAnidadosExistentes, + regNuevo.registros + ); + } + + return regNuevo; + } + }); + + return registrosMergeados; +} + +/** + * Actualiza la lista de profesionales que han registrado en esta prestación + * + * @param prestacion - Prestación a actualizar + * @param profesional - Profesional actual que está registrando + */ +function actualizarProfesionalesQueRegistran(prestacion: any, profesional: any) { + if (!prestacion.profesionalesQueRegistran) { + prestacion.profesionalesQueRegistran = []; + } + + // Verificar si el profesional ya está en la lista + const yaExiste = prestacion.profesionalesQueRegistran.some( + (prof: any) => prof.id && prof.id.toString() === profesional.id.toString() + ); + + if (!yaExiste) { + prestacion.profesionalesQueRegistran.push({ + id: profesional.id, + nombreCompleto: profesional.nombreCompleto, + nombre: profesional.nombre, + apellido: profesional.apellido, + documento: profesional.documento + }); + } +} + router.patch('/prestaciones/:id', (req: Request, res, next) => { Prestacion.findById(req.params.id, async (err, data: any) => { if (err) { @@ -638,7 +743,17 @@ router.patch('/prestaciones/:id', (req: Request, res, next) => { } } if (req.body.registros) { - data.ejecucion.registros = req.body.registros; + // Usar merge para preservar datos de auditoría de registros existentes + data.ejecucion.registros = mergeRegistrosPreservandoAuditoria( + data.ejecucion.registros, + req.body.registros + ); + + // Actualizar lista de profesionales que registran + const profesionalQueRegistra = Auth.getProfesional(req); + if (profesionalQueRegistra) { + actualizarProfesionalesQueRegistran(data, profesionalQueRegistra); + } } if (req.body.ejecucion?.fecha) { data.ejecucion.fecha = req.body.ejecucion.fecha; @@ -677,7 +792,17 @@ router.patch('/prestaciones/:id', (req: Request, res, next) => { break; case 'registros': if (req.body.registros && data.estadoActual.tipo !== 'validada') { - data.ejecucion.registros = req.body.registros; + // Usar merge para preservar datos de auditoría de registros existentes + data.ejecucion.registros = mergeRegistrosPreservandoAuditoria( + data.ejecucion.registros, + req.body.registros + ); + + // Actualizar lista de profesionales que registran + const profesionalQueRegistra = Auth.getProfesional(req); + if (profesionalQueRegistra) { + actualizarProfesionalesQueRegistran(data, profesionalQueRegistra); + } if (req.body.solicitud) { data.solicitud = req.body.solicitud; @@ -754,7 +879,17 @@ router.patch('/prestaciones/:id', (req: Request, res, next) => { break; case 'periodosCensables': data.periodosCensables = req.body.periodosCensables; - data.ejecucion.registros = req.body.registros; + // Usar merge para preservar datos de auditoría de registros existentes + data.ejecucion.registros = mergeRegistrosPreservandoAuditoria( + data.ejecucion.registros, + req.body.registros + ); + + // Actualizar lista de profesionales que registran + const profesionalActual = Auth.getProfesional(req); + if (profesionalActual) { + actualizarProfesionalesQueRegistran(data, profesionalActual); + } break; default: return next(500); diff --git a/modules/rup/schemas/prestacion.ts b/modules/rup/schemas/prestacion.ts index 4b45a514a4..4b247ea171 100644 --- a/modules/rup/schemas/prestacion.ts +++ b/modules/rup/schemas/prestacion.ts @@ -167,6 +167,17 @@ export const PrestacionSchema = new Schema({ elementoRUP: SchemaTypes.ObjectId }, + + profesionalesQueRegistran: [ + { + _id: false, + id: Schema.Types.ObjectId, + nombreCompleto: String, + nombre: String, + apellido: String, + documento: Number + } + ], tags: Schema.Types.Mixed, // Historia de estado de la prestación estados: [PrestacionEstadoSchema], From 3f0145c6c1e22b8fb21a4d3e8ba2b37395b88022 Mon Sep 17 00:00:00 2001 From: nicolasarana <90768149+nicolasarana@users.noreply.github.com> Date: Wed, 7 Jan 2026 11:31:20 -0300 Subject: [PATCH 2/2] feat(RUP):"Guardar datos de auditoria por registro" --- modules/rup/routes/prestacion.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/modules/rup/routes/prestacion.ts b/modules/rup/routes/prestacion.ts index bc3d034a1c..e0bd632dbc 100755 --- a/modules/rup/routes/prestacion.ts +++ b/modules/rup/routes/prestacion.ts @@ -592,16 +592,13 @@ router.post('/prestaciones', async (req, res, next) => { */ function mergeRegistrosPreservandoAuditoria(registrosExistentes: any[], registrosNuevos: any[]): any[] { if (!registrosExistentes || registrosExistentes.length === 0) { - // Si no hay registros existentes, retornamos los nuevos tal cual return registrosNuevos; } if (!registrosNuevos || registrosNuevos.length === 0) { - // Si no hay registros nuevos, mantenemos los existentes return registrosExistentes; } - // Crear un mapa de registros existentes por _id para búsqueda rápida const registrosExistentesMap = new Map(); registrosExistentes.forEach(reg => { if (reg._id) { @@ -609,23 +606,18 @@ function mergeRegistrosPreservandoAuditoria(registrosExistentes: any[], registro } }); - // Procesar los registros nuevos const registrosMergeados = registrosNuevos.map(regNuevo => { const idNuevo = regNuevo._id ? regNuevo._id.toString() : null; - // Si el registro nuevo tiene _id y existe en los registros actuales if (idNuevo && registrosExistentesMap.has(idNuevo)) { const regExistente = registrosExistentesMap.get(idNuevo); - // Preservar datos de auditoría del registro existente const registroMergeado = { ...regNuevo, createdAt: regExistente.createdAt, createdBy: regExistente.createdBy, - // updatedAt y updatedBy serán actualizados por el AuditPlugin automáticamente }; - // Si el registro tiene registros anidados (secciones), mergear recursivamente if (regNuevo.registros && regNuevo.registros.length > 0) { registroMergeado.registros = mergeRegistrosPreservandoAuditoria( regExistente.registros || [], @@ -635,13 +627,8 @@ function mergeRegistrosPreservandoAuditoria(registrosExistentes: any[], registro return registroMergeado; } else { - // Es un registro completamente nuevo, no tiene datos de auditoría previos - // El AuditPlugin de Mongoose agregará createdAt/createdBy automáticamente - - // Si tiene registros anidados y alguno podría ser existente, procesarlos también if (regNuevo.registros && regNuevo.registros.length > 0) { const registrosAnidadosExistentes = []; - // Intentar encontrar registros anidados existentes en todos los registros existentes registrosExistentes.forEach(regEx => { if (regEx.registros && regEx.registros.length > 0) { registrosAnidadosExistentes.push(...regEx.registros); @@ -672,7 +659,6 @@ function actualizarProfesionalesQueRegistran(prestacion: any, profesional: any) prestacion.profesionalesQueRegistran = []; } - // Verificar si el profesional ya está en la lista const yaExiste = prestacion.profesionalesQueRegistran.some( (prof: any) => prof.id && prof.id.toString() === profesional.id.toString() );