diff --git a/src/app/apps/rup/mapa-camas/mapa-camas.module.ts b/src/app/apps/rup/mapa-camas/mapa-camas.module.ts index 9066429f6e..c051ff9291 100644 --- a/src/app/apps/rup/mapa-camas/mapa-camas.module.ts +++ b/src/app/apps/rup/mapa-camas/mapa-camas.module.ts @@ -70,6 +70,7 @@ import { IngresoPacienteService } from './sidebar/ingreso/ingreso-paciente-workf import { PeriodosCensablesComponent } from './sidebar/periodos-censables/periodos-censables.component'; import { ListadoMedicamentosCapasComponent } from './views/listado-internacion-capas/listado-medicamentos-capas.component'; import { CITASLibModule } from '../../../components/turnos/citas.module'; +import { InformeEstadisticaService } from 'src/app/modules/rup/services/informe-estadistica.service'; export const INTERNACION_COMPONENTS = [ MapaCamasMainComponent, @@ -128,7 +129,8 @@ export const INTERNACION_PROVIDERS = [ IntegridadService, PermisosMapaCamasService, PlanIndicacionesEventosServices, - IngresoPacienteService + IngresoPacienteService, + InformeEstadisticaService ]; @NgModule({ diff --git a/src/app/apps/rup/mapa-camas/services/mapa-camas.http.ts b/src/app/apps/rup/mapa-camas/services/mapa-camas.http.ts index e1590ddb4c..6b0be4196b 100644 --- a/src/app/apps/rup/mapa-camas/services/mapa-camas.http.ts +++ b/src/app/apps/rup/mapa-camas/services/mapa-camas.http.ts @@ -1,6 +1,7 @@ +/* eslint-disable no-console */ import { Injectable } from '@angular/core'; import { Server } from '@andes/shared'; -import { Observable } from 'rxjs'; +import { Observable, tap } from 'rxjs'; import { ISnapshot } from '../interfaces/ISnapshot'; import { ICama } from '../interfaces/ICama'; @@ -117,6 +118,12 @@ export class MapaCamasHTTP { } censoDiario(fecha: Date, unidadOrganizativa: string): Observable { + console.log('🌐 [MapaCamasHTTP] Request a censo-diario →', { + url: `${this.url}/censo-diario`, + fecha, + unidadOrganizativa + }); + return this.server.get(`${this.url}/censo-diario`, { params: { fecha, unidadOrganizativa }, showError: true @@ -135,6 +142,6 @@ export class MapaCamasHTTP { } getPrestacionesInternacion(params: any): Observable { - return this.server.get(`${this.url}/prestaciones`, { params: params, showError: true }); + return this.server.get(`${this.url}/informe-estadistica`, { params: params, showError: true }); } } diff --git a/src/app/apps/rup/mapa-camas/services/mapa-camas.service.ts b/src/app/apps/rup/mapa-camas/services/mapa-camas.service.ts index 7d8ef76131..6faac64ec9 100644 --- a/src/app/apps/rup/mapa-camas/services/mapa-camas.service.ts +++ b/src/app/apps/rup/mapa-camas/services/mapa-camas.service.ts @@ -2,7 +2,7 @@ import { Auth } from '@andes/auth'; import { cache, notNull } from '@andes/shared'; import { Injectable } from '@angular/core'; import { BehaviorSubject, combineLatest, Observable, of, timer } from 'rxjs'; -import { catchError, map, multicast, pluck, startWith, switchMap } from 'rxjs/operators'; +import { catchError, map, multicast, pluck, startWith, switchMap, tap } from 'rxjs/operators'; import { IPaciente } from '../../../../core/mpi/interfaces/IPaciente'; import { PacienteService } from '../../../../core/mpi/services/paciente.service'; import { ISectores } from '../../../../interfaces/IOrganizacion'; @@ -18,6 +18,8 @@ import { MapaCamasHTTP } from './mapa-camas.http'; import { MaquinaEstadosHTTP } from './maquina-estados.http'; import { InternacionResumenHTTP, IResumenInternacion } from './resumen-internacion.http'; import { PermisosMapaCamasService } from '../services/permisos-mapa-camas.service'; +import { InformeEstadisticaService } from 'src/app/modules/rup/services/informe-estadistica.service'; +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; @Injectable() export class MapaCamasService { public timer$; @@ -45,7 +47,11 @@ export class MapaCamasService { public view = new BehaviorSubject<'mapa-camas' | 'listado-internacion' | 'mapa-recursos'>('mapa-camas'); public prestacion$: Observable; + public informeEstadistica$: Observable; + public selectedPrestacion = new BehaviorSubject({ id: null } as any); + public selectedInformeEstadistica = new BehaviorSubject({ id: null } as any); + public camaSelectedSegunView$: Observable; public maquinaDeEstado$: Observable; @@ -80,6 +86,7 @@ export class MapaCamasService { constructor( private camasHTTP: MapaCamasHTTP, private prestacionService: PrestacionesService, + private informeEstadisticaService: InformeEstadisticaService, private pacienteService: PacienteService, private maquinaEstadosHTTP: MaquinaEstadosHTTP, private salaComunService: SalaComunService, @@ -135,6 +142,11 @@ export class MapaCamasService { snap.diaEstada = 0; } }); + // 👉 Aquí detectamos los casos sin sectores + const sinSectores = snapshot.filter(s => !s.sectores || s.sectores.length === 0); + if (sinSectores.length > 0) { + console.warn('⚠️ Snapshots sin sectores:', sinSectores.map(s => s.id)); + } return snapshot.sort((a, b) => (a.unidadOrganizativa.term.localeCompare(b.unidadOrganizativa.term)) || (a.sectores[a.sectores.length - 1].nombre.localeCompare(b.sectores[b.sectores.length - 1].nombre + '')) || (a.nombre.localeCompare('' + b.nombre))); @@ -188,7 +200,7 @@ export class MapaCamasService { return of(null); } if (capa === 'estadistica') { - return this.prestacionService.getById(cama.idInternacion, { showError: false }); + return of(null); } return this.internacionResumenHTTP.get(cama.idInternacion).pipe( switchMap(internacionResumen => { @@ -203,6 +215,7 @@ export class MapaCamasService { cache() ); + this.resumenInternacion$ = combineLatest([ this.selectedCama, this.ambito2, @@ -223,6 +236,50 @@ export class MapaCamasService { cache() ) as Observable; + this.informeEstadistica$ = combineLatest([ + this.selectedInformeEstadistica, + this.selectedCama, + this.view, + this.capa2 + ]).pipe( + switchMap(([informe, cama, view, capa]) => { + + if (view === 'listado-internacion') { + if (informe?.id) { + return of(informe); + } + + const pacienteId = cama?.paciente?.id; + if (pacienteId) { + return this.informeEstadisticaService.get({ paciente: pacienteId }).pipe( + map(informes => informes?.[0] || null) + ); + } + + return of(null); + } + + if (!cama?.idInternacion) { + return of(null); + } + + if (capa === 'estadistica') { + const id = informe?.id || cama?.idInternacion; + if (!id) { + console.warn('⚠️ No hay ID válido para obtener el informe estadístico'); + return of(null); + } + return this.informeEstadisticaService.getById(id, { showError: false }); + } + + return of(null); + }), + catchError(err => { + return of(null); + }), + cache() + ); + this.camaSelectedSegunView$ = this.view.pipe( switchMap(view => { @@ -231,7 +288,7 @@ export class MapaCamasService { } // Para conseguir la cama de la internación desde el listado return combineLatest([ - this.selectedPrestacion, + this.selectedInformeEstadistica, this.selectedResumen ]).pipe( switchMap(([prestacion, resumen]) => { @@ -379,6 +436,16 @@ export class MapaCamasService { this.selectedPrestacion.next(prestacion); } + selectInformeEstadistica(informe: IInformeEstadistica) { + if (!informe) { + return this.selectedInformeEstadistica.next({ id: null } as any); + } + + this.selectedInformeEstadistica.next(informe); + + } + + selectResumen(resumen: IResumenInternacion) { if (!resumen) { return this.selectedResumen.next({ id: null } as any); @@ -396,8 +463,8 @@ export class MapaCamasService { camasFiltradas = camasFiltradas.filter((snap: ISnapshot) => snap.paciente.documento.includes(paciente) || snap.paciente.numeroIdentificacion?.includes(paciente)); } else { - camasFiltradas = camasFiltradas.filter((snap: ISnapshot) => - (snap.paciente.nombre.toLowerCase().includes(paciente.toLowerCase()) || + camasFiltradas = camasFiltradas.filter((snap: ISnapshot) => ( + snap.paciente.nombre.toLowerCase().includes(paciente.toLowerCase()) || snap.paciente.alias?.toLowerCase().includes(paciente.toLowerCase()) || snap.paciente.apellido.toLowerCase().includes(paciente.toLowerCase())) ); @@ -526,6 +593,38 @@ export class MapaCamasService { return listaInternacionFiltrada; } + filtrarInformesEstadistica( + listaInformes: IInformeEstadistica[], + documento?: string, + apellido?: string, + estado?: string + ): IInformeEstadistica[] { + let listaFiltrada = listaInformes; + + if (documento) { + const doc = documento.toLowerCase(); + listaFiltrada = listaFiltrada.filter((informe: IInformeEstadistica) => + informe.paciente?.documento?.toLowerCase().includes(doc) || + informe.paciente?.numeroIdentificacion?.toLowerCase().includes(doc) + ); + } + + if (apellido) { + const ape = apellido.toLowerCase(); + listaFiltrada = listaFiltrada.filter((informe: IInformeEstadistica) => + informe.paciente?.apellido?.toLowerCase().includes(ape) + ); + } + + if (estado) { + listaFiltrada = listaFiltrada.filter((informe: IInformeEstadistica) => + informe.estadoActual?.tipo === estado + ); + } + + return listaFiltrada; + } + snapshot(fecha, idInternacion = null, ambito: string = null, capa: string = null, estado: string = null): Observable { ambito = ambito || this.ambito; capa = capa || this.capa; @@ -541,11 +640,11 @@ export class MapaCamasService { this.ambito2, this.capa2, this.selectedCama, - this.selectedPrestacion, + this.selectedInformeEstadistica, this.selectedResumen, this.view ]).pipe( - switchMap(([ambito, capa, selectedCama, selectedPrestacion, selectedResumen, view]) => { + switchMap(([ambito, capa, selectedCama, selectedInformeEstadistica, selectedResumen, view]) => { hasta = hasta || new Date(); if (type === 'cama') { return this.camasHTTP.historial(ambito, capa, desde, hasta, { idCama: cama ? cama.idCama : selectedCama.idCama }); @@ -556,11 +655,13 @@ export class MapaCamasService { } else if (view === 'listado-internacion') { if (!desde) { - desde = selectedPrestacion ? selectedPrestacion.solicitud.fecha : selectedResumen.fechaIngreso; + desde = selectedInformeEstadistica ? selectedInformeEstadistica.informeIngreso.fechaIngreso : selectedResumen.fechaIngreso; + } - if (this.capa === 'estadistica' && selectedPrestacion.id) { - desde = [desde, selectedPrestacion.solicitud.fecha].sort((a, b) => moment(a).diff(moment(b)))[0]; - return this.camasHTTP.historialInternacion(ambito, capa, desde, hasta, selectedPrestacion.id); + if (this.capa === 'estadistica' && selectedInformeEstadistica.id) { + desde = [desde, selectedInformeEstadistica.informeIngreso.fechaIngreso].sort((a, b) => moment(a).diff(moment(b)))[0]; + + return this.camasHTTP.historialInternacion(ambito, capa, desde, hasta, selectedInformeEstadistica.id); } if (selectedResumen._id) { desde = [desde, selectedResumen.fechaIngreso].sort((a, b) => moment(a).diff(moment(b)))[0]; diff --git a/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/cama-detalle.component.ts b/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/cama-detalle.component.ts index 5ffe1e66b6..59d857f115 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/cama-detalle.component.ts +++ b/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/cama-detalle.component.ts @@ -15,8 +15,8 @@ import { PermisosMapaCamasService } from '../../services/permisos-mapa-camas.ser import { InternacionResumenHTTP } from '../../services/resumen-internacion.http'; import { OrganizacionService } from 'src/app/services/organizacion.service'; import { Auth } from '@andes/auth'; - - +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; +import { InformeEstadisticaService } from 'src/app/modules/rup/services/informe-estadistica.service'; @Component({ selector: 'app-cama-detalle', templateUrl: 'cama-detalle.component.html' @@ -69,6 +69,7 @@ export class CamaDetalleComponent implements OnInit, AfterViewChecked, OnDestroy public unicoMovimiento = false; public subscripcion: Subscription; public prestacion; + public InformeEstadistica; items = [ { @@ -93,6 +94,7 @@ export class CamaDetalleComponent implements OnInit, AfterViewChecked, OnDestroy private mapaCamasService: MapaCamasService, private mapaCamasHTTP: MapaCamasHTTP, private prestacionesService: PrestacionesService, + public InformeEstadisticaService: InformeEstadisticaService, public permisosMapaCamasService: PermisosMapaCamasService, private turneroService: TurneroService, private motivoAccesoService: ModalMotivoAccesoHudsService, @@ -115,8 +117,7 @@ export class CamaDetalleComponent implements OnInit, AfterViewChecked, OnDestroy this.relaciones$ = this.cama$.pipe(switchMap(cama => this.mapaCamasService.getRelacionesPosibles(cama))); this.accionesEstado$ = this.mapaCamasService.prestacionesPermitidas(this.mapaCamasService.selectedCama); this.organizacionV2$ = this.organizacionService.usaCapasUnificadas(this.auth.organizacion.id); - this.subscripcion = this.mapaCamasService.prestacion$.subscribe(p => this.prestacion = p); - + this.subscripcion = this.mapaCamasService.informeEstadistica$.subscribe(p => this.InformeEstadistica = p); this.paciente$ = this.cama$.pipe( filter(cama => !!cama.paciente), switchMap(cama => cama.paciente ? this.mapaCamasService.getPaciente(cama.paciente) : of(null)) diff --git a/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/internacion-detalle/internacion-detalle.component.html b/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/internacion-detalle/internacion-detalle.component.html index d477be1a59..e2926572a6 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/internacion-detalle/internacion-detalle.component.html +++ b/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/internacion-detalle/internacion-detalle.component.html @@ -16,11 +16,11 @@ - + - + @@ -52,7 +52,7 @@ - diff --git a/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/internacion-detalle/internacion-detalle.component.ts b/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/internacion-detalle/internacion-detalle.component.ts index 26cdec5a75..9cc006794f 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/internacion-detalle/internacion-detalle.component.ts +++ b/src/app/apps/rup/mapa-camas/sidebar/cama-detalle/internacion-detalle/internacion-detalle.component.ts @@ -9,7 +9,8 @@ import { PermisosMapaCamasService } from '../../../services/permisos-mapa-camas. import { ListadoInternacionCapasService } from '../../../views/listado-internacion-capas/listado-internacion-capas.service'; import { ListadoInternacionService } from '../../../views/listado-internacion/listado-internacion.service'; import { IngresoPacienteService } from '../../ingreso/ingreso-paciente-workflow/ingreso-paciente-workflow.service'; - +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; +import { InformeEstadisticaService } from 'src/app/modules/rup/services/informe-estadistica.service'; @Component({ selector: 'app-internacion-detalle', templateUrl: './internacion-detalle.component.html', @@ -51,7 +52,8 @@ export class InternacionDetalleComponent implements OnInit, AfterViewChecked { private listadoInternacionCapasService: ListadoInternacionCapasService, private listadoInternacion: ListadoInternacionService, private cdr: ChangeDetectorRef, - private ingresoPacienteService: IngresoPacienteService + private ingresoPacienteService: IngresoPacienteService, + private informeEstadisticaService: InformeEstadisticaService ) { } ngAfterViewChecked() { @@ -77,7 +79,6 @@ export class InternacionDetalleComponent implements OnInit, AfterViewChecked { this.editarIngresoIdInternacion = null; this.editarEgreso = false; this.capa = this.mapaCamasService.capa; - this.mapaCamasService.historialInternacion$.subscribe( historial => { if (historial.length && (this.capa === 'estadistica' || historial.some(mov => mov.extras.egreso))) { @@ -91,20 +92,29 @@ export class InternacionDetalleComponent implements OnInit, AfterViewChecked { } ); - this.mapaCamasService.prestacion$.subscribe(prestacion => { + this.mapaCamasService.informeEstadistica$.subscribe(informe => { this.estadoPrestacion = ''; this.existeIngreso = false; - if (prestacion) { - this.estadoPrestacion = prestacion.estadoActual.tipo; - if (prestacion.ejecucion.registros[0].valor.informeIngreso) { - this.existeIngreso = true; + if (informe) { + if (informe.estadoActual?.tipo) { + this.estadoPrestacion = informe.estadoActual.tipo; + + } else if (informe.estados && informe.estados.length > 0) { + this.estadoPrestacion = informe.estados[informe.estados.length - 1].tipo; + + } else if (typeof informe.estado === 'string') { + this.estadoPrestacion = informe.estado; } - this.existeEgreso = !!prestacion.ejecucion.registros[1]?.valor?.InformeEgreso; + + this.existeIngreso = !!informe.informeIngreso; + + this.existeEgreso = !!informe.informeEgreso; this.editarEgreso = !this.existeEgreso; - this.ingresoPacienteService.selectPaciente(prestacion.paciente?.id); + + this.ingresoPacienteService.selectPaciente(informe.paciente?.id); } - // loading se setea en true desde el listado de internacion + this.mapaCamasService.isLoading(false); }); @@ -146,17 +156,18 @@ export class InternacionDetalleComponent implements OnInit, AfterViewChecked { ); this.anular$ = combineLatest([ - this.mapaCamasService.selectedPrestacion, + this.mapaCamasService.informeEstadistica$, this.registraEgreso$, this.mapaCamasService.view, this.mapaCamasService.loading ]).pipe( auditTime(1), - map(([prestacion, registraEgreso, vista, loading]) => { - this.activateOption(this.items[0].key); - return prestacion?.estadoActual?.tipo !== 'validada' && vista === 'listado-internacion' && !loading; + map(([informe, registraEgreso, vista, loading]) => { + const estado = informe?.estadoActual?.tipo; + return estado !== 'validada' && vista === 'listado-internacion' && !loading; }) ); + } onAnularInternacion() { diff --git a/src/app/apps/rup/mapa-camas/sidebar/egreso/egresar-paciente.component.html b/src/app/apps/rup/mapa-camas/sidebar/egreso/egresar-paciente.component.html index f939882dd9..0656e00c1b 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/egreso/egresar-paciente.component.html +++ b/src/app/apps/rup/mapa-camas/sidebar/egreso/egresar-paciente.component.html @@ -1,6 +1,6 @@
- @@ -9,7 +9,7 @@ - + + + [(ngModel)]="registro.valor.InformeEgreso.tipoEgreso.otraOrganizacion" [required]="true"> @@ -52,21 +52,21 @@ - + + + + [(ngModel)]="registro.valor.InformeEgreso.diasDeEstada" required readonly> + + - + - - - - + + + + [(ngModel)]="registro.valor.InformeEgreso.diagnosticos.otrasCircunstancias" + name="otrasCircunstancias" (getData)="codigoCIE10($event, 'circunstancia')" + placeholder="Buscar..."> - - + + + + + [(ngModel)]="registro.valor.InformeEgreso.diagnosticos.diasDePermisoDeSalida"> @@ -92,17 +98,17 @@ + name="producidaPor" [data]="causaExterna.producidaPor" labelField="nombre" required> - + + + - + (getData)="searchComoSeProdujo($event)" labelField="nombre" required> @@ -151,33 +157,32 @@ - + - + + *ngFor="let procedimiento of registro.valor.InformeEgreso.procedimientosQuirurgicos; let i = index"> - + - + ariaLabel="Borrar procedimiento quirúrgico" (click)="removeProcedimiento(i)"> + \ No newline at end of file diff --git a/src/app/apps/rup/mapa-camas/sidebar/egreso/egresar-paciente.component.ts b/src/app/apps/rup/mapa-camas/sidebar/egreso/egresar-paciente.component.ts index a8253a493b..a954483bfd 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/egreso/egresar-paciente.component.ts +++ b/src/app/apps/rup/mapa-camas/sidebar/egreso/egresar-paciente.component.ts @@ -1,10 +1,9 @@ - import { Auth } from '@andes/auth'; import { Plex } from '@andes/plex'; import { cache } from '@andes/shared'; import { Component, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'; import { BehaviorSubject, combineLatest, Observable, of, Subscription } from 'rxjs'; -import { catchError, first, map, switchMap } from 'rxjs/operators'; +import { catchError, debounceTime, first, map, switchMap, tap } from 'rxjs/operators'; import { IPrestacion } from '../../../../../modules/rup/interfaces/prestacion.interface'; import { PrestacionesService } from '../../../../../modules/rup/services/prestaciones.service'; import { OrganizacionService } from '../../../../../services/organizacion.service'; @@ -19,6 +18,10 @@ import { InternacionResumenHTTP } from '../../services/resumen-internacion.http' import { ListadoInternacionService } from '../../views/listado-internacion/listado-internacion.service'; import { ListadoInternacionCapasService } from '../../views/listado-internacion-capas/listado-internacion-capas.service'; import { NgForm } from '@angular/forms'; +import { InformeEstadisticaService } from 'src/app/modules/rup/services/informe-estadistica.service'; +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; +import { debug } from 'console'; +import { debugOutputAstAsTypeScript } from '@angular/compiler'; @Component({ selector: 'app-egresar-paciente', templateUrl: './egresar-paciente.component.html', @@ -46,6 +49,7 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { public capa: string; public cama: ISnapshot; public prestacion: IPrestacion; + public informe: IInformeEstadistica; public maquinaEstados: IMaquinaEstados; public estadoDestino; public checkTraslado = false; @@ -67,6 +71,7 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { valor: { InformeEgreso: { fechaEgreso: null, + diasDeEstada: null, nacimientos: [ { pesoAlNacer: null, @@ -80,11 +85,20 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { producidaPor: null, lugar: null, comoSeProdujo: null + }, + tipoEgreso: null, + diagnosticos: { + principal: null, + secundarios: [], + otrasCircunstancias: null, + diasEstadaOtrasCircunstancias: null, + diasDePermisoDeSalida: null } } } }; + public procedimientosObstetricos = false; public procedimientosObstetricosNoReq = false; public existeCausaExterna = false; @@ -108,6 +122,7 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { public cie10Service: Cie10Service, private organizacionService: OrganizacionService, private servicioPrestacion: PrestacionesService, + private informeEstadisticaService: InformeEstadisticaService, public mapaCamasService: MapaCamasService, public procedimientosQuirurgicosService: ProcedimientosQuirurgicosService, private listadoInternacionService: ListadoInternacionService, @@ -153,36 +168,34 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { // else: this.cama tiene valor, el form de egreso es valido y de ser capa estadistica la prestacion no esta validada const condicion = camaActual?.estado === 'disponible' || (camaActual?.estado === 'ocupada' && camaActual?.idInternacion === this.cama?.idInternacion) + || this.informe || this.prestacion; return !condicion; }) ); + this.registrosEgresoResumen$ = combineLatest([ this.mapaCamasService.capa2, + this.mapaCamasService.informeEstadistica$, this.mapaCamasService.prestacion$ ]).pipe( first(), - switchMap(([capa, prestacion]) => { + switchMap(([capa, informe, prestacion]) => { if (capa === 'estadistica' || (capa === 'estadistica-v2' && this.view === 'mapa-camas')) { - /* Si es capa estadistica va a existir la prestacion pero no el resumen. - Si es capa medica la que realiza el egreso, puede que estadistica-v2 aun no haya cargado el informe de ingreso. - En este caso particular, permitimos el egreso y obtenemos la fecha de ingreso desde el resumen. - */ - const fechaIngreso = prestacion?.ejecucion.registros[0].valor.informeIngreso.fechaIngreso || this.resumen?.fechaIngreso; - const paciente = prestacion?.paciente.id || this.resumen?.paciente.id; + const fechaIngreso = informe?.informeIngreso?.fechaIngreso || this.resumen?.fechaIngreso; + const paciente = informe?.paciente?.id || this.resumen?.paciente.id; const desde = moment(fechaIngreso).subtract(12, 'hours').toDate(); const hasta = moment(fechaIngreso).add(12, 'hours').toDate(); - - // Combinar el historial de cama con la búsqueda del resumen return combineLatest([ + this.camasHTTP.historialInternacion( 'internacion', capa, - this.informeIngreso.fechaIngreso, + fechaIngreso, moment().toDate(), - prestacion.id + informe.id ), this.internacionResumenService.search({ organizacion: this.auth.organizacion.id, @@ -211,33 +224,45 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { this.mapaCamasService.capa2, this.mapaCamasService.ambito2, this.mapaCamasService.selectedCama, + this.mapaCamasService.informeEstadistica$, this.mapaCamasService.prestacion$, this.mapaCamasService.resumenInternacion$ - ]).subscribe(([view, capa, ambito, cama, prestacion, resumen]) => { + ]).subscribe(([view, capa, ambito, cama, informe, prestacion, resumen]) => { this.inProgress = false; this.resumen = resumen; - let fecha = moment(resumen?.fechaEgreso || this.mapaCamasService.fecha).toDate(); - if (view === 'listado-internacion' && prestacion) { - // DESDE EL LISTADO FECHA VIENE CON LA DEL INGRESO. PUES NO! + + let fecha = moment(resumen?.fechaEgreso || this.mapaCamasService.fecha).toDate(); + if (view === 'listado-internacion' && (informe || prestacion)) { fecha = moment(resumen?.fechaEgreso).toDate() || moment().toDate(); - this.prestacionValidada = prestacion.estados[prestacion.estados.length - 1].tipo === 'validada'; - } + const objetoConEstados = informe || prestacion; + const estados = objetoConEstados?.estados; + if (estados && estados.length > 0) { + this.prestacionValidada = estados[estados.length - 1].tipo === 'validada'; + } else { + this.prestacionValidada = false; + } + + } this.registro.valor.InformeEgreso.fechaEgreso = moment(fecha).toDate(); this.fechaMaxProcedimiento = moment(this.registro.valor.InformeEgreso.fechaEgreso).endOf('day').toDate(); this.fechaEgresoOriginal = null; + + this.view = view; this.capa = capa; + + if (capa === 'estadistica' || capa === 'estadistica-v2') { - if (!prestacion) { + if (!informe) { return; } - this.prestacion = prestacion; - this.informeIngreso = this.prestacion.ejecucion.registros[0].valor.informeIngreso; + this.informe = informe; + this.informeIngreso = this.informe?.informeIngreso; if (this.hayEgreso) { - this.registro.valor.InformeEgreso = Object.assign({}, this.prestacion.ejecucion.registros[1].valor.InformeEgreso); + this.registro.valor.InformeEgreso = Object.assign({}, this.informe.informeEgreso); fecha = moment(this.registro.valor.InformeEgreso.fechaEgreso).toDate(); this.fechaEgresoOriginal = moment(this.registro.valor.InformeEgreso.fechaEgreso).toDate(); @@ -250,9 +275,10 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { if (this.subscription2) { this.subscription2.unsubscribe(); } + const fechaABuscarMin = moment(this.informeIngreso.fechaIngreso).add(-1, 's').toDate(); const fechaABuscarMax = this.hayEgreso ? moment(this.registro.valor.InformeEgreso.fechaEgreso).add(-10, 's').toDate() : moment().toDate(); // para excluir el egreso - const idInternacion = resumen?.id || prestacion.id; + const idInternacion = resumen?.id || informe?.id || prestacion.id; this.subscription2 = this.camasHTTP.historialInternacion(ambito, capa, fechaABuscarMin, fechaABuscarMax, idInternacion) .subscribe(movimientos => { movimientos.sort((a, b) => new Date(b.fecha).getTime() - new Date(a.fecha).getTime()); @@ -268,16 +294,19 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { this.setEstadoDestino(); } }); + } else { this.cama = cama; this.setEstadoDestino(); } } else if (this.resumen?.id) { - // asistencial (no sala) - if (this.resumen.fechaEgreso) { + const esCapaAsistencial = this.capa === 'medica' || this.capa === 'enfermeria'; + + if (this.resumen.fechaEgreso && (esCapaAsistencial || this.view === 'listado-internacion')) { this.fechaEgresoOriginal = moment(this.resumen.fechaEgreso).toDate(); this.registro.valor.InformeEgreso.tipoEgreso = this.listaTipoEgreso.find(tipo => tipo.nombre === this.resumen.tipo_egreso); } + const fechaABuscarMax = resumen.fechaEgreso ? moment(resumen.fechaEgreso).add(-10, 's').toDate() : moment().toDate(); // para excluir el egreso this.subscription2 = this.camasHTTP.historialInternacion(ambito, capa, resumen.fechaIngreso, fechaABuscarMax, resumen.id) .subscribe(movimientos => { @@ -290,30 +319,34 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { this.setEstadoDestino(); }); - } else if (cama.sala) { + + } else if (cama?.sala) { this.cama = cama; } this.fecha = moment(fecha).toDate(); this.setDiasEstada(); }); + } - /* Calcula cual seria el siguiente estado correcto que corresponderia partir del movimiento actual - en base a la maquina de estados y se lo asigna a la variable 'estadoDestino' - */ private setEstadoDestino() { - this.subscription3 = this.mapaCamasService.getRelacionesPosibles(this.cama).subscribe((relacionesPosibles) => { - this.estadoDestino = relacionesPosibles[0]?.destino; + if (!this.cama) { + return; + } + if (this.subscription3) { + this.subscription3.unsubscribe(); + } + this.subscription3 = this.mapaCamasService.getRelacionesPosibles(this.cama).pipe(first()).subscribe((relacionesPosibles) => { + this.estadoDestino = relacionesPosibles.find(r => r.destino.nombre === 'Disponible' || r.destino.nombre === 'Limpieza' || r.destino.nombre === 'Mantenimiento')?.destino || relacionesPosibles[0]?.destino; }); } onType() { this.inProgress = true; } - - get hayEgreso() { - return this.prestacion && this.prestacion.ejecucion.registros[1] && this.prestacion.ejecucion.registros[1].valor; + get hayEgreso(): boolean { + return !!(this.informe && this.informe.informeEgreso); } setFecha() { @@ -324,7 +357,6 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { this.mapaCamasService.setFecha(nuevaFecha); this.registro.valor.InformeEgreso.fechaEgreso = nuevaFecha; if (this.capa === 'estadistica' || this.capa === 'estadistica-v2') { - // si se está egresando con fusion de capas puede que estadistica-v2 aun no haya cargado el informe if (this.capa === 'estadistica-v2' && !this.informeIngreso?.fechaIngreso) { this.plex.info('warning', 'Antes de egresar al paciente debe cargar el informe de ingreso.'); return; @@ -334,7 +366,6 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { this.fechaMaxProcedimiento = moment(this.registro.valor.InformeEgreso.fechaEgreso).endOf('day').toDate(); } } - guardar(valid) { if (valid.formValid) { this.inProgress = true; @@ -344,11 +375,14 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { this.plex.info('success', 'Los datos se actualizaron correctamente'); if (this.view === 'listado-internacion') { const fechaHasta = moment(this.registro.valor.InformeEgreso.fechaEgreso).add(1, 'm').toDate(); - // actualiza el listado this.listadoInternacionService.setFechaHasta(fechaHasta); this.listadoInternacionCapasService.setFechaHasta(fechaHasta); + this.mapaCamasService.selectResumen(null); + this.mapaCamasService.selectInformeEstadistica(null); this.mapaCamasService.selectPrestacion(null); this.mapaCamasService.selectResumen(null); + + } else if (this.view === 'mapa-camas') { this.mapaCamasService.setFecha(this.registro.valor.InformeEgreso.fechaEgreso); } @@ -371,15 +405,16 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { } } - /* Para las capas estadistica-v2, medica y enfermeria actualiza el resumen. Luego actualiza el estado de la cama cualquiera sea la capa. */ + + // Setea valores de la prestacion (estadistica y estadistica-v2) antes de llamar al egreso simplificado + egresoSimplificado(estado): Observable { // Se configura nuevo estado con datos del egreso let estadoPatch = {}; if (this.cama.sala) { - // sala comun this.cama.estado = estado; this.cama.extras = { egreso: true, @@ -388,7 +423,6 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { }; estadoPatch = this.cama; } else { - // cama estadoPatch = { _id: this.cama.id || this.cama._id, estado: estado, @@ -403,6 +437,7 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { } }; } + const saveInternacion = () => { if (this.capa !== 'estadistica' && !this.cama.sala) { // estadistica-v2, medica, enfermeria (exceptuando salas) @@ -420,85 +455,108 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { this.inProgress = false; if (this.capa !== 'estadistica' && !this.cama.sala && !resumenSaved) { - /* si hubo algun error actualizando el resumen, no debería actualizar el estado de la cama para + /* si hubo algun error actualizando el resumen, no debería actualizar el estado de la cama para no generar datos inconsistentes entre internacion y movimientos */ - throw new Error(); + throw new Error('Error al actualizar el resumen de internación.'); } + if (this.fechaEgresoOriginal) { - return this.mapaCamasService.changeTime(this.cama, this.fechaEgresoOriginal, this.registro.valor.InformeEgreso.fechaEgreso, this.cama.idInternacion); + const fechaOriginalString = moment(this.fechaEgresoOriginal).toISOString(); + const nuevaFechaString = moment(this.registro.valor.InformeEgreso.fechaEgreso).toISOString(); + + if (fechaOriginalString !== nuevaFechaString) { + return this.mapaCamasService.changeTime(this.cama, this.fechaEgresoOriginal, this.registro.valor.InformeEgreso.fechaEgreso, this.cama.idInternacion); + } + this.plex.info('success', 'Datos de egreso actualizados. Liberando/actualizando la cama.', 'Actualización Completa'); + return this.mapaCamasService.save(estadoPatch, this.registro.valor.InformeEgreso.fechaEgreso); + } else { + // Caso 3: PRIMER EGRESO (fechaEgresoOriginal es null) return this.mapaCamasService.save(estadoPatch, this.registro.valor.InformeEgreso.fechaEgreso); } }) ); } - // Setea valores de la prestacion (estadistica y estadistica-v2) antes de llamar al egreso simplificado egresoExtendido(): Observable { const registros = this.controlRegistrosGuardar(); - if (registros) { - const params: any = { - op: 'registros', - registros: registros - }; - return this.servicioPrestacion.patch(this.prestacion.id, params).pipe( - switchMap(prestacion => { - if (this.view === 'listado-internacion' || this.capa === 'estadistica') { - this.mapaCamasService.selectPrestacion(prestacion); - } - if (this.capa === 'estadistica-v2' && this.resumen?.fechaEgreso) { - const idInternacion = this.view === 'listado-internacion' ? this.resumen.id : this.cama.idInternacion; - // actualiza fecha y tipo de egreso en el resumen para mantener la sincronización - return this.internacionResumenService.update(idInternacion, { - tipo_egreso: this.registro.valor.InformeEgreso.tipoEgreso.id, - fechaEgreso: this.registro.valor.InformeEgreso.fechaEgreso - }); - } else { - // estadistica o medica - return this.egresoSimplificado(this.estadoDestino); - } - }), - catchError(error => { - this.plex.info('warning', `${error} ${moment(registros[0].valor.informeIngreso.fechaIngreso).format('YYYY-MM-DD HH:mm:ss').bold()}`, 'Error'); - return of(null); - }) - ); - } - return of(null); - } - controlRegistrosGuardar() { - const registros = JSON.parse(JSON.stringify(this.prestacion.ejecucion.registros)); - if (this.registro.valor.InformeEgreso.diagnosticoPrincipal) { - this.registro.esDiagnosticoPrincipal = true; + if (!registros) { + return of(null); } - if (this.registro.valor.InformeEgreso.UnidadOrganizativaDestino) { - const datosOrganizacionDestino = { - id: this.registro.valor.InformeEgreso.UnidadOrganizativaDestino.id, - nombre: this.registro.valor.InformeEgreso.UnidadOrganizativaDestino.nombre - }; - this.registro.valor.InformeEgreso.UnidadOrganizativaDestino = datosOrganizacionDestino; - } + const informeId = this.informe._id || this.informe.id; + const body = { informeEgreso: this.registro.valor.InformeEgreso }; - const existeEgreso = this.prestacion.ejecucion.registros.find(r => r.concepto.conceptId === '58000006'); + return this.informeEstadisticaService.patchRegistros(informeId, body).pipe( + switchMap(informes => { - if (!existeEgreso) { - registros.push(this.registro); - } else { - const indexRegistro = registros.findIndex(registro => registro.concepto.conceptId === '58000006'); - registros[indexRegistro] = this.registro; - } + if (this.view === 'listado-internacion' || this.capa === 'estadistica') { + this.mapaCamasService.selectInformeEstadistica(informes); + } - return registros; - } + if (this.capa === 'estadistica-v2' && this.resumen?.fechaEgreso) { + const idInternacion = this.resumen.id; + this.internacionResumenService.update(idInternacion, { + tipo_egreso: this.registro.valor.InformeEgreso.tipoEgreso?.id, + fechaEgreso: this.registro.valor.InformeEgreso.fechaEgreso + }).subscribe(); + } + return this.egresoSimplificado(this.estadoDestino); + }), + + catchError(error => { + this.plex.info( + 'warning', + `${error} ${moment(this.registro.valor.InformeEgreso.fechaEgreso).format('YYYY-MM-DD HH:mm:ss').bold()}`, + 'Error' + ); + return of(null); + }) + ); + } + controlRegistrosGuardar() { + const egreso = this.registro.valor.InformeEgreso; + + return { + fechaEgreso: egreso.fechaEgreso, + diasDeEstada: egreso.diasDeEstada, + tipoEgreso: { + id: egreso.tipoEgreso?.id, + nombre: egreso.tipoEgreso?.nombre, + OrganizacionDestino: egreso.UnidadOrganizativaDestino + ? { + id: egreso.UnidadOrganizativaDestino.id, + nombre: egreso.UnidadOrganizativaDestino.nombre + } + : undefined + }, + diagnosticos: { + principal: egreso.diagnosticoPrincipal, + secundarios: egreso.otrosDiagnosticos, + otrasCircunstancias: egreso.otrasCircunstancias, + diasEstadaOtrasCircunstancias: egreso.diasEstadaOtrasCircunstancias, + diasDePermisoDeSalida: egreso.diasDePermisoDeSalida + } + }; + } setDiasEstada() { if (this.capa === 'estadistica' || this.capa === 'estadistica-v2') { - const fechaIngreso = this.informeIngreso.fechaIngreso || this.resumen.fechaIngreso; - const fechaEgreso = this.registro.valor.InformeEgreso.fechaEgreso; - this.registro.valor.InformeEgreso['diasDeEstada'] = this.mapaCamasService.calcularDiasEstada(fechaIngreso, fechaEgreso); + const fechaIngreso = this.informe.informeIngreso?.fechaIngreso || this.resumen?.fechaIngreso; + const fechaEgreso = this.registro.valor.InformeEgreso?.fechaEgreso; + if (fechaIngreso && fechaEgreso) { + const dias = this.mapaCamasService.calcularDiasEstada(fechaIngreso, fechaEgreso); + + this.registro.valor.InformeEgreso.diasDeEstada = dias; + + } else { + console.warn('⚠️ No se puede calcular días de estadía: faltan fechas', { + fechaIngreso, + fechaEgreso + }); + } } } @@ -517,15 +575,18 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { } } - onChangeTraslado(event) { + + public onChangeTraslado(event: { value: boolean }) { if (event.value) { - this.registro.valor.InformeEgreso.UnidadOrganizativaDestino = { id: null, nombre: '' }; + this.registro.valor.InformeEgreso.tipoEgreso.OrganizacionDestino = null; } else { - this.registro.valor.InformeEgreso.UnidadOrganizativaDestino = null; + this.registro.valor.InformeEgreso.tipoEgreso.otraOrganizacion = null; + this.registro.valor.InformeEgreso.tipoEgreso.OrganizacionDestino = { id: null, nombre: null }; } - + this.refreshSaveButton.next({}); } + codigoCIE10(event, tipo) { const filtro = [{ desde: 'A00', @@ -549,21 +610,25 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { }); } else { const callback = []; - if (this.registro.valor.InformeEgreso.diagnosticoPrincipal) { - callback.push(this.registro.valor.InformeEgreso.diagnosticoPrincipal); - } - if (this.registro.valor.InformeEgreso.otrosDiagnosticos) { - callback.push(this.registro.valor.InformeEgreso.otrosDiagnosticos); + const principal = this.registro.valor.InformeEgreso.diagnosticos?.principal; + if (principal) { + callback.push(principal); + } + if (this.registro.valor.InformeEgreso.otrosDiagnosticos) { + callback.push(...this.registro.valor.InformeEgreso.otrosDiagnosticos); } - if (this.registro.valor.InformeEgreso.causaExterna && this.registro.valor.InformeEgreso.causaExterna.comoSeProdujo) { + + if (this.registro.valor.InformeEgreso.causaExterna?.comoSeProdujo) { callback.push(this.registro.valor.InformeEgreso.causaExterna.comoSeProdujo); } + event.callback(callback); } } + showProcedimientos_causas() { this.procedimientosObstetricos = false; this.procedimientosObstetricosNoReq = false; @@ -580,8 +645,11 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { const regexCIEProcedimientosObstetricos = new RegExp('^O8[0-4].[0-9]|O60.1|O60.2'); const regexCIEProcedimientosObstetricosNoReq = new RegExp('^O0[0-6].[0-9]'); - if (this.registro.valor.InformeEgreso.diagnosticoPrincipal) { - this.existeCausaExterna = regexCIECausasExternas.test(this.registro.valor.InformeEgreso.diagnosticoPrincipal.codigo); + + if (this.registro.valor.InformeEgreso.diagnosticos?.principal) { + this.existeCausaExterna = regexCIECausasExternas.test( + this.registro.valor.InformeEgreso.diagnosticos.principal.codigo + ); } if (this.registro.valor.InformeEgreso.otrosDiagnosticos) { @@ -591,11 +659,11 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { } } - if (this.registro.valor.InformeEgreso.diagnosticoPrincipal) { - this.procedimientosObstetricos = regexCIEProcedimientosObstetricos.test(this.registro.valor.InformeEgreso.diagnosticoPrincipal.codigo); - this.procedimientosObstetricosNoReq = regexCIEProcedimientosObstetricosNoReq.test(this.registro.valor.InformeEgreso.diagnosticoPrincipal.codigo); + if (this.registro.valor.InformeEgreso.diagnosticos?.principal) { + const principal = this.registro.valor.InformeEgreso.diagnosticos.principal; + this.procedimientosObstetricos = regexCIEProcedimientosObstetricos.test(principal.codigo); + this.procedimientosObstetricosNoReq = regexCIEProcedimientosObstetricosNoReq.test(principal.codigo); } - if (this.registro.valor.InformeEgreso.otrosDiagnosticos) { const diagObstetitricos = this.registro.valor.InformeEgreso.otrosDiagnosticos.filter(d => regexCIEProcedimientosObstetricosNoReq.test(d.codigo)); if (diagObstetitricos && diagObstetitricos.length > 0) { @@ -707,7 +775,7 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { checkEstadoCama() { this.mapaCamasService.get(this.fecha, this.cama?.id).subscribe((cama) => { if (cama && cama.estado !== 'disponible') { - if (!cama.idInternacion || (cama.idInternacion && cama.idInternacion !== this.prestacion.id) && this.capa !== 'estadistica-v2') { + if (!cama.idInternacion || (cama.idInternacion && cama.idInternacion !== this.informe.id) && this.capa !== 'estadistica-v2') { this.registro.valor.InformeEgreso.fechaEgreso = this.fechaEgresoOriginal; this.fecha = this.fechaEgresoOriginal; this.plex.info('warning', `No es posible realizar el cambio de fecha porque la cama ${this.cama.nombre.bold()} no se encuentra disponible`, @@ -724,10 +792,11 @@ export class EgresarPacienteComponent implements OnInit, OnDestroy { Define las fechas minima y maxima para el egreso actual según corresponda. */ checkHistorial(fecha: Date) { + if (this.subscription4) { this.subscription4.unsubscribe(); } - this.subscription4 = this.mapaCamasService.historial('cama', this.cama.fecha, moment().toDate(), this.cama).subscribe( + this.subscription4 = this.mapaCamasService.historial('cama', this.cama?.fecha, moment().toDate(), this.cama).subscribe( historialCama => { this.fechaMax = null; for (const historial of historialCama) { diff --git a/src/app/apps/rup/mapa-camas/sidebar/egreso/informe-egreso.component.html b/src/app/apps/rup/mapa-camas/sidebar/egreso/informe-egreso.component.html index b690a5e719..e5aa232b94 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/egreso/informe-egreso.component.html +++ b/src/app/apps/rup/mapa-camas/sidebar/egreso/informe-egreso.component.html @@ -15,8 +15,8 @@
- - + +
@@ -28,20 +28,21 @@ Tipo de egreso

{{informeEgreso.tipoEgreso?.nombre}}

+
Organización destino -

{{informeEgreso.UnidadOrganizativaDestino?.nombre}}

+

{{informeEgreso.tipoEgreso?.OrganizacionDestino?.nombre}}

-
+
Diagnostico Principal al egreso -

{{informeEgreso.diagnosticoPrincipal.codigo}} - - {{informeEgreso.diagnosticoPrincipal.nombre}} +

{{informeEgreso.diagnosticos.principal.codigo}} - + {{informeEgreso.diagnosticos.principal.nombre}}

- + Es primera vez:

SI diff --git a/src/app/apps/rup/mapa-camas/sidebar/egreso/informe-egreso.component.ts b/src/app/apps/rup/mapa-camas/sidebar/egreso/informe-egreso.component.ts index 9476bdeacc..f6e5d1d738 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/egreso/informe-egreso.component.ts +++ b/src/app/apps/rup/mapa-camas/sidebar/egreso/informe-egreso.component.ts @@ -3,8 +3,9 @@ import { IPrestacion } from '../../../../../modules/rup/interfaces/prestacion.in import { Observable } from 'rxjs'; import { MapaCamasService } from '../../services/mapa-camas.service'; import { notNull } from '@andes/shared'; -import { map } from 'rxjs/operators'; - +import { map, tap } from 'rxjs/operators'; +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; +import { IInformeEgreso } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; @Component({ selector: 'app-informe-egreso', templateUrl: './informe-egreso.component.html', @@ -12,9 +13,9 @@ import { map } from 'rxjs/operators'; export class InformeEgresoComponent implements OnInit { prestacion$: Observable; + informe$: Observable; registro$: Observable; informeEgreso$: Observable; - // VARIABLES public prestacionValidada = false; @@ -23,20 +24,29 @@ export class InformeEgresoComponent implements OnInit { ) { } ngOnInit() { - this.prestacion$ = this.mapaCamasService.prestacion$; - this.registro$ = this.prestacion$.pipe( + this.informe$ = this.mapaCamasService.informeEstadistica$; + + this.registro$ = this.informe$.pipe( notNull(), - map((prestacion) => { - return prestacion.ejecucion.registros[1]; - }) + map(informe => informe) ); - this.informeEgreso$ = this.registro$.pipe( + this.informeEgreso$ = this.informe$.pipe( notNull(), - map((registro) => { - return registro.valor.InformeEgreso; - }) + map(informe => informe.informeEgreso || informe.informeEgreso) ); + // this.informeEgreso$ = this.informe$.pipe( + // notNull(), + // tap(informe => { + // console.log('📘 informe completo:', JSON.parse(JSON.stringify(informe))); + // }), + // map(informe => informe.informeEgreso || informe.informeEgreso), + // tap(informeEgreso => { + // console.log('informeEgreso:', JSON.parse(JSON.stringify(informeEgreso))); + // }) + // ); + + } } diff --git a/src/app/apps/rup/mapa-camas/sidebar/ingreso/informe-ingreso.component.html b/src/app/apps/rup/mapa-camas/sidebar/ingreso/informe-ingreso.component.html index 3d2968cea9..a0d4983f20 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/ingreso/informe-ingreso.component.html +++ b/src/app/apps/rup/mapa-camas/sidebar/ingreso/informe-ingreso.component.html @@ -1,65 +1,89 @@ - + - - + + + + + - - - + + + + + + + + + + + + + +

+ + Censable + + + + NUEVO REGISTRO + + + + + + - + + - + + - -
- - - Censable - - - - - - - - - - - - + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+
+ - +
+
+ - -
- -
- - -
-
- - -
- - - -
- - -
-
- +
+
\ No newline at end of file diff --git a/src/app/apps/rup/mapa-camas/sidebar/ingreso/informe-ingreso.component.ts b/src/app/apps/rup/mapa-camas/sidebar/ingreso/informe-ingreso.component.ts index ef350c1ca5..1481b854a7 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/ingreso/informe-ingreso.component.ts +++ b/src/app/apps/rup/mapa-camas/sidebar/ingreso/informe-ingreso.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit, Output, EventEmitter } from '@angular/core'; import { MapaCamasService } from '../../services/mapa-camas.service'; import { IPrestacion } from '../../../../../modules/rup/interfaces/prestacion.interface'; -import { Observable } from 'rxjs'; +import { combineLatest, Observable } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { notNull } from '@andes/shared'; - +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; @Component({ selector: 'app-informe-ingreso', templateUrl: './informe-ingreso.component.html', @@ -15,7 +15,7 @@ export class InformeIngresoComponent implements OnInit { informeIngreso$: Observable; paciente$: Observable; pacienteFields = ['sexo', 'fechaNacimiento', 'edad', 'cuil', 'financiador', 'numeroAfiliado', 'direccion', 'telefono']; - + informeEstadistica$: Observable; // EVENTOS @Output() toggleEditar = new EventEmitter(); @@ -24,14 +24,46 @@ export class InformeIngresoComponent implements OnInit { ) { } ngOnInit() { + this.informeEstadistica$ = this.mapaCamasService.informeEstadistica$; this.prestacion$ = this.mapaCamasService.prestacion$; - this.informeIngreso$ = this.prestacion$.pipe( - notNull(), - map((prestacion) => prestacion.ejecucion.registros[0].valor.informeIngreso) + + this.informeIngreso$ = combineLatest([ + this.informeEstadistica$, + this.prestacion$ + ]).pipe( + map(([informeEstadistica, prestacion]) => { + if (informeEstadistica?.informeIngreso) { + return informeEstadistica.informeIngreso; + } + + if (prestacion?.ejecucion?.registros?.[0]?.valor?.informeIngreso) { + return prestacion.ejecucion.registros[0].valor.informeIngreso; + } + + return null; + }), + notNull() ); - this.paciente$ = this.prestacion$.pipe( + + this.paciente$ = combineLatest([ + this.informeEstadistica$, + this.prestacion$ + ]).pipe( + map(([informeEstadistica, prestacion]) => { + if (informeEstadistica?.paciente) { + return informeEstadistica.paciente; + } + + if (prestacion?.paciente) { + return prestacion.paciente; + } + + console.warn('⚠️ No se encontró paciente ni en informeEstadistica ni en prestación'); + return null; + }), notNull(), - switchMap(prestacion => this.mapaCamasService.getPaciente(prestacion.paciente)) + switchMap(paciente => this.mapaCamasService.getPaciente(paciente)) ); } + } diff --git a/src/app/apps/rup/mapa-camas/sidebar/ingreso/ingresar-paciente.component.html b/src/app/apps/rup/mapa-camas/sidebar/ingreso/ingresar-paciente.component.html index 1a6e83d55a..c229b4cd4b 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/ingreso/ingresar-paciente.component.html +++ b/src/app/apps/rup/mapa-camas/sidebar/ingreso/ingresar-paciente.component.html @@ -2,7 +2,7 @@
+ (click)="guardar($event)" [disabled]="formIngreso.invalid || disableButton || inProgress"> @@ -10,13 +10,13 @@ + (guardarCarpetaEmit)="afterComponenteCarpeta($event)"> + (click)="togglePrestacionCensable()"> @@ -26,7 +26,7 @@ + (click)="togglePrestacionNoCensable()"> No Censable @@ -37,42 +37,43 @@ + name=" fechaIngreso" [max]="mapaCamasService.fechaActual$ | async" required [debounce]="600" + (change)="setFecha()" grow="full" (typing)="onType()"> + [(ngModel)]="cama" name="cama" [data]="camas" placeholder="Elija cama" label="Cama" + idField="id" labelField="nombre + '(' + sectorName + ')'" (change)="selectCama(cama)" + grow="full"> + name="cama" [(ngModel)]="cama.nombre"> - + + (getData)="loadProfesionales($event)" [required]="true" labelField="apellido+' '+nombre"> + (change)="onchange($event)"> + (getData)="loadOrganizacion($event)" label="Organización origen" + placeholder="Seleccione la organización" labelField="nombre" [required]="true"> + [(ngModel)]="informeIngreso.organizacionOrigen" [required]="true"> @@ -81,8 +82,7 @@ + [(ngModel)]="informeIngreso.especialidades" [multiple]="true" label="Especialidad/es"> @@ -104,15 +104,16 @@ + [data]="pacienteAsociado" placeholder="Seleccione..." label="Cobertura" + labelField="nombre">
+ *ngIf="(informeIngreso?.asociado?.id === 'Plan de salud privado o Mutual') || (informeIngreso?.asociado === 'Plan de salud privado o Mutual')"> + (ngModelChange)="onFinanciadorChange($event)" name="financiador" + [data]="selectorFinanciadores" label="Financiador" labelField="nombre" + [required]="true">

@@ -121,19 +122,19 @@ + name="situacionLaboral" [data]="situacionesLaborales" placeholder="Seleccione... " + labelField="nombre"> + name="ocupacionHabitual" (getData)="getOcupaciones($event)" + placeholder="Seleccione... " labelField="'(' + codigo + ') ' + nombre"> + [data]="nivelesInstruccion" placeholder="Seleccione..." label="Nivel instrucción" + labelField="nombre">
@@ -142,8 +143,8 @@ + [paciente]="paciente" [registro]="registro" [soloValores]="false" + [params]="elementosRUPService.getParams(registro)"> \ No newline at end of file diff --git a/src/app/apps/rup/mapa-camas/sidebar/ingreso/ingresar-paciente.component.ts b/src/app/apps/rup/mapa-camas/sidebar/ingreso/ingresar-paciente.component.ts index 3a849b1815..cf4a79e561 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/ingreso/ingresar-paciente.component.ts +++ b/src/app/apps/rup/mapa-camas/sidebar/ingreso/ingresar-paciente.component.ts @@ -25,7 +25,9 @@ import { cache } from '@andes/shared'; import { IMaquinaEstados } from '../../interfaces/IMaquinaEstados'; import { ListadoInternacionCapasService } from '../../views/listado-internacion-capas/listado-internacion-capas.service'; import { IObraSocial } from 'src/app/interfaces/IObraSocial'; - +import { InformeEstadisticaService } from 'src/app/modules/rup/services/informe-estadistica.service'; +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; +import { IOrganizacion } from 'src/app/interfaces/IOrganizacion'; @Component({ selector: 'app-ingresar-paciente', templateUrl: './ingresar-paciente.component.html', @@ -54,6 +56,7 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { public cama: ISnapshot; public snapshot: ISnapshot[]; public prestacion: IPrestacion; + public informeEstadistica: IInformeEstadistica; public resumen: IResumenInternacion; public capa: string; public fechaValida = true; @@ -65,29 +68,39 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { public inProgress = false; public prepagas$: Observable; private backupObraSocial; - public registrosIngresoResumen$: Observable;; + public registrosIngresoResumen$: Observable; public get origenExterno() { - return this.informeIngreso?.origen?.id === 'traslado' || this.informeIngreso.origen === 'Traslado'; + return this.informeIngreso?.origen?.tipo === 'Traslado'; } public check = false; - public informeIngreso = { + public informeIngreso: any = { fechaIngreso: new Date(), horaNacimiento: new Date(), edadAlIngreso: null, - origen: null, + origen: { + tipo: null, + organizacionOrigen: null, + otraOrganizacion: null + }, ocupacionHabitual: null, situacionLaboral: null, nivelInstruccion: null, especialidades: [], asociado: null, - obraSocial: null, + cobertura: { + tipo: null, + obraSocial: { + nombre: '' as string, + financiador: '' as string, + codigoPuco: undefined as number | undefined + } + }, nroCarpeta: null, motivo: null, organizacionOrigen: null, profesional: null, financiador: null, - - PaseAunidadOrganizativa: null + paseAunidadOrganizativa: null }; public poseeMovimientos: Boolean; private subscription: Subscription; @@ -114,7 +127,8 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { public elementosRUPService: ElementosRUPService, public internacionResumenService: InternacionResumenHTTP, private conceptObserverService: ConceptObserverService, - private obraSocialService: ObraSocialService + private obraSocialService: ObraSocialService, + private informeEstadisticaService: InformeEstadisticaService ) { } ngOnDestroy() { @@ -184,6 +198,7 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { this.mapaCamasService.capa2, this.mapaCamasService.camaSelectedSegunView$, this.mapaCamasService.prestacion$, + this.mapaCamasService.informeEstadistica$, this.mapaCamasService.resumenInternacion$, pacienteID$.pipe( filter(pacID => !!pacID), @@ -191,13 +206,13 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { return this.mapaCamasService.getPaciente({ id: pacID }, false); }) )] - ).subscribe(([estado, view, capa, cama, prestacion, resumen, paciente]: [IMaquinaEstados, string, string, ISnapshot, IPrestacion, IResumenInternacion, IPaciente]) => { + ).subscribe(([estado, view, capa, cama, prestacion, informeEstadistica, resumen, paciente]: [IMaquinaEstados, string, string, ISnapshot, IPrestacion, IInformeEstadistica, IResumenInternacion, IPaciente]) => { this.capa = capa; this.prestacion = prestacion; + this.informeEstadistica = informeEstadistica; this.paciente = paciente; this.resumen = resumen; - // Puede suceder, por error, que el ingreso impacte pero no se cree el movimiento correspondiente - this.poseeMovimientos = !!(cama?.id); // si tiene cama, entonces registra al menos un movimiento + this.poseeMovimientos = !!(cama?.id); if (paciente && paciente.financiador && paciente.financiador.length > 0) { const os = paciente.financiador[0]; this.backupObraSocial = os; @@ -212,7 +227,6 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { this.paciente.obraSocial = this.prestacion.paciente.obraSocial; this.changeTipoObraSocial(); } else { - // capa medica/enfermeria, ingreso en estadistica o carga de prestacion en estadistica-v2 if (paciente.id) { const fechaIngresoInicial = resumen?.fechaIngreso || this.mapaCamasService.fecha; this.informeIngreso.fechaIngreso = new Date(fechaIngresoInicial); @@ -283,53 +297,55 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { }) ); this.obraSocialService.getListado({}).subscribe(listado => this.selectorFinanciadores = listado.filter(financiador => this.obrasSociales.every(os => os.nombre !== financiador.nombre))); - if (this.informeIngreso.obraSocial) { + if (this.informeIngreso.cobertura?.obraSocial) { this.financiador = this.selectorFinanciadores.find( - f => f.codigoPuco === this.informeIngreso.obraSocial.codigoPuco + f => f.codigoPuco === this.informeIngreso.cobertura.obraSocial.codigoPuco ); } } - cargarUltimaInternacion(paciente: IPaciente) { const conceptIdIngresoInternacion = '721915006'; - this.servicioPrestacion.getRegistrosHuds(paciente.id, conceptIdIngresoInternacion).subscribe(ingreso => { - if (ingreso.length > 0) { - ingreso = ingreso.sort((a, b) => b.fecha.getTime() - a.fecha.getTime()); - const ultimoIngreso = ingreso[0].registro.valor.informeIngreso; + this.informeEstadisticaService.getRegistrosHuds(paciente.id, conceptIdIngresoInternacion).subscribe((ingreso: any[]) => { + if (ingreso && ingreso.length > 0) { + const ultimoIngreso = ingreso[0].informeIngreso; this.informeIngreso.situacionLaboral = this.situacionesLaborales?.find(item => item.nombre === ultimoIngreso.situacionLaboral) || null; this.informeIngreso.nivelInstruccion = this.nivelesInstruccion?.find(item => item.nombre === ultimoIngreso.nivelInstruccion) || null; this.informeIngreso.ocupacionHabitual = ultimoIngreso.ocupacionHabitual; this.informeIngreso.asociado = ultimoIngreso.asociado; - this.informeIngreso.obraSocial = ultimoIngreso.obraSocial; + this.informeIngreso.cobertura.obraSocial = (ultimoIngreso as any).obraSocial; + + this.informeIngreso.cobertura.tipo = (ultimoIngreso as any).asociado; this.paciente.obraSocial = ultimoIngreso.obraSocial; this.esPrepaga = this.informeIngreso.asociado?.id === 'Plan de salud privado o Mutual'; + } }); } changeTipoObraSocial() { - this.selectedOS = false; - this.esPrepaga = false; - this.financiador = null; - const asociadoId = typeof this.informeIngreso.asociado === 'string' - ? this.informeIngreso.asociado - : this.informeIngreso.asociado?.id; - if (asociadoId === 'Plan de salud privado o Mutual') { - this.selectedOS = true; - this.esPrepaga = true; - if (this.informeIngreso.obraSocial) { - const financiadorParaSelect = this.selectorFinanciadores.find( - f => f.nombre === this.informeIngreso.obraSocial.nombre - ); - - if (financiadorParaSelect) { - this.financiador = financiadorParaSelect; - } else { - this.financiador = this.informeIngreso.obraSocial; - } - } + if (!this.informeIngreso.cobertura) { + this.informeIngreso.cobertura = { tipo: null, obraSocial: null }; + } + + const asociado = this.informeIngreso.asociado?.id || this.informeIngreso.asociado; + + if (asociado === 'Plan de salud privado o Mutual') { + this.informeIngreso.cobertura.tipo = 'Plan de salud privado o Mutual'; + + this.informeIngreso.cobertura.obraSocial = this.financiador || null; + + } else if (asociado === 'Plan o Seguro público' || asociado === 'Hospital Público') { + this.informeIngreso.cobertura.tipo = 'Plan o Seguro público'; + this.informeIngreso.cobertura.obraSocial = null; + } else if (asociado === 'Sin cobertura' || asociado === 'Ninguno') { + this.informeIngreso.cobertura.tipo = 'sinCobertura'; + this.informeIngreso.cobertura.obraSocial = null; + } else { + this.informeIngreso.cobertura.tipo = null; + this.informeIngreso.cobertura.obraSocial = null; } + } @@ -499,19 +515,18 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { return !!this.prestacion?.id && !this.cama?.esCensable && (this.capa === 'estadistica' || this.capa === 'estadistica-v2'); } - ingresoSimplificado(estado, paciente, idInternacion = null, nuevaPrestacion = null) { + + ingresoSimplificado(estado, paciente, idInternacion = null, nuevoInforme = null) { // si idInternacion === null es ingreso nuevo // si nuevaPrestacion !== null estadistica-v2 esta ingresando un paciente // Se modifica el estado de la cama this.cama.estado = estado; this.cama.paciente = paciente; this.cama.fechaIngreso = new Date(this.informeIngreso.fechaIngreso); - - if (this.prestacion && this.poseeMovimientos) { - // Se actualiza fecha y hora en camas + this.informeEstadistica = this.informeEstadistica; + if (this.informeEstadistica && this.poseeMovimientos) { this.cama.idInternacion = idInternacion; if (this.informeIngreso.fechaIngreso.getTime() !== this.fechaIngresoOriginal.getTime()) { - // Recuperamos snapshot inicial, por si hay un cambio de cama this.sincronizarCamaInternacion(idInternacion, this.fechaIngresoOriginal, this.informeIngreso.fechaIngreso).subscribe(() => { this.plex.info('success', 'Los datos se actualizaron correctamente'); this.mapaCamasService.setFecha(this.informeIngreso.fechaIngreso); @@ -530,12 +545,10 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { this.onSave.emit(); } } else { - if (nuevaPrestacion) { - // estadistica-v2 - this.prestacion = nuevaPrestacion; + if (nuevoInforme) { + this.informeEstadistica = nuevoInforme; } if (this.cama.idInternacion) { - // Edición de internación existente por capa medica/enfermeria this.sincronizarCamaInternacion(this.cama.idInternacion, this.fechaIngresoOriginal, this.informeIngreso.fechaIngreso).subscribe(() => { this.onSave.emit(); this.disableButton = false; @@ -568,7 +581,7 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { paciente: this.cama.paciente, organizacion: { ...this.auth.organizacion }, ingreso, - idPrestacion: this.capa === 'estadistica-v2' ? nuevaPrestacion.id : undefined + idPrestacion: this.capa === 'estadistica-v2' ? this.informeEstadistica.id : undefined }); createAction.pipe( @@ -599,34 +612,95 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { ingresoExtendido(paciente) { // construimos el informe de ingreso - this.informeIngreso.situacionLaboral = (this.informeIngreso.situacionLaboral) ? this.informeIngreso.situacionLaboral.nombre : null; - this.informeIngreso.nivelInstruccion = ((typeof this.informeIngreso.nivelInstruccion === 'string')) ? this.informeIngreso.nivelInstruccion : (Object(this.informeIngreso.nivelInstruccion).nombre); - this.informeIngreso.asociado = ((typeof this.informeIngreso.asociado === 'string')) ? this.informeIngreso.asociado : (Object(this.informeIngreso.asociado).nombre); - this.informeIngreso.origen = ((typeof this.informeIngreso.origen === 'string')) ? this.informeIngreso.origen : (Object(this.informeIngreso.origen).nombre); - // Verificamos si es de origen externo + const origenAntiguo: string | { [key: string]: any } = (this.informeIngreso as any).origen; + + if (origenAntiguo) { + if (typeof origenAntiguo === 'string') { + this.informeIngreso.origen = { + tipo: null, + organizacionOrigen: null, + otraOrganizacion: origenAntiguo + }; + } else { + this.informeIngreso.origen = { + tipo: origenAntiguo.tipo || null, + organizacionOrigen: origenAntiguo.organizacionOrigen || null, + otraOrganizacion: origenAntiguo.otraOrganizacion || null + }; + } + } else { + this.informeIngreso.origen = { + tipo: null, + organizacionOrigen: null, + otraOrganizacion: null + }; + } if (this.origenExterno && !this.check) { - this.informeIngreso.organizacionOrigen = { - id: this.informeIngreso.organizacionOrigen.id, - nombre: this.informeIngreso.organizacionOrigen.nombre + this.informeIngreso.origen = this.informeIngreso.origen || { + tipo: null, + organizacionOrigen: null, + otraOrganizacion: null }; + + this.informeIngreso.origen.organizacionOrigen = { + id: this.informeIngreso.organizacionOrigen?.id || this.informeIngreso.origen.organizacionOrigen?.id, + nombre: this.informeIngreso.organizacionOrigen?.nombre || this.informeIngreso.origen.organizacionOrigen?.nombre + }; + } + + if (this.informeIngreso.origen?.tipo && typeof this.informeIngreso.origen.tipo !== 'string') { + this.informeIngreso.origen.tipo = this.informeIngreso.origen.tipo.nombre || null; } - this.informeIngreso.PaseAunidadOrganizativa = this.informeIngreso.PaseAunidadOrganizativa; - if (!this.informeIngreso.asociado && this.informeIngreso.obraSocial) { - delete this.informeIngreso.obraSocial; - } if (this.informeIngreso.asociado === 'Plan o Seguro público') { - this.informeIngreso.obraSocial = null; + this.informeIngreso.paseAunidadOrganizativa = this.informeIngreso.paseAunidadOrganizativa; + + const asociado = this.informeIngreso.asociado?.id || this.informeIngreso.asociado; + if (asociado === 'Plan de salud privado o Mutual' || asociado?.id === 'Plan de salud privado o Mutual') { + this.informeIngreso.cobertura.tipo = 'Plan de salud privado o Mutual'; + this.informeIngreso.cobertura.obraSocial = this.financiador || this.paciente.obraSocial; + } else if (asociado === 'Plan o Seguro público' || asociado === 'Hospital Público') { + this.informeIngreso.cobertura.tipo = 'Plan o Seguro público'; + this.informeIngreso.cobertura.obraSocial = null; + } else if (asociado === 'Sin cobertura' || asociado === 'Ninguno') { + this.informeIngreso.cobertura.tipo = 'sinCobertura'; + this.informeIngreso.cobertura.obraSocial = null; } else { - this.informeIngreso.obraSocial = this.paciente.obraSocial || this.financiador; + this.informeIngreso.cobertura.tipo = null; + this.informeIngreso.cobertura.obraSocial = null; } if (this.paciente.fechaNacimiento) { this.informeIngreso.edadAlIngreso = this.mapaCamasService.calcularEdad(this.paciente.fechaNacimiento, this.informeIngreso.fechaIngreso); } - if (this.prestacion) { - this.actualizarPrestacion(paciente); + if (this.informeEstadistica) { + // Si ya existe un informe estadístico, lo actualiza + this.actualizarInformeEstadistica(paciente); } else { - this.crearPrestacion(paciente); + // Si no existe ni informe ni prestación, crea una nueva prestación + this.crearInformeEstadistico(paciente); } + + + } + + actualizarInformeEstadistica(paciente) { + const cambios = { + op: 'update', + paciente: this.paciente, + informeIngreso: this.informeIngreso, + }; + + this.informeEstadisticaService.patch(this.informeEstadistica._id, cambios).subscribe({ + next: (informeActualizado: any) => { + this.informeIngreso = informeActualizado.informeIngreso; + this.mapaCamasService.selectInformeEstadistica(informeActualizado); + + // acá sí está perfecto usar el _id del actualizado + this.ingresoSimplificado('ocupada', paciente, informeActualizado._id); + }, + error: () => { + this.plex.info('danger', 'Error al actualizar informe estadístico'); + } + }); } actualizarPrestacion(paciente) { @@ -648,16 +722,17 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { }); } - crearPrestacion(paciente) { - const nuevaPrestacion = this.datosBasicosPrestacion(); - this.servicioPrestacion.post(nuevaPrestacion).subscribe(prestacion => { + crearInformeEstadistico(paciente) { + const nuevoInforme = this.datosBasicosInformeEstad(); + + this.informeEstadisticaService.post(nuevoInforme).subscribe(informeEstadistica => { if (this.cama) { if (this.capa === 'estadistica') { - this.ingresoSimplificado('ocupada', paciente, prestacion.id); + this.ingresoSimplificado('ocupada', paciente, informeEstadistica._id); } else { // capa estadistica-v2 usa como idInternacion el id del resumen, por tanto primero hay que crearlo - this.ingresoSimplificado('ocupada', paciente, null, prestacion); + this.ingresoSimplificado('ocupada', paciente, null, informeEstadistica); } } else if (this.capa === 'estadistica') { this.plex.info('warning', 'Paciente ingresado a lista de espera'); @@ -667,7 +742,6 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { this.plex.info('danger', 'ERROR: La prestación no pudo ser registrada'); }); } - // Inicializa una prestación con todos sus datos básicos datosBasicosPrestacion() { // armamos el elemento data a agregar al array de registros @@ -691,6 +765,40 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { return nuevaPrestacion; } + datosBasicosInformeEstad(): IInformeEstadistica { + const nuevoInforme: IInformeEstadistica = { + id: null as any, + organizacion: this.auth.organizacion, + unidadOrganizativa: this.cama.unidadOrganizativa, + paciente: this.paciente, + informeIngreso: { + ...this.informeIngreso, + situacionLaboral: this.informeIngreso.situacionLaboral, + nivelInstruccion: this.informeIngreso.nivelInstruccion, + ocupacionHabitual: this.informeIngreso.ocupacionHabitual, + asociado: this.informeIngreso.asociado, + } as any, + estados: [{ + tipo: 'ejecucion', + createdAt: new Date(), + createdBy: this.informeIngreso.profesional + }], + createdAt: new Date(), + createdBy: { + id: this.informeIngreso.profesional.id, + nombreCompleto: this.informeIngreso.profesional.nombre + ' ' + this.informeIngreso.profesional.apellido, + nombre: this.informeIngreso.profesional.nombre, + apellido: this.informeIngreso.profesional.apellido, + username: this.informeIngreso.profesional.documento, + documento: this.informeIngreso.profesional.documento, + organizacion: this.auth.organizacion as unknown as IOrganizacion + } + }; + + return nuevoInforme; + } + + // Crea o actualiza una prestación de internación completarIngreso(paciente) { if (!this.prestacion) { @@ -877,23 +985,22 @@ export class IngresarPacienteComponent implements OnInit, OnDestroy { public setFinanciador(financiador) { this.financiador = financiador; } - onAsociadoChange(asociado) { + onAsociadoChange(asociado: any) { this.informeIngreso.asociado = asociado; this.changeTipoObraSocial(); + if (asociado?.id === 'Plan de salud privado o Mutual' || asociado === 'Plan de salud privado o Mutual') { + this.selectedOS = true; + } else { + this.selectedOS = false; + } } - onFinanciadorChange(financiadorSeleccionado) { - this.financiador = financiadorSeleccionado; - if (this.paciente.obraSocial) { - this.paciente.obraSocial.financiador = financiadorSeleccionado.financiador; - this.paciente.obraSocial.codigoPuco = financiadorSeleccionado.codigoPuco; - this.paciente.obraSocial.nombre = financiadorSeleccionado.nombre; - } else { - this.paciente.obraSocial = { - codigoPuco: financiadorSeleccionado.codigoPuco, - nombre: financiadorSeleccionado.nombre, - financiador: financiadorSeleccionado.financiador - }; + + onFinanciadorChange(financiador: any) { + this.financiador = financiador; + if (!this.informeIngreso.cobertura) { + this.informeIngreso.cobertura = { tipo: null, obraSocial: null }; } + this.informeIngreso.cobertura.obraSocial = financiador; } } diff --git a/src/app/apps/rup/mapa-camas/sidebar/movimientos-internacion/movimientos-internacion.component.ts b/src/app/apps/rup/mapa-camas/sidebar/movimientos-internacion/movimientos-internacion.component.ts index f475bda5f3..f883cdbf10 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/movimientos-internacion/movimientos-internacion.component.ts +++ b/src/app/apps/rup/mapa-camas/sidebar/movimientos-internacion/movimientos-internacion.component.ts @@ -1,11 +1,11 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { combineLatest, Observable, of, Subject } from 'rxjs'; -import { auditTime, catchError, map, startWith, takeUntil, switchMap } from 'rxjs/operators'; +import { auditTime, catchError, map, startWith, takeUntil, switchMap, tap } from 'rxjs/operators'; import { MapaCamasService } from '../../services/mapa-camas.service'; import { MapaCamasHTTP } from '../../services/mapa-camas.http'; import { IPrestacion } from 'src/app/modules/rup/interfaces/prestacion.interface'; import { IResumenInternacion } from '../../services/resumen-internacion.http'; - +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; @Component({ selector: 'app-movimientos-internacion', templateUrl: './movimientos-internacion.component.html', @@ -28,15 +28,13 @@ export class MovimientosInternacionComponent implements OnInit, OnDestroy { getFechasInternacion() { const capa = this.mapaCamasService.capa2.getValue(); + // modificaciones para que se vean los movimientos con la estructura nueva if (capa === 'estadistica') { - return this.mapaCamasService.prestacion$.pipe( - map(prestacion => { - return { - desde: prestacion.ejecucion.registros[0].valor.informeIngreso.fechaIngreso, - hasta: prestacion.ejecucion.registros[1]?.valor.InformeEgreso?.fechaEgreso || new Date() - }; - }), - catchError(() => of(null)) + return this.mapaCamasService.informeEstadistica$.pipe( + map(informeEstadistica => ({ + desde: informeEstadistica?.informeIngreso?.fechaIngreso, + hasta: informeEstadistica?.informeEgreso?.fechaEgreso || new Date() + })), ); } else { return this.mapaCamasService.resumenInternacion$.pipe( @@ -81,9 +79,9 @@ export class MovimientosInternacionComponent implements OnInit, OnDestroy { }) ); - let requestPrestacion: Observable; + let requestPrestacion: Observable; if (this.mapaCamasService.capa === 'estadistica') { - requestPrestacion = this.mapaCamasService.selectedPrestacion; + requestPrestacion = this.mapaCamasService.informeEstadistica$; } else { // se estaría usando capas unificadas requestPrestacion = this.mapaCamasService.selectedResumen; @@ -116,6 +114,7 @@ export class MovimientosInternacionComponent implements OnInit, OnDestroy { ); } + onChange() { const filtros = { desde: this.desde, diff --git a/src/app/apps/rup/mapa-camas/sidebar/registros-huds-detalle/registros-huds-detalle.component.ts b/src/app/apps/rup/mapa-camas/sidebar/registros-huds-detalle/registros-huds-detalle.component.ts index 7de7f10c19..3a1232832b 100644 --- a/src/app/apps/rup/mapa-camas/sidebar/registros-huds-detalle/registros-huds-detalle.component.ts +++ b/src/app/apps/rup/mapa-camas/sidebar/registros-huds-detalle/registros-huds-detalle.component.ts @@ -16,6 +16,8 @@ import { RegistroHUDSItemAccion } from './registros-huds-item/registros-huds-ite import { ISnapshot } from '../../interfaces/ISnapshot'; import { LaboratorioService } from 'src/app/services/laboratorio.service'; import { PacienteCacheService } from 'src/app/core/mpi/services/pacienteCache.service'; +import { InformeEstadisticaService } from 'src/app/modules/rup/services/informe-estadistica.service'; +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; @Component({ selector: 'app-registros-huds-detalle', @@ -57,6 +59,7 @@ export class RegistrosHudsDetalleComponent implements OnInit { constructor( public mapaCamasService: MapaCamasService, private prestacionService: PrestacionesService, + private informeEstadisticaService: InformeEstadisticaService, private auth: Auth, private router: Router, private motivoAccesoService: ModalMotivoAccesoHudsService, @@ -74,22 +77,32 @@ export class RegistrosHudsDetalleComponent implements OnInit { this.token$ = combineLatest([ this.cama$, this.mapaCamasService.selectedPrestacion, - this.mapaCamasService.resumenInternacion$, + this.mapaCamasService.informeEstadistica$, + this.mapaCamasService.resumenInternacion$ ]).pipe( - map(([cama, prestacion, resumen]) => { - if (cama?.paciente && cama.paciente === this.paciente - || prestacion?.paciente && prestacion.paciente === this.paciente || - resumen?.paciente && resumen.paciente === this.paciente) { + map(([cama, prestacion, informe, resumen]) => { + const paciente = + cama?.paciente || + prestacion?.paciente || + resumen?.paciente || + informe?.paciente; + + if (!paciente?.id) { + return null; + } + + if (this.paciente?.id === paciente.id) { return null; } + this.inProgress = true; - return [cama, prestacion, resumen]; + return paciente; }), notNull(), - switchMap(([cama, prestacion, resumen]) => { - this.paciente = cama.paciente || prestacion.paciente || resumen.paciente; - return this.motivoAccesoService.getAccessoHUDS(this.paciente as IPaciente); - }), + switchMap((paciente: IPaciente) => { + this.paciente = paciente; + return this.motivoAccesoService.getAccessoHUDS(paciente); + }) ); this.token$.subscribe({ diff --git a/src/app/apps/rup/mapa-camas/views/censos/censo-diario/censo-diario.component.html b/src/app/apps/rup/mapa-camas/views/censos/censo-diario/censo-diario.component.html index 168e366c1d..d0aa8aefa9 100644 --- a/src/app/apps/rup/mapa-camas/views/censos/censo-diario/censo-diario.component.html +++ b/src/app/apps/rup/mapa-camas/views/censos/censo-diario/censo-diario.component.html @@ -6,20 +6,23 @@ + [debounce]="600"> - +
- + + [tooltip]="(!censo) ? 'Debe generar el censo para descargarlo' : 'Descargar censo diario'" + type="warning" (click)="descargarCenso()"> - +
@@ -40,19 +43,31 @@ - {{censoP.datos.paciente | nombre}} | - {{censoP.datos.paciente | documento}} - {{censoP.datos.cama.nombre}}, - {{censoP.datos.cama.sectores[censoP.datos.cama.sectores.length -1].nombre}} + + {{ censoP?.datos?.paciente | nombre }} | + {{ censoP?.datos?.paciente | documento }} - {{censoP.ingreso}} - {{censoP.paseDe}} - {{censoP.egreso}} - {{censoP.paseA}} + - {{ censoP.fechaIngreso | fecha }} + {{ censoP?.datos?.cama?.nombre || '-' }}, + {{ + censoP?.datos?.cama?.sectores?.length + ? censoP.datos.cama.sectores[censoP.datos.cama.sectores.length - 1]?.nombre + : '-' + }} - {{censoP.diasEstada}} + + {{ censoP?.ingreso || '-' }} + {{ censoP?.paseDe || '-' }} + {{ censoP?.egreso || '-' }} + {{ censoP?.paseA || '-' }} + + + {{ censoP.fechaIngreso | fecha }} + - + + + {{ censoP?.diasEstada || 0 }} diff --git a/src/app/apps/rup/mapa-camas/views/censos/censo-diario/censo-diario.component.ts b/src/app/apps/rup/mapa-camas/views/censos/censo-diario/censo-diario.component.ts index 03eb0e41ee..ac3233fb58 100644 --- a/src/app/apps/rup/mapa-camas/views/censos/censo-diario/censo-diario.component.ts +++ b/src/app/apps/rup/mapa-camas/views/censos/censo-diario/censo-diario.component.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import { Component, OnInit } from '@angular/core'; import { Auth } from '@andes/auth'; import { OrganizacionService } from '../../../../../../services/organizacion.service'; @@ -53,11 +54,14 @@ export class CensosDiariosComponent implements OnInit { }); } + generarCensoDiario() { this.censoPacientes = []; this.censo = {}; this.mapaCamasService.censoDiario(moment(this.fecha).toDate(), this.selectedUnidadOranizativa.conceptId) .subscribe((censoDiario: any) => { + console.log('--- RESPUESTA COMPLETA DE LA API ---', censoDiario); + console.log('--- censoDiario.censo ES ---', censoDiario.censo); this.censo = { existencia0: censoDiario.censo.existenciaALas0, ingresos: censoDiario.censo.ingresos, @@ -71,11 +75,14 @@ export class CensosDiariosComponent implements OnInit { diasEstada: censoDiario.censo.diasEstada, disponibles24: censoDiario.censo.disponibles, }; + console.log('📦 CENSO DIARIO:', censoDiario); Object.keys(censoDiario.pacientes).map(p => { let delDiaAnterior = false; let ingresoAServicio = false; const censoPaciente = censoDiario.pacientes[p]; + console.log('🧩 PACIENTE:', p, censoPaciente); + censoPaciente.actividad.forEach((actividad: any, index) => { const movimiento = { datos: { diff --git a/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.component.html b/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.component.html index f5c0b2b82f..15a81cde84 100644 --- a/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.component.html +++ b/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.component.html @@ -1,110 +1,125 @@ - - - -
- - - -
+ + - - + -
- - - -
+
+ + + +
-
- - -
+ - -
- - -
- - - - - - {{ internacion.paciente | nombre }} - - - {{ internacion.paciente | documento }} - - - - {{internacion.ejecucion?.registros[0]?.valor?.informeIngreso?.motivo}} - - - - {{ devuelveFecha(internacion,"ingreso") | fecha }} - {{ devuelveFecha(internacion,"ingreso") | hora }} - - - - {{ fechaEgreso | fecha }} - {{ fechaEgreso | hora }} - - - - {{ internacion.paciente.obraSocial?.nombre }} - - - {{ internacion.unidadOrganizativa?.term }} - - - {{internacion.estadoActual.tipo }} - - - -
-
+ - - - - - - +
+ + + +
-
+
+ + +
- - - - - - - - - - - - - - - - - - -
-
\ No newline at end of file + +
+ + +
+ + + + + + {{ internacion.paciente | nombre }} + {{ internacion.paciente | documento }} + + + {{ internacion.informeIngreso.motivo }} + + + + {{ devuelveFecha(internacion, 'ingreso') | fecha }} + {{ devuelveFecha(internacion, 'ingreso') | hora }} + + + + {{ fechaEgreso | fecha }} + {{ fechaEgreso | hora }} + + + + {{ internacion.paciente.obraSocial?.nombre }} + + + {{ internacion.unidadOrganizativa?.term }} + + + {{ internacion.estadoActual?.tipo }} + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.component.ts b/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.component.ts index ecc0cd51c6..07cc88eea0 100644 --- a/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.component.ts +++ b/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.component.ts @@ -1,137 +1,103 @@ +/* eslint-disable no-console */ import { Component, OnInit } from '@angular/core'; import { Location } from '@angular/common'; import { ActivatedRoute, Router } from '@angular/router'; import { Plex } from '@andes/plex'; -import { snomedIngreso, snomedEgreso } from '../../constantes-internacion'; -import { PrestacionesService } from '../../../../../modules/rup/services/prestaciones.service'; -import { MapaCamasService } from '../../services/mapa-camas.service'; -import { IPrestacion } from '../../../../../modules/rup/interfaces/prestacion.interface'; +import { map } from 'rxjs/operators'; import { Observable } from 'rxjs'; +import { Auth } from '@andes/auth'; + +import { MapaCamasService } from '../../services/mapa-camas.service'; import { ListadoInternacionService } from './listado-internacion.service'; import { IngresoPacienteService } from '../../sidebar/ingreso/ingreso-paciente-workflow/ingreso-paciente-workflow.service'; -import { map } from 'rxjs/operators'; import { PermisosMapaCamasService } from '../../services/permisos-mapa-camas.service'; -import { Auth } from '@andes/auth'; +import { InformeEstadisticaService } from 'src/app/modules/rup/services/informe-estadistica.service'; +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; @Component({ selector: 'app-internacion-listado', templateUrl: './listado-internacion.component.html', }) - export class InternacionListadoComponent implements OnInit { - listaInternacion$: Observable; - selectedPrestacion$: Observable; + listaInternacion$: Observable; + selectedInforme$: Observable; + + + fechaIngresoHasta$ = this.listadoInternacionService.fechaIngresoHasta; mainView$ = this.mapaCamasService.mainView; - // VARIABLES public mostrar = 'datosInternacion'; public cambiarUO = false; public puedeValidar = false; public puedeRomper = false; public editando = false; public estaBuscando = false; + public columns = [ - { // prioriza nombre autopercibido en caso de tener + { key: 'apellido-nombre', label: 'Apellido y nombre', sorteable: true, opcional: false, - sort: (a, b) => { - const aNombre = a.paciente.alias || a.paciente.nombre; - const bNombre = b.paciente.alias || b.paciente.nombre; - return (a.paciente.apellido + aNombre).localeCompare(b.paciente.apellido + bNombre); - } + sort: (a, b) => (a.paciente.apellido + a.paciente.nombre).localeCompare(b.paciente.apellido + b.paciente.nombre) }, { key: 'documento', label: 'Documento', sorteable: true, opcional: false, - sort: (a, b) => { - const aDocumento = a.paciente.documento || a.paciente.numeroIdentificacion; - const bDocumento = b.paciente.documento || b.paciente.numeroIdentificacion; - return aDocumento.localeCompare(bDocumento); - } + sort: (a, b) => (a.paciente.documento || '').localeCompare(b.paciente.documento || '') }, { key: 'diagnostico', - label: 'Motivo Ingreso', + label: 'Motivo ingreso', sorteable: true, opcional: true, - sort: (a: any, b: any) => { - const nameA = a.ejecucion?.registros[0]?.valor?.informeIngreso?.motivo || ''; - const nameB = b.ejecucion?.registros[0]?.valor?.informeIngreso?.motivo || ''; - return nameA.localeCompare(nameB); - } + sort: (a, b) => (a.informeIngreso?.motivo || '').localeCompare(b.informeIngreso?.motivo || '') }, { key: 'fechaIngreso', label: 'Fecha de ingreso', sorteable: true, opcional: false, - sort: (a, b) => { - const fecha1 = moment(this.devuelveFecha(a, 'ingreso')); - const fecha2 = moment(this.devuelveFecha(b, 'ingreso')); - return fecha1.diff(fecha2); - } + sort: (a, b) => moment(a.informeIngreso?.fechaIngreso).diff(moment(b.informeIngreso?.fechaIngreso)) }, { key: 'fechaEgreso', label: 'Fecha de egreso', sorteable: true, opcional: false, - sort: (a, b) => { - let fecha1 = this.devuelveFecha(a, 'egreso'); - let fecha2 = this.devuelveFecha(b, 'egreso'); - if (fecha1) { - fecha1 = moment(fecha1); - if (fecha2) { - fecha2 = moment(fecha2); - return fecha1.diff(fecha2); - } else { - return 1; - } - } - return -1; - } + sort: (a, b) => moment(a.informeEgreso?.fechaEgreso).diff(moment(b.informeEgreso?.fechaEgreso)) }, { key: 'obraSocial', label: 'Obra social', sorteable: true, opcional: false, - sort: (a, b) => { - const p1 = a.paciente.obraSocial?.nombre || ''; - const p2 = b.paciente.obraSocial?.nombre || ''; - return p1.localeCompare(p2); - } + sort: (a, b) => (a.obraSocial?.nombre || '').localeCompare(b.obraSocial?.nombre || '') }, { key: 'unidadOrganizativa', label: 'Unidad organizativa', sorteable: true, opcional: false, - sort: (a, b) => { - return a.unidadOrganizativa.term.localeCompare(b.unidadOrganizativa.term); - } + sort: (a, b) => (a.unidadOrganizativa?.term || '').localeCompare(b.unidadOrganizativa?.term || '') }, { key: 'estado', label: 'Estado', sorteable: true, opcional: false, - sort: (a, b) => { - return a.estadoActual.tipo.localeCompare(b.estadoActual.tipo); - } + sort: (a, b) => (a.estadoActual?.tipo || '').localeCompare(b.estadoActual?.tipo || '') } ]; constructor( private plex: Plex, private location: Location, - private prestacionService: PrestacionesService, - public mapaCamasService: MapaCamasService, + private informeEstadisticaService: InformeEstadisticaService, + private mapaCamasService: MapaCamasService, private listadoInternacionService: ListadoInternacionService, private ingresoPacienteService: IngresoPacienteService, private permisosMapaCamasService: PermisosMapaCamasService, @@ -141,97 +107,167 @@ export class InternacionListadoComponent implements OnInit { ) { } ngOnInit() { - // verificamos permisos + const capa = this.route.snapshot.paramMap.get('capa'); const permisosInternacion = this.auth.getPermissions('internacion:rol:?'); - if (permisosInternacion.length >= 1 && (permisosInternacion.indexOf(capa) !== -1 || permisosInternacion[0] === '*')) { + + if (permisosInternacion.length >= 1 && (permisosInternacion.includes(capa) || permisosInternacion[0] === '*')) { this.mapaCamasService.setCapa(capa); } else { this.router.navigate(['/inicio']); } + this.mapaCamasService.setAmbito('internacion'); this.permisosMapaCamasService.setAmbito('internacion'); this.mapaCamasService.setView('listado-internacion'); - this.mapaCamasService.select({ id: ' ' } as any); // Pequeño HACK - this.plex.updateTitle([{ - route: '/inicio', - name: 'Andes' - }, { - name: 'Internacion' - }, { - name: 'Listado de Internacion' - }]); - - this.selectedPrestacion$ = this.mapaCamasService.selectedPrestacion.pipe( - map(prestacion => { - this.puedeValidar = false; - this.puedeRomper = false; - if (prestacion?.ejecucion?.registros[1] && prestacion.ejecucion.registros[1].valor?.InformeEgreso) { - const informeEgreso = prestacion.ejecucion.registros[1].valor.InformeEgreso; - this.puedeValidar = prestacion.estados[prestacion.estados.length - 1].tipo !== 'validada' && - informeEgreso.fechaEgreso && - informeEgreso.tipoEgreso && - informeEgreso.diagnosticoPrincipal; - this.puedeRomper = (prestacion.ejecucion && prestacion.ejecucion.registros[1] && prestacion.estados[prestacion.estados.length - 1].tipo === 'validada'); + this.mapaCamasService.select({ id: ' ' } as any); + + this.plex.updateTitle([ + { route: '/inicio', name: 'Andes' }, + { name: 'Internación' }, + { name: 'Listado de Internación' } + ]); + + this.listaInternacion$ = this.listadoInternacionService.listaInternacionFiltrada$.pipe( + map((res: any) => { + if (Array.isArray(res)) { + return res; + } else if (Array.isArray(res?.data)) { + return res.data; + } else if (Array.isArray(res?.listaInternacion)) { + return res.listaInternacion; + } else { + console.warn('⚠️ listaInternacionFiltrada$ no devolvió un array. Valor recibido:', res); + return []; } - return prestacion; }) ); - this.listaInternacion$ = this.listadoInternacionService.listaInternacionFiltrada$; + + this.selectedInforme$ = this.mapaCamasService.selectedInformeEstadistica.pipe( + map((prestacion: any) => { + const informe = prestacion as IInformeEstadistica; + this.verificarInforme(informe); + return informe; + }) + ); } - devuelveFecha(internacion, tipo) { - const informe = this.verRegistro(internacion, tipo); - if (tipo === 'ingreso') { - return informe.informeIngreso.fechaIngreso; - } else { - return informe ? informe.InformeEgreso.fechaEgreso : null; - } + validar(seleccionarInforme: IInformeEstadistica) { + this.plex.confirm('Luego de validar la prestación ya no podrá editarse.
¿Desea continuar?', 'Confirmar validación').then(validar => { + if (validar) { + if (seleccionarInforme) { + const id = seleccionarInforme._id; + console.log('🔵 Enviando a validarInforme() el ID:', id); + + const egresoExiste = seleccionarInforme.informeEgreso; + const ultimoEstado = seleccionarInforme.estados[seleccionarInforme.estados.length - 1].tipo; + console.log('🟨 Último estado:', ultimoEstado); + if (egresoExiste && ultimoEstado !== 'validada') { + if (egresoExiste.fechaEgreso && egresoExiste.tipoEgreso && + egresoExiste.diagnosticos?.principal) { + this.informeEstadisticaService.validarInforme(id).subscribe({ + next: prestacion => { + this.mapaCamasService.selectInformeEstadistica(seleccionarInforme); + this.verificarInforme(prestacion); + this.listadoInternacionService.refresh.next(true); + }, + error: () => this.plex.info('danger', 'ERROR: No es posible validar la informre') + }); + } else { + this.plex.info('danger', 'ERROR: Faltan datos'); + } + } else { + this.plex.info('danger', 'ERROR: Debe completar los datos mínimos de egreso para validar la internación'); + } + } + } + }); } - verRegistro(prestacion, tipoRegistro) { - let registro = null; - if (tipoRegistro === 'ingreso') { - registro = prestacion.ejecucion.registros.find(r => r.concepto.conceptId === snomedIngreso.conceptId); - } - if (tipoRegistro === 'egreso') { - registro = prestacion.ejecucion.registros.find(r => r.concepto.conceptId === snomedEgreso.conceptId); - } + cancelar() { + this.mapaCamasService.selectPrestacion(null); + this.mapaCamasService.selectInformeEstadistica(null); + this.mostrar = 'datosInternacion'; + } + + cambiarCama() { + this.mostrar = 'desocuparCama'; + } + + devuelveFecha(internacion: IInformeEstadistica, tipo: 'ingreso' | 'egreso') { + return tipo === 'ingreso' ? internacion.informeIngreso?.fechaIngreso : internacion.informeEgreso?.fechaEgreso || null; + } + + romperValidacion(seleccionarInforme: IInformeEstadistica) { + const id = seleccionarInforme.id || seleccionarInforme._id; + this.plex.confirm('Esta acción puede traer consecuencias
¿Desea continuar?', 'Romper validación').then(validar => { + if (validar) { + this.informeEstadisticaService.romperValidacion(id).subscribe({ + next: informe => { + this.mapaCamasService.selectInformeEstadistica(informe); + this.verificarInforme(informe); + this.listadoInternacionService.refresh.next(true); + }, + error: () => this.plex.toast('danger', 'ERROR: No es posible romper la validación de la prestación') + }); + } + }); + } - if (registro) { - return registro.valor; + verificarInforme(informe: IInformeEstadistica) { + this.puedeValidar = false; + this.puedeRomper = false; + if (informe) { + const ultimoEstado = informe.estados?.length ? informe.estados[informe.estados.length - 1].tipo : (informe.estadoActual?.tipo || informe.estado); + if (ultimoEstado !== 'validada') { + const informeEgreso = informe.informeEgreso; + if (informeEgreso?.fechaEgreso && informeEgreso?.tipoEgreso && informeEgreso?.diagnosticos?.principal) { + this.puedeValidar = true; + } + } else { + this.puedeRomper = true; + } } - return null; } - seleccionarPrestacion(prestacion, selectedPrestacion) { + seleccionarInforme(informe: IInformeEstadistica, selected: IInformeEstadistica) { + + const id = informe.id || informe._id; + const selectedId = selected?.id || selected?._id; + if (this.mostrar === 'datosInternacion') { - if (selectedPrestacion._id === prestacion._id) { - this.mapaCamasService.selectPrestacion(null); + + if (selectedId === id) { + this.mapaCamasService.selectInformeEstadistica(null); this.mapaCamasService.select(null); } else { - this.mapaCamasService.selectPrestacion(prestacion); - this.mapaCamasService.setFecha(prestacion.ejecucion.registros[0].valor.informeIngreso.fechaIngreso); - this.ingresoPacienteService.selectPaciente(prestacion.paciente.id); - this.verificarPrestacion(prestacion); + const informeNormalizado = { + ...informe, + id, + _id: id + }; + + this.mapaCamasService.selectInformeEstadistica(informeNormalizado); + this.mapaCamasService.setFecha(informeNormalizado.informeIngreso?.fechaIngreso); + this.ingresoPacienteService.selectPaciente(informeNormalizado.paciente.id); this.mapaCamasService.isLoading(true); } } } - cancelar() { - this.mapaCamasService.selectPrestacion(null); - this.mostrar = 'datosInternacion'; - } - - volver() { - this.mapaCamasService.selectPrestacion(null); - this.location.back(); - } - - cambiarCama() { - this.mostrar = 'desocuparCama'; + seleccionarPrestacion(informe: IInformeEstadistica, selected: IInformeEstadistica) { + if (this.mostrar === 'datosInternacion') { + if (selected?.id === informe.id) { + this.mapaCamasService.selectInformeEstadistica(null); + this.mapaCamasService.select(null); + } else { + this.mapaCamasService.selectInformeEstadistica(informe); + this.mapaCamasService.setFecha(informe.informeIngreso?.fechaIngreso); + this.ingresoPacienteService.selectPaciente(informe.paciente.id); + this.mapaCamasService.isLoading(true); + } + } } refresh() { @@ -243,83 +279,23 @@ export class InternacionListadoComponent implements OnInit { this.mostrar = 'datosInternacion'; } + volver() { + this.mapaCamasService.selectInformeEstadistica(null); + this.location.back(); + } + accionDesocupar(accion) { this.mostrar = 'cambiarCama'; this.cambiarUO = accion.cambiarUO; } - verificarPrestacion(prestacion: IPrestacion) { - this.puedeValidar = false; - this.puedeRomper = false; - if (prestacion.ejecucion) { - if (prestacion.ejecucion.registros[1]) { - if (prestacion.estados[prestacion.estados.length - 1].tipo !== 'validada') { - const informeEgreso = prestacion.ejecucion.registros[1].valor.InformeEgreso; - if (informeEgreso) { - if (informeEgreso.fechaEgreso && informeEgreso.tipoEgreso && informeEgreso.diagnosticoPrincipal) { - this.puedeValidar = true; - } - } - } else { - this.puedeRomper = true; - } - } - } - } - onAccion($event) { this.editando = $event?.accion === 'editando'; } - validar(selectedPrestacion: IPrestacion) { - this.plex.confirm('Luego de validar la prestación ya no podrá editarse.
¿Desea continuar?', 'Confirmar validación').then(validar => { - if (validar) { - if (selectedPrestacion.ejecucion.registros[1]) { - const egresoExiste = selectedPrestacion.ejecucion.registros[1].valor; - if (egresoExiste && selectedPrestacion.estados[selectedPrestacion.estados.length - 1].tipo !== 'validada') { - if (egresoExiste.InformeEgreso.fechaEgreso && egresoExiste.InformeEgreso.tipoEgreso && - egresoExiste.InformeEgreso.diagnosticoPrincipal) { - this.prestacionService.validarPrestacion(selectedPrestacion).subscribe({ - next: prestacion => { - this.mapaCamasService.selectPrestacion(prestacion); - this.verificarPrestacion(prestacion); - this.listadoInternacionService.refresh.next(true); - }, - error: () => this.plex.info('danger', 'ERROR: No es posible validar la prestación') - }); - } else { - this.plex.info('danger', 'ERROR: Faltan datos'); - } - } else { - this.plex.info('danger', 'ERROR: Debe completar los datos mínimos de egreso para validar la internación'); - } - } - } - }); - } - - romperValidacion(selectedPrestacion: IPrestacion,) { - this.plex.confirm('Esta acción puede traer consecuencias
¿Desea continuar?', 'Romper validación').then(validar => { - if (validar) { - // hacemos el patch y luego creamos los planes - const cambioEstado: any = { - op: 'romperValidacion', - desdeInternacion: true - }; - // En api el estado de la prestación cambia a ejecucion - this.prestacionService.patch(selectedPrestacion.id, cambioEstado).subscribe({ - next: prestacion => { - this.mapaCamasService.selectPrestacion(prestacion); - this.verificarPrestacion(prestacion); - this.listadoInternacionService.refresh.next(true); - }, - error: () => this.plex.toast('danger', 'ERROR: No es posible romper la validación de la prestación') - }); - } - }); - } - buscando(valor) { this.estaBuscando = valor; } + + } diff --git a/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.service.ts b/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.service.ts index 3459b4d4c1..499cee2e07 100644 --- a/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.service.ts +++ b/src/app/apps/rup/mapa-camas/views/listado-internacion/listado-internacion.service.ts @@ -1,15 +1,15 @@ import { Injectable } from '@angular/core'; -import { IPrestacion } from '../../../../../modules/rup/interfaces/prestacion.interface'; -import { Observable, BehaviorSubject, combineLatest, of } from 'rxjs'; +import { Observable, BehaviorSubject, combineLatest } from 'rxjs'; import { switchMap, map, auditTime } from 'rxjs/operators'; import { MapaCamasHTTP } from '../../services/mapa-camas.http'; import { cache } from '@andes/shared'; +import { IInformeEstadistica } from 'src/app/modules/rup/interfaces/informe-estadistica.interface'; @Injectable() export class ListadoInternacionService { - public listaInternacion$: Observable; - public listaInternacionFiltrada$: Observable; + public listaInternacion$: Observable; + public listaInternacionFiltrada$: Observable; public pacienteText = new BehaviorSubject(null); public fechaIngresoDesde = new BehaviorSubject(moment().subtract(1, 'months').toDate()); public fechaIngresoHasta = new BehaviorSubject(moment().toDate()); @@ -41,7 +41,6 @@ export class ListadoInternacionService { fechaEgresoHasta, }; return this.mapaHTTP.getPrestacionesInternacion(filtros); - }), cache() ); @@ -54,7 +53,7 @@ export class ListadoInternacionService { this.unidadOrganizativa ]).pipe( map(([listaInternacion, paciente, estado, obraSocial, unidad]) => - this.filtrarListaInternacion(listaInternacion, paciente, estado, obraSocial, unidad) + this.filtrarInformesEstadistica(listaInternacion, { paciente, estado, obraSocial, unidad }) ) ); @@ -64,8 +63,7 @@ export class ListadoInternacionService { this.fechaEgresoDesde, this.fechaEgresoHasta ]).pipe( - map(([ - ingresoDesde, ingresoHasta, egresoDesde, egresoHasta]) => { + map(([ingresoDesde, ingresoHasta, egresoDesde, egresoHasta]) => { return !( (moment(ingresoDesde).isValid() && moment(ingresoHasta).isValid()) || (moment(egresoDesde).isValid() && moment(egresoHasta).isValid()) @@ -86,39 +84,46 @@ export class ListadoInternacionService { ); } - filtrarListaInternacion(listaInternacion: IPrestacion[], paciente: string, estado: string, obraSocial: any, unidad: any) { + // Método viejo + filtrarListaInternacion(listaInternacion: IInformeEstadistica[], paciente: string, estado: string, obraSocial: any, unidad: any) { let listaInternacionFiltrada = listaInternacion; if (paciente) { const esNumero = Number.isInteger(Number(paciente)); if (esNumero) { - listaInternacionFiltrada = listaInternacionFiltrada.filter((internacion: IPrestacion) => + listaInternacionFiltrada = listaInternacionFiltrada.filter((internacion: IInformeEstadistica) => (internacion.paciente.documento?.includes(paciente) || internacion.paciente?.numeroIdentificacion?.includes(paciente))); } else { - listaInternacionFiltrada = listaInternacionFiltrada.filter((internacion: IPrestacion) => (internacion.paciente.nombre.toLowerCase().includes(paciente.toLowerCase()) || + listaInternacionFiltrada = listaInternacionFiltrada.filter((internacion: IInformeEstadistica) => + (internacion.paciente.nombre.toLowerCase().includes(paciente.toLowerCase()) || internacion.paciente.alias?.toLowerCase().includes(paciente.toLowerCase()) || internacion.paciente.apellido.toLowerCase().includes(paciente.toLowerCase())) ); } } + if (estado) { - listaInternacionFiltrada = listaInternacionFiltrada.filter((internacion: IPrestacion) => + listaInternacionFiltrada = listaInternacionFiltrada.filter((internacion: IInformeEstadistica) => internacion.estados[internacion.estados.length - 1].tipo === estado ); } + if (obraSocial) { listaInternacionFiltrada = listaInternacionFiltrada.filter( - (internacion: IPrestacion) => { + (internacion: IInformeEstadistica) => { + const cobertura = internacion.informeIngreso?.cobertura; + const obra = cobertura?.obraSocial; + if (obraSocial._id === 'sin-obra-social') { - return !internacion.paciente.obraSocial; + return !obra; } - return internacion.paciente.obraSocial?.nombre === obraSocial.nombre; + return obra?.nombre === obraSocial.nombre; } ); } if (unidad) { - listaInternacionFiltrada = listaInternacionFiltrada.filter((internacion: IPrestacion) => + listaInternacionFiltrada = listaInternacionFiltrada.filter((internacion: IInformeEstadistica) => internacion.unidadOrganizativa?.term === unidad.term ); } @@ -126,6 +131,51 @@ export class ListadoInternacionService { return listaInternacionFiltrada; } + filtrarInformesEstadistica(informes: any[], filtros: any) { + const { paciente, estado, obraSocial, unidad } = filtros || {}; + + let listaFiltrada = informes; + + if (paciente) { + const esNumero = Number.isInteger(Number(paciente)); + if (esNumero) { + listaFiltrada = listaFiltrada.filter((i) => + i.paciente?.documento?.includes(paciente) || + i.paciente?.numeroIdentificacion?.includes(paciente) + ); + } else { + const valor = paciente.toLowerCase(); + listaFiltrada = listaFiltrada.filter((i) => + i.paciente?.nombre?.toLowerCase().includes(valor) || + i.paciente?.apellido?.toLowerCase().includes(valor) || + i.paciente?.alias?.toLowerCase().includes(valor) + ); + } + } + + if (estado) { + listaFiltrada = listaFiltrada.filter((i) => + i.estados?.[i.estados.length - 1]?.tipo === estado + ); + } + + if (obraSocial) { + listaFiltrada = listaFiltrada.filter((i) => { + if (obraSocial._id === 'sin-obra-social') { + return !i.paciente?.obraSocial; + } + return i.paciente?.obraSocial?.nombre === obraSocial.nombre; + }); + } + if (unidad) { + listaFiltrada = listaFiltrada.filter((i) => + i.unidadOrganizativa?.term === unidad.term + ); + } + return listaFiltrada; + } + + setFechaHasta(fecha: Date) { this.fechaIngresoHasta.next(fecha); } diff --git a/src/app/modules/rup/components/ejecucion/hudsBusqueda.component.ts b/src/app/modules/rup/components/ejecucion/hudsBusqueda.component.ts index 0cc875df1a..cb170fa241 100644 --- a/src/app/modules/rup/components/ejecucion/hudsBusqueda.component.ts +++ b/src/app/modules/rup/components/ejecucion/hudsBusqueda.component.ts @@ -5,7 +5,7 @@ import * as moment from 'moment'; import { LaboratorioService } from 'src/app/services/laboratorio.service'; import { RecetaService } from 'src/app/services/receta.service'; import { Observable, forkJoin } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { switchMap, tap } from 'rxjs/operators'; import { InternacionResumenHTTP } from 'src/app/apps/rup/mapa-camas/services/resumen-internacion.http'; import { IPaciente } from 'src/app/core/mpi/interfaces/IPaciente'; import { PacienteService } from 'src/app/core/mpi/services/paciente.service'; @@ -19,7 +19,24 @@ import { getSemanticClass } from '../../pipes/semantic-class.pipes'; import { EmitConcepto, RupEjecucionService } from '../../services/ejecucion.service'; import { HUDSService } from '../../services/huds.service'; import { PrestacionesService } from './../../services/prestaciones.service'; - +import { InformeEstadisticaService } from '../../services/informe-estadistica.service'; +import { IInformeEstadistica } from '../../interfaces/informe-estadistica.interface'; + + +interface IInternacionExtendida { + id: string; + fechaIngreso: any; + fechaEgreso: any; + paciente?: any; + esEstadistica?: boolean; + informesEstadisticos?: IInformeEstadistica[]; + registros?: any[]; + ambito?: string; + ingreso?: any; + organizacion?: any; + tipo_egreso?: string | null; + [key: string]: any; +} @Component({ selector: 'rup-hudsBusqueda', templateUrl: 'hudsBusqueda.html', @@ -42,6 +59,7 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { public loading = false; public cdas = []; + public informe: IInformeEstadistica[] = []; @Input() paciente: IPaciente; @Input() vistaHuds = false; @@ -65,7 +83,9 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { public prestacionSeleccionada = []; private _prestaciones: any = []; private prestacionesCopia: any = []; - private internaciones; + // private internaciones; + private internaciones: IInternacionExtendida[] = []; + get prestaciones() { return this._prestaciones; @@ -133,7 +153,7 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { public txtABuscar; public efectorRestringido = this.auth.check('huds:soloEfectorActual'); public indiceInternaciones; - public otrasPrestaciones; + public otrasPrestaciones: any = { registros: [] }; public filtroRecetas; public searchRecetas; public busquedaRecetas; @@ -191,6 +211,7 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { private laboratorioService: LaboratorioService, private recetasService: RecetaService, private profesionalService: ProfesionalService, + private informeEstadisticaService: InformeEstadisticaService, ) { } @@ -201,13 +222,23 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { */ ngAfterContentInit() { if (this.paciente) { - this.listarInternaciones(); - this.listarPrestaciones(); this.listarConceptos(); + + forkJoin({ + internaciones: this.listarInternaciones(), + prestaciones: this.listarPrestaciones(), + informes: this.listarInformeEstadistico() + }).subscribe(() => { + this.mergeInternacionesConInformes(); + + if (this.internaciones && this.internaciones.length > 0) { + this.setAmbitoOrigen('internacion'); + } else { + this.setAmbitoOrigen('ambulatorio'); + } + }); } const token = this.huds.getHudsToken(); - // Cuando se inicia una prestación debemos volver a consultar si hay CDA nuevos al ratito. - // [TODO] Ser notificado via websockets setTimeout(() => { this.buscarCDAPacientes(token); }, 1000 * 30); @@ -350,6 +381,97 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { return this.pacienteService.getById(id); } + // modificaciones para el pdf y huds + + listarInformeEstadistico() { + return this.informeEstadisticaService.getByPaciente( + this.paciente.id, + false, + this.fechaInicio, + this.fechaFin + ).pipe(tap((informe) => { + const informesFiltrados = informe.filter(inf => { + const idPacienteInforme = inf.paciente?.id || (inf.paciente as any)?._id; + return idPacienteInforme === this.paciente.id; + }); + + + this.informe = informesFiltrados; + })); + } + // modificaciones para el pdf y huds + + mergeInternacionesConInformes() { + const base: IInternacionExtendida[] = this.internaciones || []; + const informes: IInformeEstadistica[] = this.informe || []; + + const internacionesPorId = new Map( + base.map(i => [i.id, i]) + ); + + const internacionesResultantes: IInternacionExtendida[] = [...base]; + + for (const inf of informes) { + + const idInternacionReal = inf._id || inf.id; + + const existente = internacionesPorId.get(idInternacionReal); + + if (!existente) { + + const nuevaInternacion: IInternacionExtendida = { + id: idInternacionReal, + fechaIngreso: inf.informeIngreso?.fechaIngreso || null, + fechaEgreso: inf.informeEgreso?.fechaEgreso || null, + paciente: inf.paciente, + esEstadistica: true, + informesEstadisticos: [inf], + + registros: [], + ambito: 'internacion', + ingreso: null, + organizacion: inf.organizacion || null, + tipo_egreso: null, + createdAt: inf.createdAt || null + }; + + internacionesResultantes.push(nuevaInternacion); + internacionesPorId.set(idInternacionReal, nuevaInternacion); + + } else { + + if (!existente.informesEstadisticos) { + existente.informesEstadisticos = []; + } + + existente.informesEstadisticos.push(inf); + } + } + + this.internaciones = internacionesResultantes; + } + // modificaciones para el pdf y huds + + mezclarInformes(informes) { + this.internaciones = this.internaciones.map(int => { + const informe = informes.find(i => i.idInternacion === int.id); + + if (informe) { + int.registros = [ + ...int.registros, + { + term: 'Informe Estadístico', + conceptId: null, + tipo: 'informe-estadistico', + data: informe + } + ]; + } + + return int; + }); + } + listarInternaciones() { let request; if (this.paciente.idPacientePrincipal) { @@ -365,7 +487,10 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { paciente: this.paciente.vinculos || this.paciente.id }); } - request.subscribe((internaciones) => this.internaciones = internaciones); + + return request.pipe(tap((internaciones: any) => { + this.internaciones = internaciones; + })); } listarPrestaciones() { @@ -390,7 +515,7 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { } - this.servicioPrestacion.getByPaciente(this.paciente.id, false).subscribe(prestaciones => { + return this.servicioPrestacion.getByPaciente(this.paciente.id, false).pipe(tap(prestaciones => { this.prestacionesTotales = prestaciones; const validadas = prestaciones.filter(p => p.estados[p.estados.length - 1].tipo === 'validada'); @@ -421,14 +546,14 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { } }); this.prestacionesCopia = this.prestaciones.slice(); - this.setAmbitoOrigen('ambulatorio'); + // this.setAmbitoOrigen('ambulatorio'); this.tiposPrestacion = this._prestaciones.map(p => p.prestacion); this.organizaciones = this.prestaciones.filter(p => p.data.ejecucion?.organizacion); this.organizaciones = this.organizaciones.map(o => o.data.ejecucion.organizacion); this.buscarCDAPacientes(this.huds.getHudsToken()); this.buscarFichasEpidemiologicas(); - }); + })); } // Trae los hallazgos @@ -587,7 +712,23 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { case 'procedimiento': return this.registrosTotalesCopia.procedimiento.length; case 'planes': - return this.prestacionesCopia.length; + // Contar prestaciones en internaciones combinadas + let totalPrestaciones = 0; + if (this.indiceInternaciones && this.indiceInternaciones.length > 0) { + this.indiceInternaciones.forEach((internacion: any) => { + internacion.registros.forEach((registro: any) => { + if (registro.otras) { + totalPrestaciones += Object.keys(registro.otras).length; + } else { + totalPrestaciones++; + } + }); + }); + } + if (this.otrasPrestaciones?.registros?.length) { + totalPrestaciones += this.otrasPrestaciones.registros.length; + } + return totalPrestaciones; case 'producto': return this.registrosTotalesCopia.producto.length; case 'laboratorios': @@ -670,10 +811,129 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { this.otrasPrestaciones = { fechaDesde, fechaHasta, indices: Object.values(indiceRegistros.indices), registros: Object.values(indiceRegistros.registros) }; } + // modificaciones para el pdf y huds + filtrarPorInternacion(prestaciones) { + + const prestacionesEnInternacion = []; + // Importar las constantes SNOMED para ingreso y egreso + const snomedIngreso = { + fsn: 'documento de solicitud de admisión (elemento de registro)', + semanticTag: 'elemento de registro', + conceptId: '721915006', + term: 'documento de solicitud de admisión' + }; + + const snomedEgreso = { + fsn: 'alta del paciente (procedimiento)', + semanticTag: 'procedimiento', + conceptId: '58000006', + term: 'alta del paciente' + }; + const internaciones = this.internaciones?.map(internacion => { + + if (internacion.esEstadistica) { + const registrosFormateados = {}; + + internacion.informesEstadisticos?.forEach((informe, index) => { + const id = informe._id || informe.id; + + const registrosRUP = []; + + const origenString = informe.informeIngreso?.origen?.tipo || + informe.informeIngreso?.origen?.organizacionOrigen?.nombre || + informe.informeIngreso?.origen?.otraOrganizacion || + 'Consultorio externo'; + + registrosRUP.push({ + id: `${id}-ingreso-registro`, + concepto: snomedIngreso, + nombre: snomedIngreso.term, + valor: { + informeIngreso: { + ...informe.informeIngreso, + origen: origenString, + situacionLaboral: informe.informeIngreso?.situacionLaboral?.nombre || '', + nivelInstruccion: informe.informeIngreso?.nivelInstruccion?.nombre || '' + } + } + }); + + if (informe.informeEgreso) { + registrosRUP.push({ + id: `${id}-egreso-registro`, + concepto: snomedEgreso, + nombre: snomedEgreso.term, + valor: { + InformeEgreso: informe.informeEgreso + } + }); + } + + const registroCombinadoKey = `informe-estadistico-${id}`; + registrosFormateados[registroCombinadoKey] = { + prestacion: { + term: 'Informe Estadístico de Internación', + conceptId: '32485007' // internación + }, + data: { + id: id, + estadoActual: { + createdAt: informe.informeIngreso?.fechaIngreso || informe.createdAt || new Date(), + createdBy: informe.createdBy || {} + }, + solicitud: { + profesional: informe.createdBy || {}, + organizacion: informe.organizacion || {}, + ambitoOrigen: 'internacion' + }, + unidadOrganizativa: { + term: informe.unidadOrganizativa?.term || 'Unidad Estadística' + }, + paciente: informe.paciente, + ejecucion: { + registros: registrosRUP + }, + _esInformeEstadistico: false + } + }; + }); + + const prestacionesPorInternacion = prestaciones.filter(prestacion => { + const fechaIngresoValida = moment(prestacion.fecha).isSameOrAfter(internacion.fechaIngreso); + const fechaEgresoValida = internacion.fechaEgreso ? moment(prestacion.fecha).isSameOrBefore(internacion.fechaEgreso) : moment(prestacion.fecha).isSameOrBefore(moment().toDate()); + const organizacionValida = internacion.organizacion._id === prestacion.organizacion || internacion.organizacion.id === prestacion.organizacion; + + if (fechaIngresoValida && fechaEgresoValida && organizacionValida) { + prestacionesEnInternacion.push(prestacion); + return prestacion; + } else { return null; } + }); + + + prestacionesPorInternacion.forEach(prestacion => { + registrosFormateados[prestacion.data.id] = { + prestacion: prestacion.prestacion, + data: prestacion.data + }; + }); + + const resultado = { + id: internacion.id, + fechaIngreso: internacion.fechaIngreso, + fechaEgreso: internacion.fechaEgreso, + organizacion: internacion.organizacion?.nombre || 'Organización Estadística', + registros: [{ + otras: registrosFormateados + }] + }; + + return resultado; + } + const prestacionesPorInternacion = prestaciones.filter(prestacion => { const fechaIngresoValida = moment(prestacion.fecha).isSameOrAfter(internacion.fechaIngreso); const fechaEgresoValida = internacion.fechaEgreso ? moment(prestacion.fecha).isSameOrBefore(internacion.fechaEgreso) : moment(prestacion.fecha).isSameOrBefore(moment().toDate()); @@ -712,7 +972,71 @@ export class HudsBusquedaComponent implements AfterContentInit, OnInit { }) .filter(grupo => grupo.registros.length); - this.indiceInternaciones = internaciones?.reverse(); + internaciones.forEach((int, idx) => { + const ingreso = int.fechaIngreso ? new Date(int.fechaIngreso).toLocaleString() : 'sin fecha'; + const egreso = int.fechaEgreso ? new Date(int.fechaEgreso).toLocaleString() : 'sin fecha'; + + }); + const internacionesCombinadas = []; + const procesadas = new Set(); + + for (let i = 0; i < internaciones.length; i++) { + if (procesadas.has(i)) { continue; } + + const internacionBase = internaciones[i]; + + const otrasCombinadas: any = {}; + + const registrosFinales = []; + let otrasAcumuladas = {}; + + internacionBase.registros.forEach((registro: any) => { + if (registro.otras) { + otrasAcumuladas = { ...otrasAcumuladas, ...registro.otras }; + } else if (this.planIndicaciones.includes(registro.conceptId)) { + registrosFinales.push(registro); + } else { + otrasAcumuladas = { ...otrasAcumuladas, ...registro }; + } + }); + + procesadas.add(i); + + for (let j = i + 1; j < internaciones.length; j++) { + if (procesadas.has(j)) { continue; } + + const otraInternacion = internaciones[j]; + + const mismoDia = moment(internacionBase.fechaIngreso).isSame(otraInternacion.fechaIngreso, 'day'); + const cercanas = Math.abs(moment(internacionBase.fechaIngreso).diff(otraInternacion.fechaIngreso, 'hours')) < 24; + + if (mismoDia || cercanas) { + + otraInternacion.registros.forEach((registro: any) => { + if (registro.otras) { + otrasAcumuladas = { ...otrasAcumuladas, ...registro.otras }; + } else if (this.planIndicaciones.includes(registro.conceptId)) { + registrosFinales.push(registro); + } else { + otrasAcumuladas = { ...otrasAcumuladas, ...registro }; + } + }); + + procesadas.add(j); + } + } + + if (Object.keys(otrasAcumuladas).length > 0) { + registrosFinales.push({ otras: otrasAcumuladas }); + } + + internacionesCombinadas.push({ + ...internacionBase, + registros: registrosFinales + }); + } + + this.indiceInternaciones = internacionesCombinadas?.reverse(); this.filtrarOtrasPrestaciones(prestaciones, prestacionesEnInternacion); } diff --git a/src/app/modules/rup/components/ejecucion/hudsBusqueda.html b/src/app/modules/rup/components/ejecucion/hudsBusqueda.html index 65f3f8aa0f..4f99b6a26d 100644 --- a/src/app/modules/rup/components/ejecucion/hudsBusqueda.html +++ b/src/app/modules/rup/components/ejecucion/hudsBusqueda.html @@ -1,6 +1,5 @@