From 1e9e090be95ec248439e19d8802771691e4a4101 Mon Sep 17 00:00:00 2001 From: ma7payne Date: Fri, 15 Dec 2023 13:06:02 -0300 Subject: [PATCH] feat(MPI): implementa form para extranjeros con DNI (#2822) --- src/app/app.module.ts | 2 + .../mpi/components/busqueda-mpi.component.ts | 1 - .../mpi/components/datos-basicos.component.ts | 59 +++++-- .../core/mpi/components/datos-basicos.html | 101 +++++++---- .../core/mpi/components/paciente.component.ts | 167 +++++++++++++++--- src/app/core/mpi/components/paciente.html | 11 +- .../pacienteVinculadoCache.service.ts | 38 ++++ 7 files changed, 307 insertions(+), 72 deletions(-) create mode 100644 src/app/core/mpi/services/pacienteVinculadoCache.service.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2198cc759c..dbc3a38286 100755 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -139,6 +139,7 @@ import { HistorialBusquedaService } from './core/mpi/services/historialBusqueda. import { PacienteBuscarService } from './core/mpi/services/paciente-buscar.service'; import { PacienteService } from './core/mpi/services/paciente.service'; import { PacienteCacheService } from './core/mpi/services/pacienteCache.service'; +import { PacienteVinculadoCacheService } from './core/mpi/services/pacienteVinculadoCache.service'; import { DirectiveLibModule } from './directives/directives.module'; import { AuditoriaModule } from './modules/auditoria/auditoria.module'; import { ValidarCertificadoComponent } from './modules/epidemiologia/components/validar-certificado/validar-certificado.component'; @@ -395,6 +396,7 @@ registerLocaleData(localeEs, 'es'); ConfiguracionPrestacionService, PrestacionLegacyService, PacienteCacheService, + PacienteVinculadoCacheService, GeoreferenciaService, HistorialBusquedaService, CodificacionService, diff --git a/src/app/core/mpi/components/busqueda-mpi.component.ts b/src/app/core/mpi/components/busqueda-mpi.component.ts index 7166a6a162..34b719b725 100644 --- a/src/app/core/mpi/components/busqueda-mpi.component.ts +++ b/src/app/core/mpi/components/busqueda-mpi.component.ts @@ -64,7 +64,6 @@ export class BusquedaMpiComponent implements OnInit { if (paciente) { this.historialBusquedaService.add(paciente); this.pacienteCache.setPaciente(paciente); - if ((paciente.numeroIdentificacion || paciente.tipoIdentificacion) && !paciente.documento) { this.router.navigate(['apps/mpi/paciente/extranjero/mpi']); // abre formulario paciente extranjero } else { diff --git a/src/app/core/mpi/components/datos-basicos.component.ts b/src/app/core/mpi/components/datos-basicos.component.ts index 17806afbb7..d06d65da0c 100644 --- a/src/app/core/mpi/components/datos-basicos.component.ts +++ b/src/app/core/mpi/components/datos-basicos.component.ts @@ -1,5 +1,5 @@ import { Plex } from '@andes/plex'; -import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; +import { AfterViewInit, Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; import { NgForm } from '@angular/forms'; import { Subscription } from 'rxjs'; import { IPacienteMatch } from '../../../modules/mpi/interfaces/IPacienteMatch.inteface'; @@ -16,12 +16,13 @@ import { PacienteService } from '../services/paciente.service'; styleUrls: ['datos-basicos.scss'] }) -export class DatosBasicosComponent implements OnInit, OnChanges { +export class DatosBasicosComponent implements OnInit, OnChanges, AfterViewInit { @Input() paciente: IPaciente; @Input() tipoPaciente = 'con-dni'; @Output() changes: EventEmitter = new EventEmitter(); - @ViewChild('form', { static: false }) ngForm: NgForm; + @ViewChild('formBasico', { static: false }) formBasico: NgForm; + @ViewChild('formExtranjero', { static: false }) formExtranjero: NgForm; formChangesSubscription: Subscription; estados = []; @@ -30,7 +31,11 @@ export class DatosBasicosComponent implements OnInit, OnChanges { estadosCiviles: any[]; tipoIdentificacion: any[]; noPoseeDNI = false; + botonRegistroDNI = false; + pacienteExtranjero: IPaciente; + public nuevoPaciente = false; + public disableRegistro = false; public nombrePattern: string; public patronDocumento = /^[1-9]{1}[0-9]{4,7}$/; hoy = moment().endOf('day').toDate(); @@ -63,7 +68,6 @@ export class DatosBasicosComponent implements OnInit, OnChanges { fotoId: null }; - constructor( private plex: Plex, private pacienteService: PacienteService, @@ -72,6 +76,31 @@ export class DatosBasicosComponent implements OnInit, OnChanges { this.nombrePattern = pacienteService.nombreRegEx.source; } + ngOnChanges(changes: SimpleChanges) { + if (changes.paciente) { + this.nuevoPaciente = changes.paciente.firstChange || !changes.paciente.currentValue.id; + + if (!changes.paciente.previousValue?.id) { + this.pacienteExtranjero = Object.assign({}, this.paciente); + } + } + + if (!changes.paciente.currentValue.notaError?.length) { + this.paciente.reportarError = false; + } + } + + ngAfterViewInit() { + if (this.formExtranjero) { + this.formExtranjero.control.valueChanges.subscribe( + () => { + this.changes.emit({ pacienteExtranjero: this.pacienteExtranjero }); + this.disableRegistro = this.formExtranjero.invalid; + } + ); + } + } + ngOnInit() { if (this.tipoPaciente === 'sin-dni') { this.noPoseeDNI = true; @@ -88,15 +117,14 @@ export class DatosBasicosComponent implements OnInit, OnChanges { }); } - ngOnChanges({ paciente }: SimpleChanges) { - if (!paciente.currentValue.notaError?.length) { - this.paciente.reportarError = false; - } + public checkFormExtranjero() { + this.formExtranjero.control.markAllAsTouched(); + return this.formExtranjero.control.valid; } public checkForm() { - this.ngForm.control.markAllAsTouched(); - return this.ngForm.control.valid; + this.formBasico.control.markAllAsTouched(); + return this.formBasico.control.valid; } checkDisableValidar() { @@ -116,6 +144,17 @@ export class DatosBasicosComponent implements OnInit, OnChanges { completarGenero() { this.paciente.genero = ((typeof this.paciente.sexo === 'string')) ? this.paciente.sexo : (Object(this.paciente.sexo).id); + this.paciente.genero = ((typeof this.pacienteExtranjero.sexo === 'string')) ? this.pacienteExtranjero.sexo : (Object(this.pacienteExtranjero.sexo).id); + } + + registrarArgentino() { + if (this.botonRegistroDNI) { + this.disableRegistro = false; + this.formExtranjero.control.markAsPristine(); + this.formExtranjero.control.markAsUntouched(); + } + + this.changes.emit({ registroDNI: this.botonRegistroDNI }); } diff --git a/src/app/core/mpi/components/datos-basicos.html b/src/app/core/mpi/components/datos-basicos.html index b6c2d8d3eb..33d113f79b 100644 --- a/src/app/core/mpi/components/datos-basicos.html +++ b/src/app/core/mpi/components/datos-basicos.html @@ -1,5 +1,44 @@
-
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
@@ -14,7 +53,7 @@ + [required]="true" placeholder="Seleccione..." grow="4">
- +
+ - - - - - - - - - - + + + + + - - - + + + + + + - - + + - - - + + + +
@@ -125,7 +166,6 @@ - @@ -182,7 +222,6 @@ [required]="paciente.reportarError ? 'true' : 'false'">
-
\ No newline at end of file diff --git a/src/app/core/mpi/components/paciente.component.ts b/src/app/core/mpi/components/paciente.component.ts index 2dbbf533bb..a280d1d874 100644 --- a/src/app/core/mpi/components/paciente.component.ts +++ b/src/app/core/mpi/components/paciente.component.ts @@ -4,7 +4,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import * as moment from 'moment'; import { EMPTY, Subscription } from 'rxjs'; -import { map, mergeMap } from 'rxjs/operators'; +import { filter, first, map, mergeMap } from 'rxjs/operators'; import { IUbicacion } from 'src/app/interfaces/IUbicacion'; import { ValidacionService } from 'src/app/services/fuentesAutenticas/validacion.service'; import { IContacto } from '../../../interfaces/IContacto'; @@ -15,6 +15,7 @@ import { IPaciente } from '../interfaces/IPaciente'; import { HistorialBusquedaService } from '../services/historialBusqueda.service'; import { PacienteService } from '../services/paciente.service'; import { PacienteCacheService } from '../services/pacienteCache.service'; +import { PacienteVinculadoCacheService } from '../services/pacienteVinculadoCache.service'; import { DatosBasicosComponent } from './datos-basicos.component'; import { DatosContactoComponent } from './datos-contacto.component'; import { RelacionesPacientesComponent } from './relaciones-pacientes.component'; @@ -52,6 +53,10 @@ export class PacienteComponent implements OnInit { loading = true; autoFocus = 0; activeTab = 0; + esExtranjero; + pacienteBase: IPaciente; + pacienteExtranjero: IPaciente; + registroDNI = false; public contacto: IContacto = { tipo: 'celular', @@ -146,6 +151,7 @@ export class PacienteComponent implements OnInit { private validacionService: ValidacionService, private parentescoService: ParentescoService, private pacienteCache: PacienteCacheService, + private pacienteVinculadoCache: PacienteVinculadoCacheService, private _router: Router, public plex: Plex, private route: ActivatedRoute, @@ -169,16 +175,16 @@ export class PacienteComponent implements OnInit { this.parentescoService.get().subscribe(resultado => { this.parentescoModel = resultado; }); + this.pacienteBase = Object.assign({}, this.pacienteModel); this.loadPaciente(); } private loadPaciente() { if (this.paciente) { - if (this.paciente.id) { - /* El paciente se agrega al historial de búsqueda sólo si ya existía */ this.historialBusquedaService.add(this.paciente); + // Busco el paciente en mongodb this.pacienteService.getById(this.paciente.id).subscribe(resultado => { if (resultado) { @@ -194,7 +200,7 @@ export class PacienteComponent implements OnInit { } this.actualizarDatosPaciente(); this.loading = false; - }, error => { + }, () => { this.loading = false; this._router.navigate(['apps/mpi/busqueda']); }); @@ -230,6 +236,16 @@ export class PacienteComponent implements OnInit { // ---------------- PACIENTE ----------------------- onSelect(paciente: IPaciente) { + if (this.registroDNI) { + this.plex.confirm('El paciente extranjero quedará vinculado
al paciente con DNI argentino.', 'Atención').then(result => { + if (result) { + this.pacienteCache.setPaciente(paciente); + this.pacienteVinculadoCache.setPaciente(this.pacienteExtranjero); + this._router.navigate(['apps/mpi/paciente']); + } + }); + } + this.showDeshacer = false; this.paciente = Object.assign({}, paciente); this.actualizarDatosPaciente(); @@ -276,35 +292,67 @@ export class PacienteComponent implements OnInit { this.paciente.lugarNacimiento = this.lugarNacimiento; } this.pacienteModel = Object.assign({}, this.paciente); - this.pacienteModel.genero = this.pacienteModel.genero ? this.pacienteModel.genero : this.pacienteModel.sexo; this.checkDisableValidar(); } - - save(ignoreSuggestions = false) { + prepararPaciente(nuevoPaciente: IPaciente, ignoreSuggestions: boolean) { this.delete = true; const contactoValid = this.datosContacto.checkForm(); - const datosBasicosValid = this.datosBasicos.checkForm(); + const datosBasicosValid = (this.tipoPaciente === 'extranjero' && !this.registroDNI) + ? this.datosBasicos.checkFormExtranjero() + : this.datosBasicos.checkForm(); + if (!contactoValid || !datosBasicosValid) { this.plex.info('warning', 'Debe completar los datos obligatorios'); return; } + this.disableIgnorarGuardar = ignoreSuggestions; this.disableGuardar = true; - const pacienteGuardar: any = Object.assign({}, this.pacienteModel); + + const pacienteGuardar: any = Object.assign({}, nuevoPaciente); + pacienteGuardar.ignoreSuggestions = ignoreSuggestions; - pacienteGuardar.sexo = ((typeof this.pacienteModel.sexo === 'string')) ? this.pacienteModel.sexo : (Object(this.pacienteModel.sexo).id); - pacienteGuardar.estadoCivil = this.pacienteModel.estadoCivil ? ((typeof this.pacienteModel.estadoCivil === 'string')) ? this.pacienteModel.estadoCivil : (Object(this.pacienteModel.estadoCivil).id) : null; - pacienteGuardar.genero = this.pacienteModel.genero ? ((typeof this.pacienteModel.genero === 'string')) ? this.pacienteModel.genero : (Object(this.pacienteModel.genero).id) : pacienteGuardar.sexo; - pacienteGuardar.tipoIdentificacion = this.pacienteModel.tipoIdentificacion ? ((typeof this.pacienteModel.tipoIdentificacion === 'string')) ? this.pacienteModel.tipoIdentificacion : (Object(this.pacienteModel.tipoIdentificacion).id) : null; + pacienteGuardar.sexo = ((typeof nuevoPaciente.sexo === 'string')) ? nuevoPaciente.sexo : (Object(nuevoPaciente.sexo).id); + pacienteGuardar.estadoCivil = nuevoPaciente.estadoCivil ? ((typeof nuevoPaciente.estadoCivil === 'string')) ? nuevoPaciente.estadoCivil : (Object(nuevoPaciente.estadoCivil).id) : null; + pacienteGuardar.genero = nuevoPaciente.genero ? ((typeof nuevoPaciente.genero === 'string')) ? nuevoPaciente.genero : (Object(nuevoPaciente.genero).id) : pacienteGuardar.sexo; + pacienteGuardar.tipoIdentificacion = nuevoPaciente.tipoIdentificacion ? ((typeof nuevoPaciente.tipoIdentificacion === 'string')) ? nuevoPaciente.tipoIdentificacion : (Object(nuevoPaciente.tipoIdentificacion).id) : null; pacienteGuardar.contacto.map(elem => { elem.tipo = ((typeof elem.tipo === 'string') ? elem.tipo : (Object(elem.tipo).id)); return elem; }); - this.pacienteService.save(pacienteGuardar).subscribe( - (resultadoSave: any) => { + return pacienteGuardar; + } + + prepararPacienteConDNI(nuevoPaciente: IPaciente, ignoreSuggestions: boolean) { + const paciente = { + ...this.pacienteBase, + id: nuevoPaciente.id, + nombre: nuevoPaciente.nombre, + alias: nuevoPaciente.alias, + apellido: nuevoPaciente.apellido, + sexo: nuevoPaciente.sexo, + genero: nuevoPaciente.genero, + fechaNacimiento: nuevoPaciente.fechaNacimiento, + documento: nuevoPaciente.documento, + estadoCivil: nuevoPaciente.estadoCivil, + direccion: nuevoPaciente.direccion, + lugarNacimiento: nuevoPaciente.lugarNacimiento, + notas: nuevoPaciente.notas, + contacto: nuevoPaciente.contacto, + documentos: nuevoPaciente.documentos, + relaciones: nuevoPaciente.relaciones, + estado: nuevoPaciente.estado, + }; + + return this.prepararPaciente(paciente, ignoreSuggestions); + } + + guardarPaciente(nuevoPaciente: IPaciente) { + return this.pacienteService.save(nuevoPaciente).pipe( + first(), filter((resultadoSave: any) => { // Existen sugerencias de pacientes similares? if (resultadoSave.sugeridos) { this.pacientesSimilares = this.escaneado || this.validado ? resultadoSave.sugeridos.filter(elem => elem.paciente.estado === 'validado') : resultadoSave.sugeridos; @@ -316,6 +364,9 @@ export class PacienteComponent implements OnInit { this.plex.info('warning', 'Existen pacientes similares, verifique las sugerencias'); } this.setMainSize(null); + + return null; + } else { if (this.changeRelaciones) { this.saveRelaciones(resultadoSave); @@ -323,16 +374,68 @@ export class PacienteComponent implements OnInit { if (this.activacionMobilePendiente) { this.datosContacto.activarAppMobile(resultadoSave, this.dataMobile); } + this.historialBusquedaService.add(resultadoSave); - this.plex.info('success', 'Los datos se actualizaron correctamente'); - this.redirect(resultadoSave); + return resultadoSave; } - }, - error => { - this.plex.info('warning', 'Error guardando el paciente'); } - ); + )); + } + + success(resultadoSave?: any) { + this.plex.info('success', 'Los datos se actualizaron correctamente'); + this.redirect(resultadoSave); + } + + mergePaciente(pacienteModel, pacienteExtranjero) { + if (pacienteExtranjero) { + const { nombre, apellido, fechaNacimiento, tipoIdentificacion, numeroIdentificacion, sexo, genero } = pacienteExtranjero; + return { ...pacienteModel, nombre, apellido, fechaNacimiento, tipoIdentificacion, numeroIdentificacion, sexo, genero }; + } else { return pacienteModel; }; + } + + save(ignoreSuggestions = false) { + const esExtranjero = this.pacienteExtranjero?.numeroIdentificacion || this.pacienteExtranjero?.tipoIdentificacion; + + if (esExtranjero && this.registroDNI) { + const pacienteConDNI = this.prepararPacienteConDNI(Object.assign({}, this.pacienteModel), ignoreSuggestions); + const pacienteExtranjero = this.prepararPaciente(this.pacienteExtranjero, ignoreSuggestions); + + if (pacienteConDNI && pacienteConDNI?.id === pacienteExtranjero?.id) { + this.guardarPaciente({ ...pacienteConDNI, id: null }).subscribe((paciente) => { + if (paciente) { + this.pacienteService.linkPatient(paciente, pacienteExtranjero).subscribe(() => { + this.historialBusquedaService.delete(pacienteExtranjero); + this.success(paciente); + }); + } + }); + } else { + this.pacienteService.linkPatient(pacienteConDNI, pacienteExtranjero).subscribe(() => { + this.historialBusquedaService.delete(pacienteExtranjero); + this.success(pacienteConDNI); + }); + } + } else { + const paciente = this.prepararPaciente(this.mergePaciente(this.pacienteModel, this.pacienteExtranjero), ignoreSuggestions); + + if (paciente) { + this.guardarPaciente(paciente).subscribe((paciente) => { + const vinculado = this.pacienteVinculadoCache.getPacienteValor(); + + if (vinculado) { + this.pacienteService.linkPatient(paciente, vinculado).subscribe(() => { + this.success(paciente); + this.pacienteVinculadoCache.clearPaciente(); + this.pacienteCache.clearScanState(); + }); + } else { + this.success(paciente); + } + }); + } + } } private redirect(resultadoSave?: any) { @@ -469,6 +572,12 @@ export class PacienteComponent implements OnInit { if (data.relaciones) { this.actualizarRelaciones(data); } + if (data.pacienteExtranjero) { + this.pacienteExtranjero = data.pacienteExtranjero; + } + if (data.registroDNI !== undefined) { + this.registroDNI = data.registroDNI; + } } documentos(documentosNew) { this.pacienteModel.documentos = documentosNew; @@ -519,19 +628,26 @@ export class PacienteComponent implements OnInit { estado: 'validado', activo: true }).pipe( + map((resultado: any) => { - if (!this.pacienteModel.id) { + if (!this.pacienteModel.id || (this.tipoPaciente === 'extranjero' && !this.validado)) { // Si estamos creando un nuevo paciente, chequeamos si existe un paciente validado con igual documento y sexo if (resultado.length && resultado[0].documento === this.pacienteModel.documento.toString()) { // El paciente que se intenta validar ya existe this.loading = false; - this.plex.info('info', 'El paciente que está cargando ya existe en el sistema', 'Atención'); + this.plex.info('warning', 'El paciente que está cargando ya existe en el sistema', 'Atención'); this.paciente = resultado[0]; this.actualizarDatosPaciente(); this.setMainSize(this.activeTab); + + if (this.tipoPaciente === 'extranjero') { + this.disableGuardar = true; + } + return true; } } + return false; }), mergeMap((validado: any) => { @@ -586,6 +702,11 @@ export class PacienteComponent implements OnInit { if (!this.pacienteModel.cuil && resultado.cuil) { this.pacienteModel.cuil = resultado.cuil; } + + if (this.tipoPaciente === 'extranjero') { + this.disableGuardar = false; + } + this.plex.toast('success', '¡Paciente Validado!'); } // error diff --git a/src/app/core/mpi/components/paciente.html b/src/app/core/mpi/components/paciente.html index 3f2b97e812..94b6de6d03 100644 --- a/src/app/core/mpi/components/paciente.html +++ b/src/app/core/mpi/components/paciente.html @@ -5,7 +5,7 @@ - @@ -15,7 +15,7 @@ label="Ignorar y Guardar" type="warning" position="right" [validateForm]="formulario" (click)="save($event,true)"> - @@ -25,8 +25,6 @@
- - @@ -65,7 +63,7 @@
- + @@ -97,8 +95,7 @@ {{ elem.paciente.estado }} - - +
diff --git a/src/app/core/mpi/services/pacienteVinculadoCache.service.ts b/src/app/core/mpi/services/pacienteVinculadoCache.service.ts new file mode 100644 index 0000000000..eefea60434 --- /dev/null +++ b/src/app/core/mpi/services/pacienteVinculadoCache.service.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { Observable } from 'rxjs'; +import { IPaciente } from '../interfaces/IPaciente'; +@Injectable() +export class PacienteVinculadoCacheService { + + private pacienteVinculadoCache = new BehaviorSubject(null); + private isScannedCache = new BehaviorSubject(null); + + setPaciente(paciente: IPaciente) { + this.pacienteVinculadoCache.next(paciente); + } + + getPacienteValor(): IPaciente { + return this.pacienteVinculadoCache.value; + } + + getPaciente(): Observable { + return this.pacienteVinculadoCache.asObservable(); + } + + clearPaciente() { + this.pacienteVinculadoCache.next(null); + } + + setScanCode(scan: string) { + this.isScannedCache.next(scan); + } + + getScan(): string { + return this.isScannedCache.value; + } + + clearScanState() { + this.isScannedCache.next(null); + } +}