Skip to content

Commit d1bc47f

Browse files
committed
feat(REC): implementa renovacion de recetas
1 parent 7bfc953 commit d1bc47f

3 files changed

Lines changed: 119 additions & 2 deletions

File tree

modules/recetas/recetas.error.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,12 @@ export class RecetaNotEdit extends Error {
1616
this.message = motivo ? this.message + '. Motivo: ' + motivo : this.message;
1717
}
1818
}
19+
20+
export class RecetaNoRenovable extends Error {
21+
status = 400;
22+
message = 'La receta no puede ser renovada';
23+
constructor(motivo?: string) {
24+
super();
25+
this.message = motivo ? this.message + '. Motivo: ' + motivo : this.message;
26+
}
27+
}

modules/recetas/recetas.routes.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { asyncHandler, Request, Response } from '@andes/api-tool';
22
import { MongoQuery, ResourceBase } from '@andes/core';
33
import { Auth } from '../../auth/auth.class';
44
import { Receta } from './receta-schema';
5-
import { buscarRecetas, getMotivosReceta, setEstadoDispensa, suspender, actualizarAppNotificada, cancelarDispensa, crearReceta } from './recetasController';
5+
import { buscarRecetas, getMotivosReceta, setEstadoDispensa, suspender, actualizarAppNotificada, cancelarDispensa, crearReceta, renovarRecetas } from './recetasController';
6+
67
import { ParamsIncorrect } from './recetas.error';
78

89
class RecetasResource extends ResourceBase {
@@ -80,6 +81,13 @@ export const post = async (req, res) => {
8081
res.status(status).json(resp);
8182
};
8283

84+
export const renovar = async (req, res) => {
85+
const resp = await renovarRecetas(req);
86+
const status = (resp as any)?.status || 200;
87+
res.status(status).json(resp);
88+
};
89+
90+
8391
export const RecetasCtr = new RecetasResource({});
8492
export const RecetasRouter = RecetasCtr.makeRoutes();
8593

@@ -96,4 +104,6 @@ RecetasRouter.use(Auth.authenticate());
96104
RecetasRouter.get('/recetas', authorizeByToken, asyncHandler(get));
97105
RecetasRouter.get('/recetas/motivos', asyncHandler(getMotivos));
98106
RecetasRouter.patch('/recetas', authorizeByToken, asyncHandler(patch));
107+
RecetasRouter.post('/recetas/renovar', authorizeByToken, asyncHandler(renovar));
99108
RecetasRouter.post('/recetas', authorizeByToken, asyncHandler(post));
109+

modules/recetas/recetasController.ts

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { searchMatriculas } from '../../core/tm/controller/profesional';
66
import { RecetasParametros } from './parametros.schema';
77
import { createLog, informarLog, updateLog, jobsLog } from './recetaLogs';
88
import { MotivosReceta, Receta } from './receta-schema';
9-
import { ParamsIncorrect, RecetaNotEdit, RecetaNotFound } from './recetas.error';
9+
import { ParamsIncorrect, RecetaNotEdit, RecetaNotFound, RecetaNoRenovable } from './recetas.error';
10+
1011
import { getReceta } from './services/receta';
1112

1213

@@ -543,6 +544,103 @@ export async function crearReceta(req) {
543544
}
544545

545546

547+
/**
548+
* Renueva una lista de recetas desde la HUDS.
549+
* Crea nuevas recetas copiando medicamento/paciente/diagnóstico, pero sobreescribiendo
550+
* el profesional y efector con los del usuario que hace la renovación.
551+
* Validaciones:
552+
* - La receta debe existir en la BD.
553+
* - No puede ser tratamiento prolongado.
554+
* - Debe tener antigüedad ≤ 6 meses.
555+
*/
556+
export async function renovarRecetas(req) {
557+
const { recetasIds, profesional, organizacion } = req.body;
558+
559+
try {
560+
if (!recetasIds || !Array.isArray(recetasIds) || recetasIds.length === 0 || !profesional || !organizacion) {
561+
throw new ParamsIncorrect();
562+
}
563+
564+
const limiteAntiguedad = moment().subtract(6, 'months').toDate();
565+
566+
// Obtener datos de profesión del profesional que renueva
567+
const datosProfesion = await getDatosProfesion(profesional);
568+
569+
const nuevasRecetas = await Promise.all(
570+
recetasIds.map(async (recetaId) => {
571+
const recetaOriginal: any = await Receta.findById(recetaId);
572+
573+
if (!recetaOriginal) {
574+
throw new RecetaNotFound();
575+
}
576+
577+
if (recetaOriginal.medicamento?.tratamientoProlongado === true) {
578+
throw new RecetaNoRenovable('la receta es un tratamiento prolongado');
579+
}
580+
581+
if (recetaOriginal.fechaRegistro < limiteAntiguedad) {
582+
throw new RecetaNoRenovable('la receta tiene más de 6 meses de antigüedad');
583+
}
584+
585+
const nuevaReceta: any = new Receta();
586+
587+
// Identificadores nuevos (la renovación no está ligada a una prestación RUP existente)
588+
nuevaReceta.idPrestacion = new Types.ObjectId().toString();
589+
nuevaReceta.idRegistro = new Types.ObjectId().toString();
590+
nuevaReceta.idRecetaOriginal = recetaOriginal._id.toString();
591+
592+
// Datos clínicos heredados de la receta original
593+
nuevaReceta.paciente = recetaOriginal.paciente;
594+
nuevaReceta.medicamento = recetaOriginal.medicamento;
595+
nuevaReceta.diagnostico = recetaOriginal.diagnostico;
596+
597+
// Profesional y efector sobreescritos por quien renueva
598+
nuevaReceta.profesional = {
599+
id: profesional.id,
600+
nombre: profesional.nombre,
601+
apellido: profesional.apellido,
602+
documento: profesional.documento,
603+
profesion: datosProfesion.profesionGrado,
604+
especialidad: datosProfesion.especialidades,
605+
matricula: datosProfesion.matriculaGrado,
606+
};
607+
nuevaReceta.organizacion = {
608+
id: organizacion.id,
609+
nombre: organizacion.nombre,
610+
};
611+
612+
// Estado de la receta
613+
const ahora = new Date();
614+
nuevaReceta.estados = [{ tipo: 'vigente', fecha: ahora }];
615+
nuevaReceta.estadoActual = { tipo: 'vigente', fecha: ahora };
616+
617+
// Estado de dispensa limpio
618+
nuevaReceta.estadosDispensa = [{ tipo: 'sin-dispensa', fecha: ahora }];
619+
nuevaReceta.estadoDispensaActual = { tipo: 'sin-dispensa', fecha: ahora };
620+
621+
// Fechas de la nueva receta
622+
nuevaReceta.fechaRegistro = ahora;
623+
nuevaReceta.fechaPrestacion = ahora;
624+
625+
// Limpiar dispensas y notificaciones de app
626+
nuevaReceta.dispensa = [];
627+
nuevaReceta.appNotificada = [];
628+
629+
Auth.audit(nuevaReceta, req);
630+
await nuevaReceta.save();
631+
632+
return nuevaReceta;
633+
})
634+
);
635+
636+
return nuevasRecetas;
637+
} catch (err) {
638+
await createLog.error('renovarRecetas', { recetasIds, profesional, organizacion }, err, req);
639+
return err;
640+
}
641+
}
642+
643+
546644
/**
547645
* Actualiza estado de recetas:
548646
* pendientes pasan a estado vigentes y

0 commit comments

Comments
 (0)