Files
adas-core/adas-core.Application/Services/UnitService.cs
T

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);
}
}
}