434 lines
18 KiB
C#
434 lines
18 KiB
C#
using adas_core.Application.Exceptions;
|
|
using adas_core.Application.Repositories.Interfaces;
|
|
using adas_core.Application.Services.Interfaces;
|
|
using adas_core.Domain.Enums;
|
|
using adas_core.Domain.Models;
|
|
using adas_core.Domain.Models.DTO;
|
|
using adas_core.Domain.Models.Filter;
|
|
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;
|
|
using MongoDB.Driver;
|
|
using Serilog;
|
|
|
|
namespace adas_core.Application.Services;
|
|
|
|
public class UnitService(
|
|
IUnitRepository unitRepository,
|
|
Lazy<IPatientService> patientService,
|
|
ILogger<UnitService> logger,
|
|
IMasterListServiceFactory masterListServiceFactory,
|
|
ISubscribersService subscribersService,
|
|
Lazy<IClientMessageService> clientMessageService,
|
|
IPointOfCareService pointOfCareService,
|
|
IHttpContextAccessor httpContextAccessor,
|
|
ILocalAuditService auditService)
|
|
: IUnitService
|
|
{
|
|
public async Task<List<Unit>> GetAll(bool withPoCs = false)
|
|
{
|
|
var units = await unitRepository.GetAll();
|
|
|
|
if (withPoCs)
|
|
foreach (var unit in units)
|
|
{
|
|
var pocList = await pointOfCareService.FindAllByUnitId(unit.Id);
|
|
unit.PointOfCares = pocList?.ToList();
|
|
}
|
|
|
|
return units;
|
|
}
|
|
|
|
public async Task<List<UnitInfoDto>> GetAllCompact()
|
|
{
|
|
var units = await unitRepository.GetAll();
|
|
var result = new List<UnitInfoDto>();
|
|
foreach (var unit in units)
|
|
result.Add(new UnitInfoDto
|
|
{
|
|
Id = unit.Id,
|
|
Name = unit.Name ?? string.Empty,
|
|
Title = unit.Title ?? string.Empty
|
|
});
|
|
return result;
|
|
}
|
|
|
|
public async Task<UnitInfoDto> GetOneCompact(ObjectId id)
|
|
{
|
|
var unit = await unitRepository.FindById(id);
|
|
var result = new UnitInfoDto
|
|
{
|
|
Id = unit?.Id,
|
|
Name = unit?.Name ?? string.Empty,
|
|
Title = unit?.Title ?? string.Empty
|
|
};
|
|
return result;
|
|
}
|
|
|
|
public async Task<PaginationResponse<Unit>> GetPaginatedUnits(PaginationFilter filter, bool withPoCs = false)
|
|
{
|
|
var result = unitRepository.GetPaginatedUnits(filter);
|
|
|
|
var count = await result.CountDocumentsAsync();
|
|
|
|
var data = await result.Skip((filter.PageNumber - 1) * filter.PageSize)
|
|
.Limit(filter.PageSize)
|
|
.ToListAsync();
|
|
|
|
|
|
if (withPoCs && data.Any())
|
|
{
|
|
var unitIds = data.Select(u => u.Id).ToList();
|
|
var allPocsForUnits = await pointOfCareService.FindAllByUnitIds(unitIds);
|
|
|
|
foreach (var unit in data) unit.PointOfCares = allPocsForUnits.Where(poc => poc.UnitId == unit.Id).ToList();
|
|
}
|
|
|
|
return new PaginationResponse<Unit>(data, filter.PageNumber, filter.PageSize, count);
|
|
}
|
|
|
|
// public Task<Unit?> GetByPointOfCare(PointOfCare pointOfCare)
|
|
// {
|
|
// return _unitRepository.FindByPointOfCare(pointOfCare);
|
|
// }
|
|
|
|
public async Task<Unit?> GetInfo(ObjectId id, LocaleEnum? dataLocale, bool fillLists = true, bool withPoCs = false)
|
|
{
|
|
var unit = await Get(id.ToString()) ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
//if (unit == null )// || unit.PointOfCares == null tiene sentido?
|
|
//{
|
|
// _logger.LogError("Section not found: {id}", id);
|
|
// return null;
|
|
//}
|
|
|
|
if (fillLists)
|
|
{
|
|
if (unit.AltableOptionListId.HasValue)
|
|
unit.AltableOptionList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.AltableOptionList,
|
|
unit.AltableOptionListId.Value, dataLocale) as AltableOptionList;
|
|
if (unit.AllergyListId.HasValue)
|
|
unit.AllergyList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.AllergyList,
|
|
unit.AllergyListId.Value, dataLocale) as AllergyList;
|
|
if (unit.DestinationListId.HasValue)
|
|
unit.DestinationList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.DestinationList,
|
|
unit.DestinationListId.Value, dataLocale) as DestinationList;
|
|
if (unit.InternalDestinationListId.HasValue)
|
|
unit.InternalDestinationList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.InternalDestinationList,
|
|
unit.InternalDestinationListId.Value, dataLocale) as InternalDestinationList;
|
|
if (unit.DiagnosisListId.HasValue)
|
|
unit.DiagnosisList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.DiagnosisList,
|
|
unit.DiagnosisListId.Value, dataLocale) as DiagnosisList;
|
|
if (unit.DischargeStatusListId.HasValue)
|
|
unit.DischargeStatusList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.DischargeStatusList,
|
|
unit.DischargeStatusListId.Value, dataLocale) as DischargeStatusList;
|
|
if (unit.DoctorListId.HasValue)
|
|
unit.DoctorList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.DoctorList, unit.DoctorListId.Value,
|
|
dataLocale) as DoctorList;
|
|
if (unit.DoctorTypeListId.HasValue)
|
|
unit.DoctorTypeList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.DoctorTypeList,
|
|
unit.DoctorTypeListId.Value, dataLocale) as DoctorTypeList;
|
|
if (unit.InsulationListId.HasValue)
|
|
unit.InsulationList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.InsulationList,
|
|
unit.InsulationListId.Value, dataLocale) as InsulationList;
|
|
if (unit.MobilityOptionListId.HasValue)
|
|
unit.MobilityOptionList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.MobilityOptionList,
|
|
unit.MobilityOptionListId.Value, dataLocale) as MobilityOptionList;
|
|
if (unit.OriginListId.HasValue)
|
|
unit.OriginList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.OriginList, unit.OriginListId.Value,
|
|
dataLocale) as OriginList;
|
|
if (unit.PatientStatusListId.HasValue)
|
|
unit.PatientStatusList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.PatientStatusList,
|
|
unit.PatientStatusListId.Value, dataLocale) as PatientStatusList;
|
|
if (unit.ProcedureListId.HasValue)
|
|
unit.ProcedureList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.ProcedureList,
|
|
unit.ProcedureListId.Value, dataLocale) as ProcedureList;
|
|
if (unit.TestListId.HasValue)
|
|
unit.TestList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.TestList, unit.TestListId.Value,
|
|
dataLocale) as TestList;
|
|
if (unit.ServiceListId.HasValue)
|
|
unit.ServiceList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.ServiceList,
|
|
unit.ServiceListId.Value, dataLocale) as ServiceList;
|
|
if (unit.TherapeuticCeilingListId.HasValue)
|
|
unit.TherapeuticCeilingList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.TherapeuticCeilingList,
|
|
unit.TherapeuticCeilingListId.Value, dataLocale) as TherapeuticCeilingList;
|
|
if (unit.TreatmentListId.HasValue)
|
|
unit.TreatmentList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.TreatmentList,
|
|
unit.TreatmentListId.Value, dataLocale) as TreatmentList;
|
|
if (unit.VisitOptionListId.HasValue)
|
|
unit.VisitOptionList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.VisitOptionList,
|
|
unit.VisitOptionListId.Value, dataLocale) as VisitOptionList;
|
|
if (unit.AccessControlListId.HasValue)
|
|
unit.AccessControlList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.AccessControlList,
|
|
unit.AccessControlListId.Value, dataLocale) as AccessControlList;
|
|
if (unit.LanguageBarrierListId.HasValue)
|
|
unit.LanguageBarrierList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.LanguageBarrierList,
|
|
unit.LanguageBarrierListId.Value, dataLocale) as LanguageBarrierList;
|
|
if (unit.PassiveSittingListId.HasValue)
|
|
unit.PassiveSittingList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.PassiveSittingList,
|
|
unit.PassiveSittingListId.Value, dataLocale) as PassiveSittingList;
|
|
if (unit.GenericListId.HasValue)
|
|
unit.GenericList =
|
|
await masterListServiceFactory.GetMasterListById(MasterListType.GenericList,
|
|
unit.GenericListId.Value, dataLocale) as GenericList;
|
|
}
|
|
|
|
if (withPoCs)
|
|
{
|
|
var pocList = await pointOfCareService.FindAllByUnitId(unit.Id);
|
|
unit.PointOfCares = pocList?.ToList();
|
|
}
|
|
|
|
return unit;
|
|
}
|
|
|
|
public async Task<Unit?> GetInfo(ObjectId id, bool withPoCs = true, bool withDevices = true)
|
|
{
|
|
var unit = await Get(id.ToString()) ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
if (withPoCs)
|
|
{
|
|
var pocList = await pointOfCareService.FindAllByUnitIdWithDevices(unit.Id);
|
|
unit.PointOfCares = pocList?.ToList();
|
|
}
|
|
|
|
return unit;
|
|
}
|
|
|
|
public async Task<Unit?> GetByName(string itemUnitName)
|
|
{
|
|
return await unitRepository.FindByName(itemUnitName) ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
}
|
|
|
|
public async Task<Unit?> FindByPatientId(ObjectId patientId)
|
|
{
|
|
//var sections = await GetAll();
|
|
var patient = await patientService.Value.FindById(patientId);
|
|
// if (patient != null && !string.IsNullOrEmpty(patient.Bed) && patient.IsInActivePoC())
|
|
// {
|
|
// // Deberia ser una lista? revisar como gestionar varias unidades con eel mismo pointOfCare
|
|
// return sections.FirstOrDefault(s => s.PointOfCares.Any(c=>c.Bed==patient.Bed && c.UnitName == patient.UnitString));
|
|
// }
|
|
if (patient is { UnitId: not null }) return await FindById(patient.UnitId);
|
|
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
}
|
|
|
|
public async Task<IEnumerable<Unit>?> FindUnitsByMasterListId(ObjectId masterListId, MasterListType masterListType)
|
|
{
|
|
try
|
|
{
|
|
var result = await unitRepository.FindByMasterListId(masterListId, masterListType);
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Exception finding by MasterId{id} section exception:{e} ", masterListId, ex.Message);
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<long> CountUnitsByMasterListId(ObjectId masterListId, MasterListType masterListType)
|
|
{
|
|
return await unitRepository.CountUnitsByMasterListId(masterListId, masterListType);
|
|
}
|
|
|
|
public async Task<IEnumerable<Unit>> FindUnitsByMasterListId(ObjectId masterListId)
|
|
{
|
|
try
|
|
{
|
|
var result = await unitRepository.FindByMasterListId(masterListId);
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Exception finding by MasterId{id} section exception:{e} ", masterListId, ex.Message);
|
|
|
|
return new List<Unit>();
|
|
}
|
|
}
|
|
|
|
public async Task<Unit?> UpdateUnitMasterList(UpdateUnitIdListDto updateUnitListDto)
|
|
{
|
|
var unit = await FindById(updateUnitListDto.UnitId) ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
var updatedUnit = await unitRepository.UpdateUnitMasterList(updateUnitListDto) ??
|
|
throw new ConflictException(HttpEnum.ErrorMessage.ConflictUpdateFailed);
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, unit, updatedUnit);
|
|
return updatedUnit;
|
|
}
|
|
|
|
public async Task<bool> UpdateConfiguration(ObjectId unitIdParsed, UnitConfiguration unitConfiguration)
|
|
{
|
|
var oldConfig = await FindById(unitIdParsed) ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
var result = await unitRepository.UpdateConfiguration(unitIdParsed, unitConfiguration);
|
|
var newConfig = await FindById(unitIdParsed) ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
if (!result) throw new ConflictException(HttpEnum.ErrorMessage.ConflictUpdateFailed);
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldConfig, newConfig);
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<Unit?> FindById(ObjectId? id)
|
|
{
|
|
if (id == null)
|
|
return null;
|
|
return await unitRepository.FindById(id);
|
|
}
|
|
|
|
public async Task<Unit?> FindByName(string? name)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
return null;
|
|
return await unitRepository.FindByName(name);
|
|
}
|
|
|
|
public async Task<Unit?> FindByUnitNameOrPocName(string? name, string? pocName)
|
|
{
|
|
if (!string.IsNullOrEmpty(name))
|
|
return await unitRepository.FindByName(name);
|
|
|
|
if (!string.IsNullOrEmpty(pocName))
|
|
{
|
|
var poc = await pointOfCareService.FindByBed(pocName);
|
|
if (poc != null)
|
|
return await FindById(poc.FirstOrDefault()?.UnitId);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
// public async Task<Unit?> FindByPointOfCare(PointOfCare pointOfCare)
|
|
// {
|
|
// return await _unitRepository.FindByPointOfCare(pointOfCare);
|
|
// }
|
|
|
|
public async Task<Unit?> InsertOne(Unit unit)
|
|
{
|
|
var newUnit = await unitRepository.InsertOneUnit(unit) ??
|
|
throw new ConflictException(HttpEnum.ErrorMessage.ConflictCreationFailed);
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, null, newUnit);
|
|
return newUnit;
|
|
}
|
|
|
|
public async Task<Unit?> UpdateUnit(Unit unit)
|
|
{
|
|
var oldUnit = await FindById(unit.Id) ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
var newUnit = await unitRepository.UpdateUnit(unit);
|
|
if (newUnit == null)
|
|
return null;
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldUnit, newUnit);
|
|
|
|
SendUnitBroadcast(newUnit, OperationType.UpdateUnit);
|
|
return newUnit;
|
|
}
|
|
|
|
public async Task<Unit?> UpdateUnitInfo(ObjectId unitId, string name, string title, string? configObsId = null)
|
|
{
|
|
var oldUnit = await FindById(unitId) ??
|
|
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
|
|
var newUnit = await unitRepository.UpdateUnitInfo(unitId, name, title) ??
|
|
throw new ConflictException(HttpEnum.ErrorMessage.ConflictUpdateFailed);
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldUnit, newUnit);
|
|
|
|
if (newUnit != null) SendUnitBroadcast(newUnit, OperationType.UpdateUnit);
|
|
return newUnit;
|
|
}
|
|
|
|
public async Task<bool> DeleteUnitById(Unit unit)
|
|
{
|
|
//if (unit is not { Status: null }) throw new ConflictException(ErrorMessage.Conflict_ResourceInUse);
|
|
_ = await unitRepository.DeleteAsync(unit.Id) ??
|
|
throw new ConflictException(HttpEnum.ErrorMessage.ConflictDeleteFailed);
|
|
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, unit, null);
|
|
return true;
|
|
}
|
|
|
|
public async Task<Unit?> Get(string id)
|
|
{
|
|
Unit? section = null;
|
|
|
|
if (ObjectId.TryParse(id, out var oid)) section = await FindById(oid);
|
|
|
|
var sections = await GetAll();
|
|
|
|
section ??= sections.FirstOrDefault(s => s.Title == id);
|
|
|
|
section ??= sections.FirstOrDefault(s => s.Name == id);
|
|
|
|
return section;
|
|
}
|
|
|
|
public async Task<List<Unit>?> FindByLocation(PatientLocation location)
|
|
{
|
|
try
|
|
{
|
|
var sections = await GetAll();
|
|
// Cambiar por comparacion con Location?
|
|
return sections.Where(section => section.PointOfCares != null &&
|
|
section.PointOfCares.Any(c =>
|
|
c.Bed == location.Bed && c.UnitName == location.UnitName)).ToList();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Error("Exception finding by location section exception:{e} location: {location} ", e.Message,
|
|
location);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private async void SendUnitBroadcast(Unit unit, OperationType operation)
|
|
{
|
|
try
|
|
{
|
|
var locations = new List<ObjectId>();
|
|
var pocs = await pointOfCareService.FindAllByUnitId(unit.Id);
|
|
if (pocs == null)
|
|
return;
|
|
|
|
locations.AddRange(pocs.Select(c => c.Id));
|
|
var subscribers = subscribersService.GetSubscribers()
|
|
.Where(s => s.LocationIds.Any(id => locations.Contains(id)))
|
|
.ToList();
|
|
|
|
foreach (var subscriber in subscribers)
|
|
_ = clientMessageService.Value.SendAsync(subscriber.Id, operation, unit);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
logger.LogError(
|
|
"Error sending Unit Broadcast {unit} with operation type {operationToString()} message: {eMessage}",
|
|
unit, operation.ToString(), e.Message);
|
|
}
|
|
}
|
|
} |