From 3ef1eefa8689761cc1497b1cf1df6784e708c420 Mon Sep 17 00:00:00 2001 From: ma7payne Date: Mon, 9 Mar 2026 15:37:14 -0300 Subject: [PATCH] =?UTF-8?q?feat(REC):=20implementa=20renovaci=C3=B3n=20de?= =?UTF-8?q?=20recetas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ejecucion/hudsBusqueda.component.ts | 137 ++++++++++--- .../components/ejecucion/hudsBusqueda.html | 192 ++++++++++-------- .../ejecucion/recetas/renovarMedicacion.html | 24 +++ .../ejecucion/recetas/renovarMedicacion.ts | 41 ++++ .../recetas/suspenderMedicacion.html | 13 +- .../ejecucion/recetas/suspenderMedicacion.ts | 26 ++- src/app/modules/rup/huds-lib.module.ts | 7 +- src/app/services/receta.service.ts | 4 + 8 files changed, 325 insertions(+), 119 deletions(-) create mode 100644 src/app/modules/rup/components/ejecucion/recetas/renovarMedicacion.html create mode 100644 src/app/modules/rup/components/ejecucion/recetas/renovarMedicacion.ts diff --git a/src/app/modules/rup/components/ejecucion/hudsBusqueda.component.ts b/src/app/modules/rup/components/ejecucion/hudsBusqueda.component.ts index 991625e2e6..b48b013d46 100644 --- a/src/app/modules/rup/components/ejecucion/hudsBusqueda.component.ts +++ b/src/app/modules/rup/components/ejecucion/hudsBusqueda.component.ts @@ -147,10 +147,13 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit, OnDestro public filtroRecetas; public searchRecetas; public busquedaRecetas; + private busquedaRecetasOriginal; public motivosSuspension; public motivoSuspensionSelector; public seleccionRecetas = []; - public seleccionSuspender = []; + public seleccionBotonesAccion = []; + public accionRecetas = null; + public mostrarConfirmacion = false; /** * Ids correspondientes a Prescripción de Medicamentos y Seguimiento Hídrico respectivamente */ @@ -946,11 +949,14 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit, OnDestro const searchTerm = this.searchRecetas?.toLowerCase() || ''; if (!searchTerm && !this.filtroRecetas) { - this.groupRecetas(); + this.busquedaRecetas = this.busquedaRecetasOriginal; return; } - let filteredRecetas = this.busquedaRecetas; + if (!this.busquedaRecetasOriginal) { + return; + } + let filteredRecetas = [...this.busquedaRecetasOriginal]; if (searchTerm) { filteredRecetas = filteredRecetas.filter(group => { @@ -997,7 +1003,7 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit, OnDestro return acc; }, {}); - this.busquedaRecetas = this.sortRecetas( + this.busquedaRecetasOriginal = this.sortRecetas( Object.keys(grupoRecetas).map(key => ({ conceptId: key, recetas: grupoRecetas[key], @@ -1005,6 +1011,7 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit, OnDestro })) ); + this.filtrarRecetas(); }); } @@ -1019,7 +1026,43 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit, OnDestro resetSeleccionRecetas() { this.groupRecetas(); this.seleccionRecetas = []; - this.seleccionSuspender = []; + this.seleccionBotonesAccion = []; + this.mostrarConfirmacion = false; + } + + setAccionRecetas(accion) { + if (this.accionRecetas === accion) { + this.accionRecetas = null; + } else { + this.accionRecetas = accion; + } + this.resetSeleccionRecetas(); + } + + confirmarAccionRecetas() { + if (this.seleccionBotonesAccion.length === 0) { return; } + if (this.accionRecetas === 'renovar') { + const count = this.seleccionBotonesAccion.length; + const msg = count === 1 + ? `¿Está seguro que desea renovar ${this.seleccionBotonesAccion[0].medicamento?.concepto?.term}?` + : `¿Está seguro que desea renovar las ${count} medicaciones seleccionadas?`; + this.plex.confirm(msg, 'Renovar recetas').then(confirmado => { + if (!confirmado) { return; } + const organizacion = { id: this.auth.organizacion.id, nombre: this.auth.organizacion.nombre }; + const recetaIds = this.seleccionBotonesAccion.map(r => r.id); + this.recetasService.renovar(recetaIds, this.profesional, organizacion).subscribe({ + next: () => { + this.plex.toast('success', 'Medicaciones renovadas correctamente'); + this.resetSeleccionRecetas(); + }, + error: () => { + this.plex.toast('danger', 'Error al renovar las medicaciones'); + } + }); + }); + } else if (this.accionRecetas === 'suspender') { + this.mostrarConfirmacion = true; + } } openRecetaTab(group) { @@ -1027,18 +1070,58 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit, OnDestro } esRecetaSeleccionable(receta) { - const estadosPermitidos = ['vigente', 'pendiente']; - const dispensasPermitidas = ['sin-dispensa', 'dispensa-parcial']; - if (!receta.medicamento.tratamientoProlongado) { - return (estadosPermitidos.includes(receta.estadoActual?.tipo) - && dispensasPermitidas.includes(receta.estadoDispensaActual?.tipo)) && this.profesionalValido; - } else { - const recetasMismoRegistro = this.busquedaRecetas?.flatMap(grupo => - grupo.recetas.filter(r => r.idRegistro === receta.idRegistro && r.medicamento.concepto.conceptId === receta.medicamento.concepto.conceptId) + if (!this.accionRecetas) { + return false; + } + + const esRenovar = this.accionRecetas === 'renovar'; + + if (esRenovar) { + // 1. Suspendidas no se pueden renovar + if (receta.estadoActual?.tipo === 'suspendida') { + return false; + } + + // 2. Solo recetas del último año + const dentroDelAnio = moment().subtract(1, 'year').isSameOrBefore(moment(receta.fechaRegistro)); + if (!dentroDelAnio) { + return false; + } + + // 3. Solo se pueden renovar si el grupo no tiene recetas pendientes + const recetasDelGrupo = this.busquedaRecetas?.flatMap(grupo => + grupo.recetas.filter(r => + r.idRegistro === receta.idRegistro && + r.medicamento.concepto.conceptId === receta.medicamento.concepto.conceptId + ) ) || []; - return recetasMismoRegistro.some(rec => - (estadosPermitidos.includes(rec.estadoActual?.tipo) - && dispensasPermitidas.includes(rec.estadoDispensaActual?.tipo)) && this.profesionalValido); + const tienePendientes = recetasDelGrupo.some(r => r.estadoActual?.tipo === 'pendiente'); + if (tienePendientes) { + return false; + } + + // 4. Solo se pueden renovar recetas finalizadas o vencidas + const estadosRenovables = ['finalizada', 'vencida']; + if (!estadosRenovables.includes(receta.estadoActual?.tipo)) { + return false; + } + + return this.profesionalValido; + } else { + // Suspension logic + const estadosPermitidos = ['vigente', 'pendiente']; + const dispensasPermitidas = ['sin-dispensa', 'dispensa-parcial']; + if (!receta.medicamento.tratamientoProlongado) { + return (estadosPermitidos.includes(receta.estadoActual?.tipo) + && dispensasPermitidas.includes(receta.estadoDispensaActual?.tipo)) && this.profesionalValido; + } else { + const recetasMismoRegistro = this.busquedaRecetas?.flatMap(grupo => + grupo.recetas.filter(r => r.idRegistro === receta.idRegistro && r.medicamento.concepto.conceptId === receta.medicamento.concepto.conceptId) + ) || []; + return recetasMismoRegistro.some(rec => + (estadosPermitidos.includes(rec.estadoActual?.tipo) + && dispensasPermitidas.includes(rec.estadoDispensaActual?.tipo)) && this.profesionalValido); + } } } @@ -1062,26 +1145,32 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit, OnDestro const isSelected = event.value; let recetaSeleccionada = []; const estadosNoSeleccionables = ['suspendida', 'vencida', 'dispensada']; + const esRenovar = this.accionRecetas === 'renovar'; + setTimeout(() => { - if (!this.recetaVisible(recetas).medicamento.tratamientoProlongado) { - recetaSeleccionada = recetas - .filter(receta => receta.estadoActual.tipo === 'vigente') - .sort((a, b) => moment(b.fechaRegistro).diff(moment(a.fechaRegistro)))[0]; + if (!this.recetaVisible(recetas).medicamento.tratamientoProlongado || esRenovar) { + if (esRenovar) { + recetaSeleccionada = this.recetaVisible(recetas); + } else { + recetaSeleccionada = recetas + .filter(receta => receta.estadoActual.tipo === 'vigente') + .sort((a, b) => moment(b.fechaRegistro).diff(moment(a.fechaRegistro)))[0]; + } if (isSelected) { this.seleccionRecetas[index] = true; - this.seleccionSuspender.push(recetaSeleccionada); + this.seleccionBotonesAccion.push(recetaSeleccionada); } else { this.seleccionRecetas[index] = null; - this.seleccionSuspender = this.seleccionSuspender.filter(r => r.id !== recetaSeleccionada.id); + this.seleccionBotonesAccion = this.seleccionBotonesAccion.filter(r => r.id !== recetaSeleccionada.id); } } else { if (isSelected) { this.seleccionRecetas[index] = true; - this.seleccionSuspender.push(...recetas.filter(receta => !estadosNoSeleccionables.includes(receta.estadoDispensaActual.tipo) && !estadosNoSeleccionables.includes(receta.estadoActual.tipo))); + this.seleccionBotonesAccion.push(...recetas.filter(receta => !estadosNoSeleccionables.includes(receta.estadoDispensaActual.tipo) && !estadosNoSeleccionables.includes(receta.estadoActual.tipo))); } else { this.seleccionRecetas[index] = null; - this.seleccionSuspender = this.seleccionSuspender.filter( + this.seleccionBotonesAccion = this.seleccionBotonesAccion.filter( r => !recetas.some(receta => receta.id === r.id) ); } diff --git a/src/app/modules/rup/components/ejecucion/hudsBusqueda.html b/src/app/modules/rup/components/ejecucion/hudsBusqueda.html index 4e799c59a0..4cc49e508d 100644 --- a/src/app/modules/rup/components/ejecucion/hudsBusqueda.html +++ b/src/app/modules/rup/components/ejecucion/hudsBusqueda.html @@ -21,22 +21,43 @@
@@ -75,67 +96,73 @@
{{ getTitulo(filtroActual) | uppercas
  • - -
    -
    - - Tratamiento prolongado: {{ (grupo.recetaVisible?.medicamento?.ordenTratamiento !== - null && grupo.recetaVisible?.medicamento?.ordenTratamiento !== undefined) ? - (grupo.recetaVisible.medicamento.ordenTratamiento + 1) : 0 }} de - {{grupo.recetaVisible?.medicamento.tiempoTratamiento?.id}} -
    -
    -
    -
    +
    + -
    -
    -
    -
    - -
    -
    -
    - {{ grupo.recetas[0].medicamento.concepto.term }}
    -
    -
    -
    - Fecha de Registro: - {{ grupo.recetaVisible?.fechaRegistro | - date:'short' }} - -
    - Profesional: {{ - grupo.recetaVisible?.profesional.nombre }} {{ - grupo.recetaVisible?.profesional.apellido }} - + Tratamiento prolongado: {{ (grupo.recetaVisible?.medicamento?.ordenTratamiento + !== + null && grupo.recetaVisible?.medicamento?.ordenTratamiento !== undefined) ? + (grupo.recetaVisible.medicamento.ordenTratamiento + 1) : 0 }} de + {{grupo.recetaVisible?.medicamento.tiempoTratamiento?.id}} +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + {{ grupo.recetas[0].medicamento.concepto.term }}
    +
    +
    +
    + Fecha de Registro: + {{ grupo.recetaVisible?.fechaRegistro | + date:'short' }} + +
    + Profesional: {{ + grupo.recetaVisible?.profesional.nombre }} + {{ + grupo.recetaVisible?.profesional.apellido }} + +
    -
    -
    -
    -
    - - {{ grupo.recetaVisible?.estadoActual?.tipo.replace('-', ' ') - }} - - - {{ - grupo.recetaVisible?.estadoDispensaActual?.tipo.replace('-', - ' ') - }} - +
    +
    +
    + + {{ grupo.recetaVisible?.estadoActual?.tipo.replace('-', + ' ') + }} + + + {{ + grupo.recetaVisible?.estadoDispensaActual?.tipo.replace('-', + ' ') + }} + +
    @@ -143,7 +170,6 @@
    {{ getTitulo(filtroActual) | uppercas
    -
@@ -215,16 +241,16 @@
{{ getTitulo(filtroActual) | uppercas
- {{ registro.estadoActual.tipo }} - - - - - + {{ registro.estadoActual.tipo }} + + + + +
@@ -883,11 +909,11 @@
{{ getTitulo(filtroActual) | uppercas
  • + [ngClass]="{'active': huds.isOpen(registro, 'recc'), 'recc': true}" + (click)="clickDerivacion(registro, iDerivacion)">
    + [ngClass]="{'active': huds.isOpen(registro, 'recc') , 'rup-border-recc': true}">
    @@ -908,12 +934,12 @@
    {{ getTitulo(filtroActual) | uppercas
    Profesional: + *ngIf='registro.profesionalSolicitante'> {{ registro.profesionalSolicitante | nombre }} + *ngIf='!registro.profesionalSolicitante'> No existe @@ -934,7 +960,7 @@
    {{ getTitulo(filtroActual) | uppercas
    + titulo="No hay derivaciones registradas">
    diff --git a/src/app/modules/rup/components/ejecucion/recetas/renovarMedicacion.html b/src/app/modules/rup/components/ejecucion/recetas/renovarMedicacion.html new file mode 100644 index 0000000000..7d44a5953b --- /dev/null +++ b/src/app/modules/rup/components/ejecucion/recetas/renovarMedicacion.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + +
    IndicacionProfesional
    {{ receta?.medicamento.concepto.term }}{{ receta?.profesional.nombre }} {{ receta?.profesional.apellido }}
    + + +
    \ No newline at end of file diff --git a/src/app/modules/rup/components/ejecucion/recetas/renovarMedicacion.ts b/src/app/modules/rup/components/ejecucion/recetas/renovarMedicacion.ts new file mode 100644 index 0000000000..8d4979ce60 --- /dev/null +++ b/src/app/modules/rup/components/ejecucion/recetas/renovarMedicacion.ts @@ -0,0 +1,41 @@ +import { Auth } from '@andes/auth'; +import { Plex } from '@andes/plex'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { RecetaService } from 'src/app/services/receta.service'; + +@Component({ + selector: 'renovar-medicacion', + templateUrl: 'renovarMedicacion.html', +}) + +export class RenovarMedicacionComponent { + constructor( + public plex: Plex, + private recetasService: RecetaService, + private auth: Auth, + ) { } + + @Input() seleccionRecetas: any[]; + @Input() profesional: any; + + @Output() reset: EventEmitter = new EventEmitter(); + @Output() cerrar: EventEmitter = new EventEmitter(); + + public renovarMedicacion() { + const organizacion = { id: this.auth.organizacion.id, nombre: this.auth.organizacion.nombre }; + const recetaIds = this.seleccionRecetas + .filter(receta => receta !== null) + .map(receta => receta.id); + + this.recetasService.renovar(recetaIds, this.profesional, organizacion).subscribe({ + next: () => { + this.reset.emit(); + this.cerrar.emit(); + this.plex.toast('success', 'Medicaciones renovadas correctamente'); + }, + error: () => { + this.plex.toast('danger', 'Error al renovar las medicaciones'); + } + }); + } +} diff --git a/src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.html b/src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.html index 7bf37b51b8..3965c0c8ba 100644 --- a/src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.html +++ b/src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.html @@ -1,7 +1,7 @@ - + + [disabled]="!formSuspension.valid" (click)="suspenderMedicacion()"> @@ -17,8 +17,7 @@ {{ medicamento.term }} {{ medicamento.count }} - {{ medicamento?.profesional?.nombre }} {{ medicamento?.profesional?.apellido }} - + {{ medicamento?.profesional?.nombre }} {{ medicamento?.profesional?.apellido }} @@ -26,10 +25,10 @@
    + required> - +
    \ No newline at end of file diff --git a/src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.ts b/src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.ts index f9e9e4dd28..83340139ba 100644 --- a/src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.ts +++ b/src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.ts @@ -1,5 +1,5 @@ import { Plex } from '@andes/plex'; -import { Component, EventEmitter, Input, Output, ChangeDetectorRef, AfterViewChecked } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ChangeDetectorRef, AfterViewChecked, ViewChild, OnInit } from '@angular/core'; import { RecetaService } from 'src/app/services/receta.service'; @Component({ @@ -8,7 +8,7 @@ import { RecetaService } from 'src/app/services/receta.service'; styleUrls: ['suspenderMedicacion.scss'] }) -export class SuspenderMedicacionComponent implements AfterViewChecked { +export class SuspenderMedicacionComponent implements AfterViewChecked, OnInit { constructor( public plex: Plex, private recetasService: RecetaService, @@ -24,6 +24,14 @@ export class SuspenderMedicacionComponent implements AfterViewChecked { public motivoSelector: any; public observacion: string; + @ViewChild('modal', { static: true }) modal: any; + + ngOnInit() { + if (this.modal) { + setTimeout(() => this.modal.show()); + } + } + get groupedMedicamentos() { if (!this.seleccionRecetas || !Array.isArray(this.seleccionRecetas)) { return []; @@ -50,8 +58,12 @@ export class SuspenderMedicacionComponent implements AfterViewChecked { return; } + const count = this.seleccionRecetas.length; const medicamento = this.seleccionRecetas[0]?.medicamento?.concepto?.term || 'medicamento'; - this.plex.confirm(`¿Está seguro que desea suspender ${this.seleccionRecetas.length > 1 ? `las (${this.seleccionRecetas.length}) medicaciones seleccionadas` : `
    "${medicamento}"`}?`, 'Atención').then(confirmacion => { + const msg = count === 1 + ? `¿Está seguro que desea suspender
    "${medicamento}"?` + : `¿Está seguro que desea suspender las ${count} medicaciones seleccionadas?`; + this.plex.confirm(msg, 'Atención').then(confirmacion => { const recetasASuspender = this.filtrarRecetasUnicas(this.seleccionRecetas); if (confirmacion && recetasASuspender.length > 0) { let completadas = 0; @@ -64,6 +76,7 @@ export class SuspenderMedicacionComponent implements AfterViewChecked { completadas++; if (completadas + errores === total) { this.reset.emit(); + if (this.modal) {this.modal.close();} if (errores === 0) { this.plex.toast('success', 'Medicaciones suspendidas correctamente'); } else { @@ -97,6 +110,13 @@ export class SuspenderMedicacionComponent implements AfterViewChecked { }); } + cancelar() { + if (this.modal) { + this.modal.close(); + } + this.reset.emit(); + } + ngAfterViewChecked() { if (this.cdr) { this.cdr.detectChanges(); diff --git a/src/app/modules/rup/huds-lib.module.ts b/src/app/modules/rup/huds-lib.module.ts index 1d042a2519..8eb9fce27e 100644 --- a/src/app/modules/rup/huds-lib.module.ts +++ b/src/app/modules/rup/huds-lib.module.ts @@ -38,6 +38,7 @@ import { VistaLaboratorioComponent } from './components/ejecucion/laboratorios/v import { VistaRecetaComponent } from './components/huds/vistaReceta'; import { SuspenderMedicacionComponent } from './components/ejecucion/recetas/suspenderMedicacion'; import { VistaDerivacionComponent } from './components/huds/vistaDerivacion'; +import { RenovarMedicacionComponent } from './components/ejecucion/recetas/renovarMedicacion'; @NgModule({ imports: [ @@ -82,7 +83,8 @@ import { VistaDerivacionComponent } from './components/huds/vistaDerivacion'; VistaHistorialTurnosComponent, HudsBusquedaComponent, ListadoInternacionHudsComponent, - SuspenderMedicacionComponent + SuspenderMedicacionComponent, + RenovarMedicacionComponent ], exports: [ VistaCDAComponent, @@ -106,7 +108,8 @@ import { VistaDerivacionComponent } from './components/huds/vistaDerivacion'; VistaHistorialTurnosComponent, HudsBusquedaComponent, ListadoInternacionHudsComponent, - SuspenderMedicacionComponent + SuspenderMedicacionComponent, + RenovarMedicacionComponent ], providers: [MotivosHudsService] diff --git a/src/app/services/receta.service.ts b/src/app/services/receta.service.ts index d1ca59e70b..89dbd93308 100644 --- a/src/app/services/receta.service.ts +++ b/src/app/services/receta.service.ts @@ -29,6 +29,10 @@ export class RecetaService { return this.server.patch(`${this.url}`, { op: 'suspender', recetaId, motivo, observacion, profesional }); } + renovar(recetasIds: string[], profesional: any, organizacion: any) { + return this.server.post(`${this.url}/renovar`, { recetasIds, profesional, organizacion }); + } + getRecetaPrincipal(recetas) { if (recetas.length === 1) { return recetas[0];