From 2f0c5fe875dba4c0abacffe6037c703461d468a9 Mon Sep 17 00:00:00 2001 From: silviroa Date: Thu, 5 Mar 2026 12:05:48 -0300 Subject: [PATCH 1/4] fix(RUP): Agrega campo esSolicitud en elementoRupRequerido --- src/app/modules/rup/interfaces/elementoRUP.interface.ts | 1 + src/app/modules/rup/services/elementosRUP.service.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/app/modules/rup/interfaces/elementoRUP.interface.ts b/src/app/modules/rup/interfaces/elementoRUP.interface.ts index 555286aea8..7068b57fc9 100644 --- a/src/app/modules/rup/interfaces/elementoRUP.interface.ts +++ b/src/app/modules/rup/interfaces/elementoRUP.interface.ts @@ -65,5 +65,6 @@ export interface IElementoRUPRequeridos { }; // Indica parámetros para la instancia del elementoRUP en formato {key: value} params: { [key: string]: any }; + esSolicitud?: boolean; sexo: string; } diff --git a/src/app/modules/rup/services/elementosRUP.service.ts b/src/app/modules/rup/services/elementosRUP.service.ts index 6d673518dd..3153669f57 100644 --- a/src/app/modules/rup/services/elementosRUP.service.ts +++ b/src/app/modules/rup/services/elementosRUP.service.ts @@ -183,6 +183,7 @@ export class ElementosRUPService { } elemento.requeridos.forEach((elem) => { if (!elem.elementoRUP) { + esSolicitud = elem.esSolicitud ?? esSolicitud; elem.elementoRUP = this.buscarElemento(elem.concepto, esSolicitud); elem.params = { ...elem.elementoRUP.params, ...(elem.params || {}) }; elem.style = { ...(elem.elementoRUP.style || {}), ...(elem.style || {}) } as any; From 83480a27735774bc166c5989ed846616f8d04705 Mon Sep 17 00:00:00 2001 From: silviroa Date: Thu, 5 Mar 2026 15:23:24 -0300 Subject: [PATCH 2/4] fix(RUP): Agrega dato de organizacion destino a molecula base cuando se trata de un registro de solicitud --- .../elementos/moleculaBase.component.ts | 53 +++++++++++++++++++ .../components/elementos/moleculaBase.html | 25 +++++++++ 2 files changed, 78 insertions(+) diff --git a/src/app/modules/rup/components/elementos/moleculaBase.component.ts b/src/app/modules/rup/components/elementos/moleculaBase.component.ts index 031d020615..8c3d6918ca 100644 --- a/src/app/modules/rup/components/elementos/moleculaBase.component.ts +++ b/src/app/modules/rup/components/elementos/moleculaBase.component.ts @@ -17,6 +17,9 @@ export class MoleculaBaseComponent extends RUPComponent implements OnInit { ]; public consultaTrastornoOriginal: any; public evoluciones; + public organizaciones: any[] = []; + public reglasMatch = []; + public reglaSelected = null; ngOnInit() { if (this.registro.concepto.semanticTag === 'trastorno') { @@ -67,6 +70,56 @@ export class MoleculaBaseComponent extends RUPComponent implements OnInit { this.contentLoaded = true; } this.createRules(); + + if (this.elementoRUP.esSolicitud) { + + if (!this.registro.valor) { + this.registro.valor = { + solicitudPrestacion: {} + }; + this.registro.valor.solicitudPrestacion['autocitado'] = false; + this.registro.valor.solicitudPrestacion['prestacionSolicitada'] = this.registro.concepto; + } + + this.servicioReglas.get({ + organizacionOrigen: this.auth.organizacion.id, + prestacionOrigen: this.prestacion?.solicitud?.tipoPrestacion.conceptId, + prestacionDestino: this.registro.concepto?.conceptId + }).subscribe(reglas => { + this.reglasMatch = reglas; + this.organizaciones = reglas.map(elem => { + return { + id: elem.destino.organizacion.id, + nombre: elem.destino.organizacion.nombre + }; + }); + + if (this.organizaciones.length === 1) { + this.registro.valor.solicitudPrestacion.organizacionDestino = this.organizaciones[0]; + this.onOrganizacionChange(); + } + }); + } + } + + onOrganizacionChange() { + const org = this.registro.valor.solicitudPrestacion.organizacionDestino; + if (org) { + this.reglaSelected = this.reglasMatch.find(r => r.destino.organizacion.id === org.id); + + if (this.reglaSelected) { + this.reglaSelected.destino.informe = this.reglaSelected.destino.informe || 'none'; + + if (this.reglaSelected.destino.informe === 'required') { + this.registro.valor.solicitudPrestacion.informe = true; + } + + this.registro.valor.solicitudPrestacion.reglaID = this.reglaSelected.id; + if (this.reglaSelected.destino.formulario) { + this.registro.valor.template = this.reglaSelected.destino.formulario; + } + } + } } onChange(value) { diff --git a/src/app/modules/rup/components/elementos/moleculaBase.html b/src/app/modules/rup/components/elementos/moleculaBase.html index e2417ceb81..fbf5bb88d1 100644 --- a/src/app/modules/rup/components/elementos/moleculaBase.html +++ b/src/app/modules/rup/components/elementos/moleculaBase.html @@ -55,4 +55,29 @@ + +
+
+
+
+
+
+
+ + + +
+
+
+
+ +
+
+
\ No newline at end of file From cc2511166009167992c0873ec2290678498622a0 Mon Sep 17 00:00:00 2001 From: silviroa Date: Tue, 10 Mar 2026 15:17:48 -0300 Subject: [PATCH 3/4] fix(TOP): Visulizar el detalle de una molecula-solicitud en bandejas TOP --- .../solicitudes/detallePedido.component.ts | 67 +++++++++++++++++++ .../top/solicitudes/detallePedido.html | 9 +++ .../solicitudes/detalleSolicitud.component.ts | 32 +++++++-- .../top/solicitudes/detalleSolicitud.html | 10 ++- src/app/components/top/top.module.ts | 12 +++- .../rup/components/elementos/ultimaFecha.html | 12 +++- 6 files changed, 126 insertions(+), 16 deletions(-) create mode 100644 src/app/components/top/solicitudes/detallePedido.component.ts create mode 100644 src/app/components/top/solicitudes/detallePedido.html diff --git a/src/app/components/top/solicitudes/detallePedido.component.ts b/src/app/components/top/solicitudes/detallePedido.component.ts new file mode 100644 index 0000000000..32df668e71 --- /dev/null +++ b/src/app/components/top/solicitudes/detallePedido.component.ts @@ -0,0 +1,67 @@ +import { Input, Component, ChangeDetectorRef, OnDestroy, ViewChild } from '@angular/core'; +import { Subject } from 'rxjs'; +import { filter, take, takeUntil } from 'rxjs/operators'; +import { RUPComponent } from 'src/app/modules/rup/components/core/rup.component'; +import { ElementosRUPService } from 'src/app/modules/rup/services/elementosRUP.service'; + +@Component({ + selector: 'detalle-pedido', + templateUrl: './detallePedido.html' +}) + +export class DetallePedidoComponent implements OnDestroy { + @ViewChild('prescripcion') prescripcion: RUPComponent; + turno; + prestacion; + itemsHistorial = []; + registroPrincipal = null; + elementoRUPPrincipal = null; + private destroy$ = new Subject(); + + @Input('prestacion') + set _prestacion(value) { + this.prestacion = value; + this.cargarDetalle(); + } + + constructor( + private elementosRUPService: ElementosRUPService, + private cd: ChangeDetectorRef + ) { } + + + cargarDetalle() { + if (!this.prestacion) { return; } + + // Esperar a que el servicio esté listo y luego usarlo (una sola vez) + this.elementosRUPService.ready.pipe( + filter(v => !!v), + take(1), + takeUntil(this.destroy$) + ).subscribe({ + next: () => { + try { + this.registroPrincipal = this.prestacion.solicitud?.registros?.[0] || null; + if (!this.registroPrincipal) { + console.warn('DetallePedido: no hay registroPrincipal en la prestacion', this.prestacion); + this.elementoRUPPrincipal = null; + this.cd.detectChanges(); + return; + } + this.elementoRUPPrincipal = this.elementosRUPService.buscarElemento(this.registroPrincipal.concepto, true); + // Forzar detección para que Angular renderice el + this.cd.detectChanges(); + } catch (err) { + console.error('DetallePedido: error al cargar elementoRUPPrincipal', err); + } + }, + error: (err) => console.error('DetallePedido: error en ready', err) + }); + + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } +} \ No newline at end of file diff --git a/src/app/components/top/solicitudes/detallePedido.html b/src/app/components/top/solicitudes/detallePedido.html new file mode 100644 index 0000000000..a41a38bdde --- /dev/null +++ b/src/app/components/top/solicitudes/detallePedido.html @@ -0,0 +1,9 @@ +
+
+
+ + +
+
+
\ No newline at end of file diff --git a/src/app/components/top/solicitudes/detalleSolicitud.component.ts b/src/app/components/top/solicitudes/detalleSolicitud.component.ts index 5e9d8e6c63..70ad360240 100644 --- a/src/app/components/top/solicitudes/detalleSolicitud.component.ts +++ b/src/app/components/top/solicitudes/detalleSolicitud.component.ts @@ -1,6 +1,7 @@ import { Input, Component, SimpleChanges, OnChanges, OnDestroy, Output, EventEmitter } from '@angular/core'; import { AdjuntosService } from '../../../modules/rup/services/adjuntos.service'; import { PacienteService } from 'src/app/core/mpi/services/paciente.service'; +import { Auth } from '@andes/auth'; @Component({ selector: 'detalle-solicitud', @@ -20,24 +21,23 @@ export class DetalleSolicitudComponent implements OnChanges, OnDestroy { public internacion = null; public organizacionInternacion; + public permisoDetalle = false; + + public items = []; - public items = [ - { key: 'solicitud', label: 'SOLICITUD' }, - { key: 'historial', label: 'HISTORIAL' }, - { key: 'turnos', label: 'TURNOS' } - ]; public mostrar = 'solicitud'; public verIndicaciones = false; constructor( public adjuntosService: AdjuntosService, - private pacienteService: PacienteService + private pacienteService: PacienteService, + private auth: Auth ) { } fotos: any[] = []; - ngOnChanges(changes: SimpleChanges) { if (changes.prestacionSeleccionada) { + this.permisoDetalle = this.auth.check('solicitudes:verDetalles'); this.adjuntosService.token$.subscribe((payload) => { const { token } = payload; const solicitudRegistros = this.prestacionSeleccionada.solicitud.registros; @@ -58,9 +58,27 @@ export class DetalleSolicitudComponent implements OnChanges, OnDestroy { this.internacionPaciente.emit(this.internacion); }); } + this.buildItems(); + } + } + + private buildItems() { + const base = [ + { key: 'solicitud', label: 'SOLICITUD' }, + { key: 'historial', label: 'HISTORIAL' }, + { key: 'turnos', label: 'TURNOS' } + ]; + + // Ejemplo de condición: agregar 'turnos' solo si se cumple permisoDetalle + // o si el tipo de solicitud es un valor específico. Ajusta aquí. + if (this.permisoDetalle) { + base.splice(1, 0, { key: 'pedido', label: 'PEDIDO' }); } + + this.items = base; } + cambiarOpcion(opcion) { this.mostrar = opcion; } diff --git a/src/app/components/top/solicitudes/detalleSolicitud.html b/src/app/components/top/solicitudes/detalleSolicitud.html index edae79dad1..bd686757c9 100644 --- a/src/app/components/top/solicitudes/detalleSolicitud.html +++ b/src/app/components/top/solicitudes/detalleSolicitud.html @@ -1,5 +1,5 @@ -
+
@@ -106,11 +106,15 @@
-
+
+ + +
+
-
+
\ No newline at end of file diff --git a/src/app/components/top/top.module.ts b/src/app/components/top/top.module.ts index 09795f4cad..94ad0835b4 100644 --- a/src/app/components/top/top.module.ts +++ b/src/app/components/top/top.module.ts @@ -14,13 +14,16 @@ import { TurnosSolicitudComponent } from './solicitudes/turnosSolicitud.componen import { VisualizacionReglasTopComponent } from './reglas/visualizacionReglasTop.component'; import { RouterService } from 'src/app/services/router.service'; import { MotivosHudsService } from 'src/app/services/motivosHuds.service'; +import { DetallePedidoComponent } from './solicitudes/detallePedido.component'; +import { ElementosRUPModule } from 'src/app/modules/rup/elementos-rup.module'; export const TOP_COMPONENTS = [ VisualizacionReglasTopComponent, VisualizacionReglasComponent, HistorialSolicitudComponent, FormNuevaSolicitudComponent, - TurnosSolicitudComponent + TurnosSolicitudComponent, + DetallePedidoComponent ]; export const TOP_PROVIDERS = [ @@ -35,13 +38,15 @@ export const TOP_PROVIDERS = [ RouterModule, HttpClientModule, SharedModule, - DirectiveLibModule + DirectiveLibModule, + ElementosRUPModule ], declarations: [ ...TOP_COMPONENTS ], providers: [ MotivosHudsService, + ...TOP_PROVIDERS ], exports: [ @@ -49,7 +54,8 @@ export const TOP_PROVIDERS = [ VisualizacionReglasComponent, HistorialSolicitudComponent, FormNuevaSolicitudComponent, - TurnosSolicitudComponent + TurnosSolicitudComponent, + DetallePedidoComponent ], }) export class TOPLibModule { diff --git a/src/app/modules/rup/components/elementos/ultimaFecha.html b/src/app/modules/rup/components/elementos/ultimaFecha.html index 14ce75af60..dc083288d6 100644 --- a/src/app/modules/rup/components/elementos/ultimaFecha.html +++ b/src/app/modules/rup/components/elementos/ultimaFecha.html @@ -4,9 +4,15 @@ -

- {{registro.concepto.term}} {{DateFormat}} -

+ +
+ +
+ + + + {{DateFormat}} +

{{registro.concepto.term}} sin valor

From 0804038472513fbc7dd6e81411233523e62e0d1c Mon Sep 17 00:00:00 2001 From: silviroa Date: Thu, 12 Mar 2026 10:04:55 -0300 Subject: [PATCH 4/4] feat(TOP): Agrega visualizacion de molecula para una solicitud --- projects/auth/src/lib/auth.service.ts | 11 +++++ .../solicitudes/detallePedido.component.ts | 46 ++++++++++++------- .../top/solicitudes/detallePedido.html | 2 +- .../solicitudes/detalleSolicitud.component.ts | 2 +- .../components/elementos/moleculaBase.html | 6 +-- .../elementos/rupers/select-base.component.ts | 7 +++ 6 files changed, 52 insertions(+), 22 deletions(-) diff --git a/projects/auth/src/lib/auth.service.ts b/projects/auth/src/lib/auth.service.ts index d12c06a6e8..a22b930448 100644 --- a/projects/auth/src/lib/auth.service.ts +++ b/projects/auth/src/lib/auth.service.ts @@ -120,6 +120,17 @@ export class Auth { return this.shiro.permissions(string); } + hasExactPermission(perm: string): boolean { + const parts = perm.split(':'); + const last = parts.pop(); + + const query = [...parts, '?'].join(':'); + const perms = this.shiro.permissions(query); + + return perms.includes(last); + + } + loggedIn() { return this.estado === Estado.active; } diff --git a/src/app/components/top/solicitudes/detallePedido.component.ts b/src/app/components/top/solicitudes/detallePedido.component.ts index 32df668e71..a0c58bff46 100644 --- a/src/app/components/top/solicitudes/detallePedido.component.ts +++ b/src/app/components/top/solicitudes/detallePedido.component.ts @@ -16,6 +16,7 @@ export class DetallePedidoComponent implements OnDestroy { itemsHistorial = []; registroPrincipal = null; elementoRUPPrincipal = null; + mostrarRup = true; private destroy$ = new Subject(); @Input('prestacion') @@ -31,7 +32,20 @@ export class DetallePedidoComponent implements OnDestroy { cargarDetalle() { - if (!this.prestacion) { return; } + if (!this.prestacion) { + // Si no hay prestacion, ocultamos para que no quede el anterior montado + this.mostrarRup = false; + this.elementoRUPPrincipal = null; + this.registroPrincipal = null; + this.cd.detectChanges(); + return; + } + + // Forzamos desmontaje temporal del para evitar que quede la instancia anterior + this.mostrarRup = false; + this.elementoRUPPrincipal = null; + this.registroPrincipal = null; + this.cd.detectChanges(); // Esperar a que el servicio esté listo y luego usarlo (una sola vez) this.elementosRUPService.ready.pipe( @@ -40,22 +54,22 @@ export class DetallePedidoComponent implements OnDestroy { takeUntil(this.destroy$) ).subscribe({ next: () => { - try { - this.registroPrincipal = this.prestacion.solicitud?.registros?.[0] || null; - if (!this.registroPrincipal) { - console.warn('DetallePedido: no hay registroPrincipal en la prestacion', this.prestacion); - this.elementoRUPPrincipal = null; - this.cd.detectChanges(); - return; - } - this.elementoRUPPrincipal = this.elementosRUPService.buscarElemento(this.registroPrincipal.concepto, true); - // Forzar detección para que Angular renderice el + this.registroPrincipal = this.prestacion.solicitud?.registros?.[0] || null; + if (!this.registroPrincipal) { + console.warn('DetallePedido: no hay registroPrincipal en la prestacion', this.prestacion); + this.elementoRUPPrincipal = null; + // restaurar flag (no mostrar) + this.mostrarRup = false; this.cd.detectChanges(); - } catch (err) { - console.error('DetallePedido: error al cargar elementoRUPPrincipal', err); + return; } - }, - error: (err) => console.error('DetallePedido: error en ready', err) + this.elementoRUPPrincipal = this.elementosRUPService.buscarElemento(this.registroPrincipal.concepto, true); + // Restauramos flag para volver a montar con los nuevos inputs + this.mostrarRup = true; + // Forzar detección para que Angular renderice el + this.cd.detectChanges(); + + } }); } @@ -64,4 +78,4 @@ export class DetallePedidoComponent implements OnDestroy { this.destroy$.next(); this.destroy$.complete(); } -} \ No newline at end of file +} diff --git a/src/app/components/top/solicitudes/detallePedido.html b/src/app/components/top/solicitudes/detallePedido.html index a41a38bdde..768912c913 100644 --- a/src/app/components/top/solicitudes/detallePedido.html +++ b/src/app/components/top/solicitudes/detallePedido.html @@ -2,7 +2,7 @@
+ [prestacion]="prestacion" [paciente]="prestacion.paciente" [soloValores]="true" [vistaHUDS]="false">
diff --git a/src/app/components/top/solicitudes/detalleSolicitud.component.ts b/src/app/components/top/solicitudes/detalleSolicitud.component.ts index 70ad360240..eb3dc9c240 100644 --- a/src/app/components/top/solicitudes/detalleSolicitud.component.ts +++ b/src/app/components/top/solicitudes/detalleSolicitud.component.ts @@ -37,7 +37,7 @@ export class DetalleSolicitudComponent implements OnChanges, OnDestroy { fotos: any[] = []; ngOnChanges(changes: SimpleChanges) { if (changes.prestacionSeleccionada) { - this.permisoDetalle = this.auth.check('solicitudes:verDetalles'); + this.permisoDetalle = this.auth.hasExactPermission('solicitudes:verDetalles'); this.adjuntosService.token$.subscribe((payload) => { const { token } = payload; const solicitudRegistros = this.prestacionSeleccionada.solicitud.registros; diff --git a/src/app/modules/rup/components/elementos/moleculaBase.html b/src/app/modules/rup/components/elementos/moleculaBase.html index fbf5bb88d1..621e0c0d1e 100644 --- a/src/app/modules/rup/components/elementos/moleculaBase.html +++ b/src/app/modules/rup/components/elementos/moleculaBase.html @@ -69,13 +69,11 @@ placeholder="Seleccione la organización" labelField="nombre" [required]="true" (change)="onOrganizacionChange()"> -
-
+
-
diff --git a/src/app/modules/rup/components/elementos/rupers/select-base.component.ts b/src/app/modules/rup/components/elementos/rupers/select-base.component.ts index a5751bf09b..e183dc3190 100644 --- a/src/app/modules/rup/components/elementos/rupers/select-base.component.ts +++ b/src/app/modules/rup/components/elementos/rupers/select-base.component.ts @@ -61,7 +61,14 @@ export class SelectBaseComponent extends RUPComponent implements OnInit, AfterVi this.params = {}; } if (this.registro && this.registro.valor) { + const value = this.registro.valor; + + if (!value || (Array.isArray(value) && value.length === 0)) { + this.otherEnabled = true; + this.otherText = 'S/D'; + } + if (Array.isArray(value)) { this.itemSelected = value; } else {