744 lines
29 KiB
C#
744 lines
29 KiB
C#
using adas_core.Application.Exceptions;
|
|
using adas_core.Application.Repositories.Interfaces;
|
|
using adas_core.Application.Services.Interfaces;
|
|
using adas_core.Application.Subscriptions;
|
|
using adas_core.Domain.Enums;
|
|
using adas_core.Domain.Models;
|
|
using adas_core.Domain.Models.DTO;
|
|
using adas_core.Domain.Models.Masters;
|
|
using adas_core.Domain.Models.MongoModels;
|
|
using adas_core.Domain.Models.Responses;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Logging;
|
|
using MongoDB.Bson;
|
|
|
|
namespace adas_core.Application.Services;
|
|
|
|
public class AdmissionService(
|
|
ILogger<AdmissionService> logger,
|
|
ISubscribersService subscribersService,
|
|
IAdmissionRepository admissionRepository,
|
|
IClientMessageService clientMessageService,
|
|
IUnitService unitService,
|
|
IPatientService patientService,
|
|
IPointOfCareService pointOfCareService,
|
|
IDisplayService displayService,
|
|
IDischargeService dischargeService,
|
|
IPatientArchiveRepository patientArchiveRepository,
|
|
IHttpContextAccessor httpContextAccessor,
|
|
ILocalAuditService auditService,
|
|
IMasterListServiceFactory masterListServiceFactory)
|
|
: IAdmissionService
|
|
{
|
|
// Auditory logs
|
|
|
|
|
|
public async Task DeleteAdmissionAsync(Admission admission)
|
|
{
|
|
await DeleteAdmissionByIdAsync(admission.Id);
|
|
}
|
|
|
|
public async Task DeleteAdmissionByIdAsync(ObjectId admissionId)
|
|
{
|
|
var admissionAux = await admissionRepository.FindById(admissionId);
|
|
if (admissionAux == null)
|
|
{
|
|
logger.LogInformation("Error deleting Admission not found, id: {AdmissionId} ", admissionId);
|
|
return;
|
|
}
|
|
|
|
await admissionRepository.Delete(admissionId);
|
|
|
|
if (admissionAux.PointOfCareId.HasValue)
|
|
{
|
|
var poc = await pointOfCareService.GetInfo(admissionAux.PointOfCareId.Value);
|
|
if (poc != null && poc.AdmissionId == admissionId)
|
|
{
|
|
poc.AdmissionId = null;
|
|
poc.Admission = null;
|
|
await pointOfCareService.Update(poc);
|
|
|
|
|
|
if (poc.Status != StatusEnum.PointOfCare.Locked && poc.Status != StatusEnum.PointOfCare.InUse)
|
|
await pointOfCareService.SetPointOfCareStatus(poc.Id, StatusEnum.PointOfCare.Available);
|
|
}
|
|
}
|
|
|
|
logger.LogInformation("Admission id: {AdmissionId} DELETED ", admissionId);
|
|
|
|
SendAdmissionBroadcast(admissionAux, OperationType.DeleteAdmission);
|
|
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, admissionAux, null);
|
|
}
|
|
|
|
public async Task DeleteAdmissionsByUnitId(ObjectId unitId)
|
|
{
|
|
_ = await admissionRepository.DeleteAdmissionsByUnitId(unitId);
|
|
}
|
|
|
|
|
|
public async Task<Admission?> GetAdmissionByIdAsync(ObjectId admissionId)
|
|
{
|
|
var result = await admissionRepository.FindById(admissionId);
|
|
if (result?.PointOfCareId != null)
|
|
{
|
|
var poc = await pointOfCareService.GetInfo(result.PointOfCareId.Value, null,false);
|
|
result.PatientLocation = new PatientLocation(poc?.UnitName, poc?.Bed, poc?.Room);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<IEnumerable<Admission>> GetAdmissionsAsync()
|
|
{
|
|
var resultList = await admissionRepository.FindAll() ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
var admissionsAsync = resultList.ToList();
|
|
foreach (var admission in admissionsAsync)
|
|
if (admission.PointOfCareId != null)
|
|
{
|
|
var poc = await pointOfCareService.GetInfo(admission.PointOfCareId.Value, null,false);
|
|
admission.PatientLocation = new PatientLocation(poc?.UnitName, poc?.Bed, poc?.Room);
|
|
}
|
|
|
|
return admissionsAsync;
|
|
}
|
|
|
|
public async Task<Admission?> InsertAdmission(Admission admission)
|
|
{
|
|
var admissionAux = await admissionRepository.FindByNhc(admission.Nhc);
|
|
if (admissionAux != null) throw new ConflictException(HttpEnum.ErrorMessage.BadRequestDuplicateData);
|
|
PointOfCare? pointOfCare = null;
|
|
//Bloqueamos el pointOfCare en el caso de que lo tenga asignado
|
|
if (admission.PointOfCareId.HasValue)
|
|
{
|
|
pointOfCare = await pointOfCareService.GetInfo(admission.PointOfCareId.Value) ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
|
|
//pointOfCare.AdmissionId = admission.Id;
|
|
//pointOfCare.Admission = admission;
|
|
admission.PatientLocation = new PatientLocation(pointOfCare.UnitName, pointOfCare.Bed, pointOfCare.Room);
|
|
}
|
|
|
|
var insertedAdmission = await admissionRepository.InsertOneAsyncAndReturn(admission) ??
|
|
throw new ConflictException(HttpEnum.ErrorMessage.ConflictCreationFailed);
|
|
|
|
if (pointOfCare is { AdmissionId: null })
|
|
{
|
|
pointOfCare.Admission = insertedAdmission;
|
|
pointOfCare.AdmissionId = insertedAdmission.Id;
|
|
if (pointOfCare.Status == StatusEnum.PointOfCare.Available)
|
|
pointOfCare.Status = StatusEnum.PointOfCare.Reserved;
|
|
|
|
await pointOfCareService.Update(pointOfCare);
|
|
}
|
|
|
|
SendAdmissionBroadcast(insertedAdmission, OperationType.NewAdmission);
|
|
// Obtener información el usuario autenticado
|
|
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, null, insertedAdmission);
|
|
|
|
return insertedAdmission;
|
|
}
|
|
|
|
public async Task UpdateAdmissionAsync(Admission admission)
|
|
{
|
|
var oldAdmission = await admissionRepository.FindById(admission.Id);
|
|
if (oldAdmission == null) return;
|
|
if (oldAdmission.PointOfCareId.HasValue)
|
|
{
|
|
var pocOld = await pointOfCareService.GetInfo(oldAdmission.PointOfCareId.Value, null,false);
|
|
if (pocOld != null)
|
|
oldAdmission.PatientLocation = new PatientLocation(pocOld.UnitName, pocOld.Bed, pocOld.Room);
|
|
}
|
|
|
|
if (admission.PointOfCareId.HasValue)
|
|
{
|
|
var poc = await pointOfCareService.GetInfo(admission.PointOfCareId.Value, null,false);
|
|
if (poc != null) admission.PatientLocation = new PatientLocation(poc.UnitName, poc.Bed, poc.Room);
|
|
}
|
|
|
|
await admissionRepository.Update(admission);
|
|
|
|
await HandlePointOfCareChange(admission, oldAdmission);
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldAdmission, admission);
|
|
SendAdmissionBroadcast(admission, OperationType.UpdateAdmission);
|
|
}
|
|
|
|
public async Task AdmitPatient(Admission admission, bool isNew = false)
|
|
{
|
|
if (admission.PointOfCareId == null)
|
|
{
|
|
logger.LogError("PointOfCare is required. Admission: {Admission}", admission);
|
|
return;
|
|
}
|
|
|
|
var unit = await unitService.FindById(admission.UnitId);
|
|
if (unit == null)
|
|
{
|
|
logger.LogError("Unit {Name} not found. Unit Id: ", admission.UnitId);
|
|
return;
|
|
}
|
|
|
|
var pointOfCare = await pointOfCareService.FindById(admission.PointOfCareId.Value);
|
|
if (pointOfCare == null)
|
|
{
|
|
logger.LogError("Point of Care not found. Patient not created. {Admission}", admission);
|
|
return;
|
|
}
|
|
|
|
|
|
Patient patient = new()
|
|
{
|
|
PointOfCareId = pointOfCare.Id,
|
|
UnitId = pointOfCare.UnitId,
|
|
PointOfCare = pointOfCare,
|
|
UnitString = pointOfCare.UnitName,
|
|
Bed = pointOfCare.Bed,
|
|
Room = pointOfCare.Room,
|
|
PatientNumber = admission.Nhc,
|
|
AdmTime = DateTime.UtcNow,
|
|
Person = admission.Person,
|
|
CreationDate = DateTime.UtcNow,
|
|
DischargeStatus = pointOfCare.Unit?.DischargeStatusList?.Options.FirstOrDefault(),
|
|
Origin = admission.Origin,
|
|
OriginAux = admission.OriginAux,
|
|
Diagnosis = admission.Diagnosis,
|
|
DiagnosisAux = admission.DiagnosisAux,
|
|
Allergies = admission.Allergies,
|
|
Insulation = admission.Insulation,
|
|
LanguageBarrier = admission.LanguageBarrier,
|
|
PassiveSitting = admission.PassiveSitting,
|
|
Altable = new OptionList
|
|
{
|
|
Name = "NotAltable",
|
|
IconDefault = "icNotAltable",
|
|
OptionType = "NotAltable"
|
|
},
|
|
Visits = pointOfCare.Unit?.VisitOptionList?.Options.FirstOrDefault(),
|
|
AccessControl = pointOfCare.Unit?.AccessControlList?.Options.FirstOrDefault(),
|
|
Location = new PatientLocation
|
|
(
|
|
unit.Name,
|
|
pointOfCare.Bed,
|
|
pointOfCare.Room
|
|
)
|
|
};
|
|
if (unit.AltableOptionListId is not null)
|
|
{
|
|
var list = await masterListServiceFactory.GetMasterListById(MasterListType.AltableOptionList,
|
|
unit.AltableOptionListId.Value, LocaleEnum.Default) as AltableOptionList;
|
|
var listOpt = list?.Options.FirstOrDefault(c => c.OptionType == "NotAltable");
|
|
if (listOpt != null)
|
|
patient.Altable = listOpt;
|
|
}
|
|
|
|
await patientService.Insert(patient);
|
|
await SetPointOfCareStatus(pointOfCare.Id, StatusEnum.PointOfCare.InUse);
|
|
|
|
if (!isNew)
|
|
await DeleteAdmissionAsync(admission);
|
|
|
|
if (admission.Insulation != null)
|
|
await patientService.UpdatePatientMasterList(
|
|
patient.Id,
|
|
MasterListType.InsulationList,
|
|
[admission.Insulation],
|
|
null, null);
|
|
|
|
if (admission.Allergies != null)
|
|
await patientService.UpdatePatientMasterList(
|
|
patient.Id,
|
|
MasterListType.AllergyList,
|
|
admission.Allergies,
|
|
null, null);
|
|
if (admission.Diagnosis != null)
|
|
await patientService.UpdatePatientMasterList(
|
|
patient.Id,
|
|
MasterListType.DiagnosisList,
|
|
[admission.Diagnosis],
|
|
null, null);
|
|
if (admission.Origin != null)
|
|
await patientService.UpdatePatientMasterList(
|
|
patient.Id,
|
|
MasterListType.OriginList,
|
|
[admission.Origin],
|
|
null, null);
|
|
if (admission.LanguageBarrier != null)
|
|
await patientService.UpdatePatientMasterList(
|
|
patient.Id,
|
|
MasterListType.LanguageBarrierList,
|
|
admission.LanguageBarrier,
|
|
null, null);
|
|
if (admission.PassiveSitting != null)
|
|
await patientService.UpdatePatientMasterList(
|
|
patient.Id,
|
|
MasterListType.PassiveSittingList,
|
|
[admission.PassiveSitting],
|
|
null, null);
|
|
}
|
|
|
|
public async Task ReturnPatientToAdmissions(ObjectId patientId)
|
|
{
|
|
var patient = await patientService.FindById(patientId);
|
|
if (patient == null)
|
|
{
|
|
logger.LogError("Error returning the patient Id: {Id} to admission", patientId);
|
|
return;
|
|
}
|
|
|
|
var unit = await unitService.FindById(patient.UnitId);
|
|
if (unit == null)
|
|
{
|
|
logger.LogError("Unit not found by Id. {Name}", patient.UnitId);
|
|
return;
|
|
}
|
|
|
|
if (patient.PointOfCareId != null)
|
|
{
|
|
var poc = await pointOfCareService.FindById(patient.PointOfCareId.Value);
|
|
Admission admission = new()
|
|
{
|
|
Nhc = patient.PatientNumber ?? string.Empty,
|
|
PointOfCareId = poc?.Id,
|
|
UnitId = unit.Id,
|
|
Person = patient.Person ??
|
|
new Person(), //No debería ser null en este punto, pero así quito el warning
|
|
Origin = patient.Origin,
|
|
OriginAux = patient.OriginAux,
|
|
Diagnosis = patient.Diagnosis,
|
|
PassiveSitting = patient.PassiveSitting,
|
|
DiagnosisAux = patient.DiagnosisAux,
|
|
Allergies = patient.Allergies,
|
|
Insulation = patient.Insulation,
|
|
LanguageBarrier = patient.LanguageBarrier,
|
|
AdmissionDate = patient.AdmTime ?? DateTime.UtcNow,
|
|
PatientLocation = patient.Location
|
|
};
|
|
|
|
await InsertAdmission(admission);
|
|
}
|
|
|
|
var dis = await dischargeService.GetDischargeByPatientId(patient.Id);
|
|
if (dis != null) await dischargeService.DeleteDischargeByIdAsync(dis.Id);
|
|
await patientService.ArchivePatient(patient);
|
|
|
|
pointOfCareService.CheckNextAdmission(patient.PointOfCareId);
|
|
}
|
|
|
|
// Used for temporal beds like PUSHED
|
|
public async Task ReturnPatientToAdmissions(ObjectId patientId, Admission adm)
|
|
{
|
|
var patient = await patientService.FindById(patientId);
|
|
if (patient == null)
|
|
{
|
|
logger.LogError("Error returning the patient Id: {Id} to admission", patientId);
|
|
return;
|
|
}
|
|
|
|
|
|
var unit = await unitService.FindById(adm.UnitId);
|
|
if (unit == null)
|
|
{
|
|
logger.LogError("Unit not found by Id. {Name}", patient.UnitId);
|
|
return;
|
|
}
|
|
|
|
if (adm.PointOfCareId != null)
|
|
{
|
|
var poc = await pointOfCareService.FindById(adm.PointOfCareId.Value);
|
|
Admission admission = new()
|
|
{
|
|
Nhc = patient.PatientNumber ?? string.Empty,
|
|
PointOfCareId = poc?.Id,
|
|
UnitId = unit.Id,
|
|
Person = patient.Person ??
|
|
new Person(), //No debería ser null en este punto, pero así quito el warning
|
|
Origin = patient.Origin,
|
|
OriginAux = patient.OriginAux,
|
|
Diagnosis = patient.Diagnosis,
|
|
DiagnosisAux = patient.DiagnosisAux,
|
|
Allergies = patient.Allergies,
|
|
PassiveSitting = patient.PassiveSitting,
|
|
Insulation = patient.Insulation,
|
|
LanguageBarrier = patient.LanguageBarrier,
|
|
AdmissionDate = patient.AdmTime ?? DateTime.UtcNow,
|
|
PatientLocation = patient.Location
|
|
};
|
|
|
|
await InsertAdmission(admission);
|
|
}
|
|
|
|
var dis = await dischargeService.GetDischargeByPatientId(patient.Id);
|
|
if (dis != null) await dischargeService.DeleteDischargeByIdAsync(dis.Id);
|
|
await patientService.ArchivePatient(patient);
|
|
|
|
pointOfCareService.CheckNextAdmission(patient.PointOfCareId);
|
|
}
|
|
|
|
public async Task<List<Admission>> GetAdmissionByLocation(PatientLocation location)
|
|
{
|
|
try
|
|
{
|
|
return await admissionRepository.FindByLocation(location);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
logger.LogError("Error getting admission by patient location {Location} exception: {Ex}", location,
|
|
e.Message);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public async Task<List<Admission>> GetAdmissionByPointOfCareId(ObjectId pocId)
|
|
{
|
|
try
|
|
{
|
|
var result = await admissionRepository.FindByPointOfCareId(pocId);
|
|
foreach (var admission in result)
|
|
{
|
|
var poc = await pointOfCareService.GetInfo(pocId, null,false);
|
|
if (poc != null) admission.PatientLocation = new PatientLocation(poc.UnitName, poc.Bed, poc.Room);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
logger.LogError("Error getting admission by patient PocId {PocId} exception: {Ex}", pocId, e.Message);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public async Task<List<Admission>> GetAdmissionByPointOfCareIdAndLocale(ObjectId pocId, LocaleEnum locale)
|
|
{
|
|
var admissions = await GetAdmissionByPointOfCareId(pocId);
|
|
|
|
// Ejecutar todas las traducciones en paralelo
|
|
var translatedAdmissions = await Task.WhenAll(
|
|
admissions.Select(adm => GetAdmissionWithLocale(adm, locale))
|
|
);
|
|
|
|
return translatedAdmissions.ToList();
|
|
}
|
|
|
|
public async Task<List<Admission>> GetAdmissionByUnitIdWithOutPoC(ObjectId unitId)
|
|
{
|
|
try
|
|
{
|
|
return await admissionRepository.GetAdmissionByUnitIdWithOutPoC(unitId);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
logger.LogError("Error getting admission by unitId with out PoCId {UnitId} exception: {Ex}", unitId,
|
|
e.Message);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public async Task<long> CountAdmissionsByUnitId(ObjectId unitId)
|
|
{
|
|
try
|
|
{
|
|
return await admissionRepository.CountByUnitId(unitId);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
logger.LogError("Error getting admission by unitId with out PoCId {UnitId} exception: {Ex}", unitId,
|
|
e.Message);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public async Task<PatientSearch?> SearchByPatientNumberAndDistinctUnit(string patientNumber, ObjectId unitId)
|
|
{
|
|
var patient = await patientService.FindByPatientNumber(patientNumber);
|
|
if (patient != null)
|
|
{
|
|
if (patient.PointOfCareId.HasValue)
|
|
patient.PointOfCare = await pointOfCareService.FindById(patient.PointOfCareId.Value);
|
|
if (patient.UnitId.HasValue)
|
|
{
|
|
var uni = await unitService.FindById(patient.UnitId.Value);
|
|
if (uni != null)
|
|
patient.UnitString = uni.Name;
|
|
}
|
|
}
|
|
|
|
var archivePatient =
|
|
await patientArchiveRepository.SearchByPatientNumberAndDistinctUnit(patientNumber, unitId);
|
|
var admission = await admissionRepository.SearchByPatientNumberAndDistinctUnit(patientNumber, unitId);
|
|
|
|
var result = new PatientSearch(patient, archivePatient, admission,
|
|
patient == null && archivePatient != null,
|
|
patient != null || archivePatient != null || admission != null);
|
|
return result;
|
|
}
|
|
|
|
public Task<Admission?> GetAdmissionByPatientNumber(string patientNumber)
|
|
{
|
|
return admissionRepository.FindByNhc(patientNumber);
|
|
}
|
|
|
|
public async Task UpdatePatientMasterListItemChange(UpdateOptionMasterListDto opt, IEnumerable<Unit> unitList,
|
|
string typeName)
|
|
{
|
|
var unitIds = unitList.Select(x => x.Id).ToList();
|
|
var oldAdmissionList = await admissionRepository.FindByUnitIds(unitIds);
|
|
var admissionUpdatedList = await admissionRepository.UpdateMasterListOption(unitIds, opt, typeName);
|
|
foreach (var admission in admissionUpdatedList)
|
|
{
|
|
var oldAdmission = oldAdmissionList.Find(adm => adm.Id == admission.Id);
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldAdmission!, admission);
|
|
SendAdmissionBroadcast(admission, OperationType.UpdateAdmission);
|
|
}
|
|
}
|
|
|
|
public async Task DeletePatientMasterListItem(OptionList opt, IEnumerable<Unit> unitList, string typeName)
|
|
{
|
|
var unitIds = unitList.Select(x => x.Id).ToList();
|
|
var oldAdmissionList = await admissionRepository.FindByUnitIds(unitIds);
|
|
var admissionUpdatedList = await admissionRepository.DeleteMasterListOption(unitIds, opt, typeName);
|
|
foreach (var admission in admissionUpdatedList)
|
|
{
|
|
var admissionUpdated = await GetAdmissionByIdAsync(admission.Id);
|
|
var oldAdmission = oldAdmissionList.Find(adm => adm.Id == admission.Id);
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldAdmission!,
|
|
admissionUpdated);
|
|
if (admissionUpdated != null)
|
|
SendAdmissionBroadcast(admissionUpdated, OperationType.UpdateAdmission);
|
|
}
|
|
}
|
|
|
|
public async Task SaveRequest(ApiRequest apiRequest)
|
|
{
|
|
try
|
|
{
|
|
if (apiRequest.Admission == null)
|
|
return;
|
|
|
|
switch (apiRequest.Type)
|
|
{
|
|
case "NewAdmission":
|
|
{
|
|
if (string.IsNullOrEmpty(apiRequest.Admission.Nhc) ||
|
|
apiRequest.Admission.Origin == null ||
|
|
apiRequest.Admission.Diagnosis == null)
|
|
{
|
|
logger.LogDebug(
|
|
"Error saving admission api request. Some values are required. Admission: {Admission}",
|
|
apiRequest.Admission);
|
|
return;
|
|
}
|
|
|
|
await InsertAdmission(apiRequest.Admission);
|
|
break;
|
|
}
|
|
case "UpdateAdmission":
|
|
{
|
|
if (string.IsNullOrEmpty(apiRequest.Admission.Nhc) ||
|
|
apiRequest.Admission.Origin == null ||
|
|
apiRequest.Admission.Diagnosis == null)
|
|
{
|
|
logger.LogDebug(
|
|
"Error updating admission api request. Some values are required. Admission: {Admission}",
|
|
apiRequest.Admission);
|
|
return;
|
|
}
|
|
|
|
await UpdateAdmissionAsync(apiRequest.Admission);
|
|
break;
|
|
}
|
|
case "DeleteAdmission":
|
|
{
|
|
await DeleteAdmissionAsync(apiRequest.Admission);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogError("Exception updating admission {Admission} . Exception: {Ex}", apiRequest.Admission,
|
|
ex.Message);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public Task SaveRequestAsync(ApiRequest apiRequest)
|
|
{
|
|
return Task.FromResult(Task.Run(async () => { await SaveRequest(apiRequest); }));
|
|
}
|
|
|
|
private async Task HandlePointOfCareChange(Admission admission, Admission oldAdmission)
|
|
{
|
|
// Check if PointOfCare has changed.
|
|
if (admission.PointOfCareId == oldAdmission.PointOfCareId) return;
|
|
|
|
// Disable new PointOfCare if it exists.
|
|
if (admission.PointOfCareId.HasValue)
|
|
{
|
|
var newPoc = await pointOfCareService.GetInfo(admission.PointOfCareId.Value);
|
|
if (newPoc == null) return;
|
|
|
|
var patientOnNewPoc = await patientService.FindByPointOfCareId(newPoc.Id);
|
|
if (newPoc.AdmissionId == null && newPoc.Status != StatusEnum.PointOfCare.Locked)
|
|
{
|
|
newPoc.Admission = admission;
|
|
newPoc.AdmissionId = admission.Id;
|
|
newPoc.Status = patientOnNewPoc != null
|
|
? StatusEnum.PointOfCare.InUse
|
|
: StatusEnum.PointOfCare.Reserved;
|
|
|
|
await pointOfCareService.Update(newPoc);
|
|
}
|
|
|
|
if (newPoc.Status == StatusEnum.PointOfCare.Available)
|
|
pointOfCareService.CheckNextAdmission(newPoc.Id);
|
|
}
|
|
|
|
// Enable previous PointOfCare if it exists.
|
|
if (oldAdmission.PointOfCareId.HasValue)
|
|
{
|
|
var oldPoc = await pointOfCareService.GetInfo(oldAdmission.PointOfCareId.Value);
|
|
if (oldPoc != null)
|
|
{
|
|
var patientOnOldPoc = await patientService.FindByPointOfCareId(oldPoc.Id);
|
|
if (oldPoc.AdmissionId == oldAdmission.Id && oldPoc.Status != StatusEnum.PointOfCare.Locked)
|
|
{
|
|
oldPoc.Admission = null;
|
|
oldPoc.AdmissionId = null;
|
|
oldPoc.Status = patientOnOldPoc != null
|
|
? StatusEnum.PointOfCare.InUse
|
|
: StatusEnum.PointOfCare.Available;
|
|
|
|
await pointOfCareService.Update(oldPoc);
|
|
}
|
|
}
|
|
|
|
if (oldPoc is { Status: StatusEnum.PointOfCare.Available })
|
|
pointOfCareService.CheckNextAdmission(oldPoc.Id);
|
|
}
|
|
}
|
|
|
|
private async Task SetPointOfCareStatus(ObjectId pointOfCareId, StatusEnum.PointOfCare status)
|
|
{
|
|
var pointOfCare = await pointOfCareService.FindById(pointOfCareId);
|
|
if (pointOfCare == null) return;
|
|
|
|
await pointOfCareService.SetPointOfCareStatus(pointOfCareId, status);
|
|
}
|
|
|
|
private async void SendAdmissionBroadcast(Admission admission, OperationType operation)
|
|
{
|
|
try
|
|
{
|
|
if (admission.PointOfCareId == null)
|
|
await SendAdmissionByUnitId(admission, operation);
|
|
else
|
|
await SendAdmissionBroadcastByPoC(admission, operation);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogError("Exception sending admission broadcast. Operation type: {Op}. Exception: {Ex}",
|
|
operation.ToString(), ex.Message);
|
|
}
|
|
}
|
|
|
|
private async Task SendAdmissionBroadcastByPoC(Admission admission, OperationType operation)
|
|
{
|
|
if (!admission.PointOfCareId.HasValue)
|
|
{
|
|
logger.LogError("Error sending admission broadcast. PointOfCare id {Id} not found",
|
|
admission.PointOfCareId);
|
|
return;
|
|
}
|
|
|
|
var pointOfCare = await pointOfCareService.FindById(admission.PointOfCareId.Value);
|
|
if (pointOfCare == null)
|
|
{
|
|
logger.LogError("Error sending admission broadcast. PointOfCare id {Id} not found",
|
|
admission.PointOfCareId);
|
|
return;
|
|
}
|
|
|
|
var pocSubscribers = subscribersService.GetSubscribers().Where(s =>
|
|
s.LocationIds.Contains(admission.PointOfCareId.Value)).GroupBy(h => h.Locale);
|
|
|
|
foreach (var group in pocSubscribers)
|
|
{
|
|
var locale = group.Key ?? LocaleEnum.Default;
|
|
IEnumerable<WsSubscriber> subscribers = group;
|
|
|
|
foreach (var subscriber in subscribers)
|
|
{
|
|
var admissionWithLocale = await GetAdmissionWithLocale(admission, locale);
|
|
_ = clientMessageService.SendAsync(subscriber.Id, operation, admissionWithLocale);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task SendAdmissionByUnitId(Admission admission, OperationType operation)
|
|
{
|
|
if (admission.UnitId == ObjectId.Empty)
|
|
{
|
|
logger.LogError("Error sending admission broadcast. UnitId is null or empty {Admission}", admission);
|
|
return;
|
|
}
|
|
|
|
var displays = await displayService.GetByUnitId(admission.UnitId);
|
|
var displayIds = displays.Select(c => c.Id).ToList();
|
|
var unitSubscribers = subscribersService.GetSubscribers().Where(s =>
|
|
s.DisplayId != null && displayIds.Contains(s.DisplayId.Value)).GroupBy(h => h.Locale);
|
|
foreach (var group in unitSubscribers)
|
|
{
|
|
var locale = group.Key ?? LocaleEnum.Default;
|
|
IEnumerable<WsSubscriber> subscribers = group;
|
|
|
|
foreach (var subscriber in subscribers)
|
|
{
|
|
var admissionWithLocale = await GetAdmissionWithLocale(admission, locale);
|
|
_ = clientMessageService.SendAsync(subscriber.Id, operation, admissionWithLocale);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task<Admission> GetAdmissionWithLocale(Admission admission, LocaleEnum locale)
|
|
{
|
|
var unit = await unitService.FindById(admission.UnitId);
|
|
if (unit == null) return admission;
|
|
if (admission.Origin?.Name != null && unit.OriginListId.HasValue)
|
|
{
|
|
if (await masterListServiceFactory.GetMasterListById(MasterListType.OriginList,
|
|
unit.OriginListId.Value, locale) is OriginList list)
|
|
{
|
|
var listOrigin = list.Options.FirstOrDefault(c => c.Id == admission.Origin.Id)?.Name;
|
|
if (listOrigin != null)
|
|
admission.Origin.Name = listOrigin;
|
|
}
|
|
}
|
|
|
|
if (admission.Diagnosis?.Name != null && unit.DiagnosisListId.HasValue)
|
|
{
|
|
if (await masterListServiceFactory.GetMasterListById(MasterListType.DiagnosisList,
|
|
unit.DiagnosisListId.Value, locale) is DiagnosisList list)
|
|
{
|
|
var listDiagnosis = list.Options.FirstOrDefault(c => c.Id == admission.Diagnosis.Id)?.Name;
|
|
if (listDiagnosis != null)
|
|
admission.Diagnosis.Name = listDiagnosis;
|
|
}
|
|
}
|
|
|
|
if (admission.Insulation?.Name != null && unit.InsulationListId.HasValue)
|
|
{
|
|
if (await masterListServiceFactory.GetMasterListById(MasterListType.InsulationList,
|
|
unit.InsulationListId.Value, locale) is InsulationList list)
|
|
{
|
|
var listInsulation = list.Options.FirstOrDefault(c => c.Id == admission.Insulation.Id)?.Name;
|
|
if (listInsulation != null)
|
|
admission.Insulation.Name = listInsulation;
|
|
}
|
|
}
|
|
|
|
return admission;
|
|
}
|
|
} |