Skip to content

Commit 5d3db8d

Browse files
committed
feat(RUP): implementa renovacion de receta
1 parent 7c8bcf0 commit 5d3db8d

File tree

13 files changed

+254
-73
lines changed

13 files changed

+254
-73
lines changed

projects/portal/src/app/services/receta.service.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { Auth } from '@andes/auth';
21
import { Server } from '@andes/shared';
32
import { Injectable } from '@angular/core';
4-
import { Observable } from 'rxjs';
3+
import * as moment from 'moment';
4+
import { forkJoin, Observable } from 'rxjs';
55
import { IProfesional } from 'src/app/interfaces/IProfesional';
66

77
@Injectable({
@@ -12,8 +12,7 @@ export class RecetaService {
1212
private url = '/modules/recetas';
1313

1414
constructor(
15-
private server: Server,
16-
private auth: Auth
15+
private server: Server
1716
) { }
1817

1918

@@ -29,6 +28,21 @@ export class RecetaService {
2928
return this.server.patch(`${this.url}`, { op: 'suspender', recetas, motivo, observacion, profesional });
3029
}
3130

31+
renovar(recetas: any[], profesional: IProfesional, organizacion: any): Observable<any[]> {
32+
const requests = recetas.map(receta => this.server.post(`${this.url}`, {
33+
idPrestacion: receta.idPrestacion,
34+
idRegistro: receta.idRegistro,
35+
idRecetaOriginal: receta,
36+
medicamento: receta.medicamento,
37+
paciente: receta.paciente,
38+
diagnostico: receta.diagnostico,
39+
profesional,
40+
organizacion
41+
}));
42+
43+
return forkJoin(requests);
44+
}
45+
3246
getUltimaReceta(recetas) {
3347
return recetas?.reduce((mostRecent, receta) => {
3448
const recetaDate = moment(receta.fechaRegistro);

src/app/modules/rup/components/core/_rup.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ $rotate: -90deg;
1717
margin-bottom: 10px;
1818
transition: 200ms all;
1919
-webkit-transition: 200ms all;
20+
overflow-x: hidden;
2021

2122
&.mini {
2223
margin-bottom: 2px;

src/app/modules/rup/components/ejecucion/hudsBusqueda.component.ts

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,31 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit {
193193
) {
194194
}
195195

196+
public mostrarRenovacion = false;
197+
public mostrarSuspension = false;
198+
199+
abrirRenovacion() {
200+
this.mostrarRenovacion = true;
201+
}
202+
203+
cerrarRenovacion() {
204+
this.mostrarRenovacion = false;
205+
}
206+
207+
cerrarSuspension() {
208+
this.mostrarSuspension = false;
209+
}
210+
211+
abrirSuspension() {
212+
this.mostrarSuspension = true;
213+
}
214+
215+
resetEstado() {
216+
this.mostrarRenovacion = false;
217+
this.mostrarSuspension = false;
218+
this.seleccionRecetas = [];
219+
}
220+
196221
/**
197222
* buscamos y listamos las prestaciones o hallazgos del paciente
198223
*
@@ -857,16 +882,6 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit {
857882
this.emitTabs(group, 'receta', 0);
858883
}
859884

860-
esRecetaSeleccionable(receta) {
861-
const estadosPermitidos = ['vigente'];
862-
const dispensasPermitidas = ['sin-dispensa', 'dispensa-parcial'];
863-
864-
const estadoValido = estadosPermitidos.includes(receta.estadoActual?.tipo);
865-
const dispensaValida = dispensasPermitidas.includes(receta.estadoDispensaActual?.tipo);
866-
867-
return estadoValido && dispensaValida && this.profesionalValido;
868-
}
869-
870885
getProfesional() {
871886
const profesionalId = this.auth.profesional;
872887

@@ -890,11 +905,32 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit {
890905
.sort((a, b) => moment(b.fechaRegistro).diff(moment(a.fechaRegistro)))[0];
891906

892907
if (isSelected) {
893-
this.seleccionRecetas[index] = true;
894-
this.seleccionSuspender.push(recetaSeleccionada);
908+
this.seleccionRecetas[index] = recetas[0];
895909
} else {
896910
this.seleccionRecetas[index] = null;
897911
this.seleccionSuspender = this.seleccionSuspender.filter(r => r.id !== recetaSeleccionada.id);
898912
}
899913
}
914+
915+
esRecetaRenovable(receta) {
916+
const fechaLimite = moment().subtract(6, 'months');
917+
const fechaRegistroValida = moment(receta.fechaRegistro).isAfter(fechaLimite);
918+
const estadoValido = receta.estadoActual?.tipo !== 'vigente' || receta.estadoDispensaActual?.tipo === 'dispensada';
919+
920+
return fechaRegistroValida && estadoValido;
921+
}
922+
923+
esRecetaSuspendible(receta) {
924+
const estadosPermitidos = ['vigente'];
925+
const dispensasPermitidas = ['sin-dispensa', 'dispensa-parcial'];
926+
927+
const estadoValido = estadosPermitidos.includes(receta.estadoActual?.tipo);
928+
const dispensaValida = dispensasPermitidas.includes(receta.estadoDispensaActual?.tipo);
929+
930+
return estadoValido && dispensaValida && this.profesionalValido;
931+
}
932+
933+
esRecetSeleccionable(receta) {
934+
return (this.mostrarRenovacion && !this.esRecetaRenovable(receta)) || (this.mostrarSuspension && !this.esRecetaSuspendible(receta));
935+
}
900936
}

src/app/modules/rup/components/ejecucion/hudsBusqueda.html

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,35 @@
2121
</div>
2222
</div>
2323
<div class="menu-titulo">
24-
<h6 class="titulo-filtro {{filtroActual}}">{{ getTitulo(filtroActual) | uppercase }}</h6>
25-
<suspender-medicacion *ngIf="filtroActual==='recetas' && seleccionRecetas.length > 0"
26-
[seleccionRecetas]="seleccionSuspender" [motivoSelector]="motivoSuspensionSelector"
27-
[motivosSuspension]="motivosSuspension" [profesional]="profesional"
28-
(reset)="resetSeleccionRecetas()"></suspender-medicacion>
24+
<ng-container>
25+
<h6 class="titulo-filtro {{filtroActual}}">
26+
<ng-container *ngIf="mostrarRenovacion">RENOVAR RECETAS</ng-container>
27+
<ng-container *ngIf="mostrarSuspension">SUSPENDER RECETAS</ng-container>
28+
<ng-container *ngIf="!mostrarRenovacion && !mostrarSuspension">{{ getTitulo(filtroActual) | uppercase
29+
}}</ng-container>
30+
</h6>
31+
</ng-container>
32+
<div class="icon-wrapper" *ngIf="filtroActual==='recetas'">
33+
<ng-container *ngIf="!mostrarRenovacion && !mostrarSuspension">
34+
<plex-button type="info" class="mr-1" icon="refresh" label="Renovar" (click)="abrirRenovacion()" size="sm">
35+
</plex-button>
36+
<plex-button type="danger" icon="stop" label="Suspender" (click)="abrirSuspension()" size="sm">
37+
</plex-button>
38+
</ng-container>
39+
<renovar-medicacion *ngIf="mostrarRenovacion" [seleccionRecetas]="seleccionRecetas"
40+
[motivoSelector]="motivoSuspensionSelector" [motivosSuspension]="motivosSuspension"
41+
[profesional]="profesional" (cerrar)="cerrarRenovacion()"
42+
(reset)="resetSeleccionRecetas()">
43+
</renovar-medicacion>
44+
<suspender-medicacion *ngIf="mostrarSuspension" [seleccionRecetas]="seleccionRecetas"
45+
[motivoSelector]="motivoSuspensionSelector" [motivosSuspension]="motivosSuspension"
46+
[profesional]="profesional" (cerrar)="cerrarSuspension()"
47+
(reset)="resetSeleccionRecetas()">
48+
</suspender-medicacion>
49+
<plex-button *ngIf="mostrarRenovacion || mostrarSuspension" type="danger" size="sm" icon="arrow-left"
50+
(click)="resetEstado()" class="ml-1" tooltip="Volver" tooltipPosition="top">
51+
</plex-button>
52+
</div>
2953
</div>
3054
<div class="grow" *ngIf="filtroActual === 'planes'">
3155
<plex-options class="filtros-ambitos" (activated)='setAmbitoOrigen($event)' [items]="filtrosAmbitos">
@@ -52,7 +76,6 @@ <h6 class="titulo-filtro {{filtroActual}}">{{ getTitulo(filtroActual) | uppercas
5276
</plex-bool>
5377
</div>
5478

55-
5679
<!-- Vista Recetas -->
5780
<ng-container *ngIf="filtroActual === 'recetas'">
5881
<plex-text [(ngModel)]="searchRecetas" name="searchRecetas" (change)="filtrarRecetas()"
@@ -62,7 +85,8 @@ <h6 class="titulo-filtro {{filtroActual}}">{{ getTitulo(filtroActual) | uppercas
6285
<ul *ngIf="busquedaRecetas.length" class="hover listado list-unstyled">
6386
<ng-container *ngFor="let grupo of busquedaRecetas; let iReceta = index">
6487
<li>
65-
<plex-bool [readonly]="!esRecetaSeleccionable(grupo?.recetas[0])"
88+
<plex-bool *ngIf="mostrarRenovacion || mostrarSuspension"
89+
[readonly]="esRecetSeleccionable(grupo?.recetas[0])"
6690
[ngModel]="seleccionRecetas[iReceta]" name="seleccionada" type="checkbox"
6791
(change)="seleccionarReceta($event, grupo.recetas, iReceta)">
6892
</plex-bool>
@@ -79,7 +103,8 @@ <h6 class="titulo-filtro {{filtroActual}}">{{ getTitulo(filtroActual) | uppercas
79103
</div>
80104
<div class="col p-0 pl-2 float-left">
81105
<div class="row p-0 m-0 titulo">
82-
{{ grupo.recetas[0].medicamento.concepto.term }}</div>
106+
{{ grupo.recetas[0].medicamento.concepto.term }}
107+
</div>
83108
<div class="row p-0 m-0">
84109
<div class="col-10 p-0 m-0">
85110
<div class="sugerido">

src/app/modules/rup/components/ejecucion/hudsBusqueda.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,11 @@
245245
display: flex;
246246
align-items: center;
247247
justify-content: space-between;
248+
249+
.icon-wrapper {
250+
display: flex;
251+
margin-bottom: 5px;
252+
}
248253
}
249254

250255
.titulo-filtro {

src/app/modules/rup/components/ejecucion/prestacionEjecucion.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ export class PrestacionEjecucionComponent implements OnInit, OnDestroy {
516516
}
517517

518518
const esAsociado = this.prestacion.ejecucion.registros.some(r =>
519-
r.valor?.medicamentos?.length && r.valor.medicamentos.some(m => m.diagnostico.conceptId === registro.concepto.conceptId)
519+
r.valor?.medicamentos?.length && r.valor.medicamentos.some(m => m.diagnostico?.conceptId === registro.concepto?.conceptId)
520520
);
521521

522522
return !esAsociado;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<plex-button *ngIf="!seleccionRecetas.length" type="success" icon="check" size="sm" tooltip="Renovar"
2+
tooltipPosition="left" disabled="true">
3+
</plex-button>
4+
5+
<plex-help *ngIf="seleccionRecetas.length" size="sm" class="ml-2" btnType="success" icon="check" tooltip="Renovar"
6+
tooltipPosition="left">
7+
<plex-title titulo="Renovar Medicamento" size="sm">
8+
<plex-button type="success" icon="check" size="sm" tooltip="Confirmar" tooltipPosition="left"
9+
(click)="renovarMedicacion()">
10+
</plex-button>
11+
</plex-title>
12+
13+
<table class="table">
14+
<thead>
15+
<tr>
16+
<th>Indicacion</th>
17+
<th>Profesional</th>
18+
</tr>
19+
</thead>
20+
<tbody>
21+
<tr *ngFor="let receta of seleccionRecetas" [style.display]="receta ? 'table-row' : 'none'">
22+
<td>{{ receta?.medicamento.concepto.term }}</td>
23+
<td>{{ receta?.profesional.nombre }} {{ receta?.profesional.apellido }}
24+
</tr>
25+
</tbody>
26+
</table>
27+
<plex-label *ngIf="!seleccionRecetas?.length" titulo="No hay recetas seleccionadas">
28+
</plex-label>
29+
</plex-help>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Auth } from '@andes/auth';
2+
import { Plex } from '@andes/plex';
3+
import { Component, EventEmitter, Input, Output } from '@angular/core';
4+
import { RecetaService } from 'projects/portal/src/app/services/receta.service';
5+
6+
@Component({
7+
selector: 'renovar-medicacion',
8+
templateUrl: 'renovarMedicacion.html',
9+
})
10+
11+
export class RenovarMedicacionComponent {
12+
constructor(
13+
public plex: Plex,
14+
private recetasService: RecetaService,
15+
private auth: Auth,
16+
) { }
17+
18+
@Input() seleccionRecetas: any[];
19+
@Input() profesional: any;
20+
21+
@Output() reset: EventEmitter<any> = new EventEmitter<any>();
22+
@Output() cerrar: EventEmitter<any> = new EventEmitter<any>();
23+
24+
public renovarMedicacion() {
25+
const organizacion = { id: this.auth.organizacion.id, nombre: this.auth.organizacion.nombre };
26+
const recetaIds = this.seleccionRecetas
27+
.filter(receta => receta !== null);
28+
29+
this.recetasService.renovar(recetaIds, this.profesional, organizacion).subscribe({
30+
next: () => {
31+
this.reset.emit();
32+
this.cerrar.emit();
33+
this.plex.toast('success', 'Medicaciones renovadas correctamente');
34+
},
35+
error: () => {
36+
this.plex.toast('danger', 'Error al renovar las medicaciones');
37+
}
38+
});
39+
}
40+
}

src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.html

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
<plex-help size="sm" class="ml-2" btnType="danger" icon="stop" tooltip="Suspender" tooltipPosition="left">
1+
<plex-button *ngIf="!seleccionRecetas.length" type="success" icon="check" size="sm" tooltip="Suspender"
2+
tooltipPosition="left" disabled="true">
3+
</plex-button>
4+
5+
<plex-help *ngIf="seleccionRecetas.length" size="sm" class="ml-2" btnType="success" icon="check" tooltip="Suspender"
6+
tooltipPosition="left">
27
<plex-title titulo="Suspender Medicamento" size="sm">
38
<plex-button type="success" icon="check" size="sm" tooltip="Confirmar" tooltipPosition="left"
49
[disabled]="!formSuspension.valid" (click)="suspenderMedicacion()">
@@ -25,8 +30,8 @@
2530
<plex-select label="Motivo de suspensión" name="motivo" [(ngModel)]="motivoSelector" [data]="motivosSuspension"
2631
required>
2732
</plex-select>
28-
<plex-text label="Observación" name="observacion" [(ngModel)]="observacion" placeholder="Ingrese una observación"
29-
[required]="motivoSelector?.nombre === 'Otro'">
33+
<plex-text label="Observación" name="observacion" [(ngModel)]="observacion"
34+
placeholder="Ingrese una observación" [required]="motivoSelector?.nombre === 'Otro'">
3035
</plex-text>
3136
</form>
3237
</plex-help>

src/app/modules/rup/components/ejecucion/recetas/suspenderMedicacion.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,26 @@ export class SuspenderMedicacionComponent {
1919
@Input() profesional: any;
2020

2121
@Output() reset: EventEmitter<any> = new EventEmitter<any>();
22+
@Output() cerrar: EventEmitter<any> = new EventEmitter<any>();
2223

2324
public motivoSelector: any;
2425
public observacion: string;
2526

2627
public suspenderMedicacion() {
27-
const medicamento = this.seleccionRecetas[0]?.medicamento.concepto.term;
28-
this.plex.confirm(`¿Está seguro que desea suspender ${this.seleccionRecetas.length > 1 ? `las (${this.seleccionRecetas.length}) medicaciones seleccionadas` : `<br><b>"${medicamento}"</b>`}?`, 'Atención').then(confirmacion => {
29-
if (confirmacion) {
30-
const recetaIds = this.seleccionRecetas.map(receta => receta.id);
31-
this.recetasService.suspender(recetaIds, this.profesional, this.motivoSelector.nombre, this.observacion).subscribe({
32-
next: () => {
33-
this.reset.emit();
34-
this.plex.toast('success', 'Medicaciones suspendidas correctamente');
35-
},
36-
error: () => {
37-
this.plex.toast('danger', 'Error al suspender las medicaciones');
38-
}
39-
});
28+
const recetaIds = this.seleccionRecetas
29+
.filter(receta => receta !== null)
30+
.map(({ id }) => id);
31+
32+
this.recetasService.suspender(recetaIds, this.profesional, this.motivoSelector.nombre, this.observacion).subscribe({
33+
next: () => {
34+
this.reset.emit();
35+
this.cerrar.emit();
36+
this.plex.toast('success', 'Medicaciones suspendidas correctamente');
37+
},
38+
error: () => {
39+
this.plex.toast('danger', 'Error al suspender las medicaciones');
4040
}
4141
});
42+
4243
}
4344
}

0 commit comments

Comments
 (0)