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

372 lines
14 KiB
C#

using adas_core.Application.Exceptions;
using adas_core.Application.Services.Interfaces;
using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.DTO;
using adas_core.Domain.Models.MongoModels;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using Serilog;
using Patient = adas_core.Domain.Models.MongoModels.Patient;
namespace adas_core.Application.Services;
public class AdminPanelService(
IOptions<ApiSettings> apiSettings,
IPatientService patientService,
IConfigObservationService configObservationService,
IMedicineService medicineService,
IPointOfCareService pocService,
IUnitService unitService,
ILogger<AdminPanelService> logger,
IAdmissionService admissionService,
IAuthService authService,
IDischargeService dischargeService,
IDisplayService displayService)
: IAdminPanelService
{
private readonly List<string> _defaultIdRecord = apiSettings.Value.DefaultIdRecord ?? [];
#region Patient
public async Task<bool> ArchivePatient(Patient patient)
{
try
{
await patientService.ArchivePatient(patient);
logger.LogDebug("archived patientid {patientid} from ADMPanel", patient.Id);
return true;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public async Task<Patient?> CreatePatient(AdmPanelRequest admRequest)
{
var patient = new Patient
{
Id = ObjectId.GenerateNewId()
};
await UpdateNewPatient(patient, admRequest);
await patientService.Insert(patient);
logger.LogDebug("Inserted {patientid} from ADMPanel", patient.Id);
return patient;
}
private async Task UpdateNewPatient(Patient patient, AdmPanelRequest admRequest)
{
if (!string.IsNullOrEmpty(admRequest.PatientNumber)) patient.PatientNumber = admRequest.PatientNumber;
if (admRequest.AdmTime.HasValue) patient.AdmTime = admRequest.AdmTime;
if (admRequest.Patient != null && !admRequest.Patient.IsEmptyDontCheckIds())
patient.Person = admRequest.Patient;
if (admRequest.Patient != null && (admRequest.Patient.Ids == null || admRequest.Patient.Ids.Count == 0))
{
if (patient.Person is { Ids: null }) patient.Person.Ids = new Dictionary<string, string>();
foreach (var item in _defaultIdRecord) patient.Person?.Ids?.Add(item, admRequest?.PatientNumber ?? "null");
}
patient.Person?.SetIds(patient.Person?.Ids ?? new Dictionary<string, string>());
if (admRequest is { UnitId: not null })
{
var unit = await unitService.FindById(admRequest.UnitId);
patient.UnitId = unit?.Id ?? admRequest.UnitId;
patient.UnitString = unit?.Name;
if (admRequest is { PointOfCareId: not null })
{
//El paciente existe en la localizacion no te dejo insertarlo
var patientInLocation = await patientService.FindByPointOfCareId(admRequest.PointOfCareId.Value);
if (patientInLocation != null)
{
logger.LogError(
"trying to insert patientid {patientid} in to location already in use. PointOfcareId: {poc}",
patient.Id, patient.PointOfCareId);
throw new Exception($"patient already in location: {patient.Location}");
}
var poc = await pocService.FindById(admRequest.PointOfCareId.Value);
if (poc == null)
{
logger.LogError(
"trying to insert patientid {patientid} in to location not found. PointOfcareId: {poc}",
patient.Id, admRequest.PointOfCareId);
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
}
await pocService.SetPointOfCareStatus(poc.Id, StatusEnum.PointOfCare.InUse);
patient.Location = new PatientLocation
(
bed: poc.Bed,
room: poc.Room,
unitName: unit?.Name
);
patient.PointOfCareId = poc.Id;
}
else
{
var pocUnknown =
await pocService.FindByBedAndUnitId(VirtualPointOfCare.Unknown.ToString(), patient.UnitId);
patient.PointOfCareId = pocUnknown?.Id;
}
patient.UpdateDate = DateTime.UtcNow;
}
}
public async Task<Patient?> FindPatientById(ObjectId id)
{
return await patientService.FindById(id) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
}
public async Task<Patient?> FindPatientByLocation(PatientLocation location)
{
return await patientService.FindByLocation(location);
}
public async Task<Patient?> FindPatientByPatientNumber(string patientNumber)
{
return await patientService.FindByPatientNumber(patientNumber);
}
public async Task<bool> UpdatePatientData(AdmPanelRequest request, Patient oldPatient)
{
//traer el paciente que se quiere actualizar con los valores que tenga en la base de datos a una variable
//actualizar unicamente los campos que tengan que ver con los datos del paciente
if (request.PatientNumber == null || request.Patient == null || request.Patient.IsEmptyDontCheckIds())
{
logger.LogError("Patient Data not updated. Old Patient:{oldPatient}. Api Request {request}", oldPatient,
request);
throw new ConflictException(HttpEnum.ErrorMessage.ConflictUpdateFailed);
}
var patientNumberChanged = oldPatient.PatientNumber != request.PatientNumber;
await patientService.UpdatePatientData(oldPatient.Id, request.PatientNumber, request.Patient,
patientNumberChanged);
return true;
}
public async Task<bool> UpdatePatientLocation(AdmPanelRequest request)
{
var patient = await patientService.FindByLocation(request.OldLocation);
var patientExistsInLocation = await patientService.FindByLocation(request.Location);
//Si ya hay un paciente en esa localización
if (patientExistsInLocation != null)
//Si hay un paciente distinto en la nueva localización movemos al anterior
if (patient != null && patientExistsInLocation.PatientNumber != patient.PatientNumber)
await patientService.UpdateLocation(patientExistsInLocation.Id,
new PatientLocation(VirtualPointOfCare.Pushed.ToString(), ObjectId.GenerateNewId().ToString()));
if (patient != null)
{
if (request.Location?.Bed == null || string.IsNullOrEmpty(request.Location.Bed))
request.Location = new PatientLocation(VirtualPointOfCare.Pushed.ToString(),
ObjectId.GenerateNewId().ToString());
//to solve problems when empty beds with not scapped ""
request.Location.Bed = request.Location?.Bed?.Replace("\"", "");
await patientService.UpdateLocation(patient.Id, request.Location);
patient = await patientService.FindById(patient.Id);
if (patient != null) await patientService.Update(patient);
}
else
{
patient = new Patient
{
Id = ObjectId.GenerateNewId()
};
await patientService.Insert(patient);
}
return true;
}
public async Task<Patient?> FindPatient(AdmPanelRequest request)
{
var findByLocation = !request.Location?.IsFullEmpty();
return await patientService.FindPatient(request.PatientId, request.PatientNumber, request.Location,
findByLocation ?? false) ?? throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
}
public async Task<Patient?> FindByLocation(PatientLocation location)
{
return await patientService.FindByLocation(location) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
}
#endregion
#region ConfigObservations
public async Task<bool> CreateConfig(ConfigObservation configObservation)
{
_ = await configObservationService.CreateConfig(configObservation) ??
throw new ConflictException(HttpEnum.ErrorMessage.ConflictCreationFailed);
return true;
}
public async Task<bool> UpdateConfig(ConfigObservation configObservation)
{
_ = await configObservationService.UpdateConfig(configObservation) ??
throw new ConflictException(HttpEnum.ErrorMessage.ConflictUpdateFailed);
return true;
}
public async Task<bool> DeleteConfigObservationItem(ObjectId id)
{
_ = await configObservationService.RemoveConfigItem(id) ??
throw new ConflictException(HttpEnum.ErrorMessage.ConflictDeleteFailed);
return true;
}
#endregion
#region Unit
public async Task<Unit?> InsertUnit(Unit unit)
{
//Insertamos la unidad y creamos los PoCs por defecto para esa unidad
var result = await unitService.InsertOne(unit);
if (result != null)
{
// Por cada valor del enum VirtualPointOfCare, creamos un PointOfCare asociado a la unidad
foreach (var pocEnum in Enum.GetValues(typeof(VirtualPointOfCare)).Cast<VirtualPointOfCare>())
{
var poc = new PointOfCare
{
UnitId = result.Id,
Status = StatusEnum.PointOfCare.Available,
Room = pocEnum.ToString(),
Bed = pocEnum.ToString()
};
var insertedPoc = await pocService.InsertPointOfCare(poc);
if (insertedPoc != null)
{
result.PointOfCareIds ??= [];
result.PointOfCareIds.Add(insertedPoc.Id);
}
}
// Actualizamos la unidad con los nuevos PointOfCareIds
await unitService.UpdateUnit(result);
}
return result;
}
public async Task<UnitInfoDto?> GetUnitDependencyDto(Unit unit)
{
try
{
return new UnitInfoDto(unit)
{
Admissions = await admissionService.CountAdmissionsByUnitId(unit.Id),
Discharges = await dischargeService.CountDischargesByUnitId(unit.Id),
Displays = await displayService.CountDisplaysByUnitId(unit.Id),
Patients = await patientService.CountPatientsByUnitId(unit.Id),
PointOfCares = await pocService.CountPoCsByUnitId(unit.Id),
VirtualPointOfCares = await pocService.CountVirtualPoCsByUnitId(unit.Id)
};
}
catch (Exception e)
{
logger.LogError(e.Message);
return null;
}
}
public async Task<bool> DeleteUnitById(ObjectId unitId)
{
try
{
var unit = await unitService.FindById(unitId);
if (unit == null) throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
//No se puede borrar una unidad que est en uso
var patients = await patientService.CountPatientsByUnitId(unitId);
if (patients > 0)
//Si tiene pacientes no se permite borrado
throw new ConflictException(HttpEnum.ErrorMessage.ConflictResourceInUse);
//Borramos admisiones
await admissionService.DeleteAdmissionsByUnitId(unitId);
//discharges
await dischargeService.DeleteDischargesByUnitId(unitId);
//Borramos Authorizations
await authService.DeleteByUnitId(unitId);
//Displays
await displayService.DeleteDisplaysByUnitId(unitId);
//PointOfCares
await pocService.DeletePoCsByUnitId(unitId);
//Una vez borrados los recursos asociados a la unidad, borramos la unidad
await unitService.DeleteUnitById(unit);
return true;
}
catch (Exception e)
{
Log.Error(e.Message);
return false;
}
}
#endregion
#region Medicine
public async Task<Medicine?> GetMedicineById(ObjectId medicineId)
{
return await medicineService.GetMedicineById(medicineId) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
}
public async Task<Medicine?> PostMedicine(Medicine medicine)
{
var newMedicine = await medicineService.PostMedicine(medicine) ??
throw new ConflictException(HttpEnum.ErrorMessage.ConflictCreationFailed);
return newMedicine;
}
public async Task<Medicine?> UpdateMedicine(Medicine medicine)
{
var updatedMedicine = await medicineService.UpdateMedicine(medicine) ??
throw new ConflictException(HttpEnum.ErrorMessage.ConflictUpdateFailed);
return updatedMedicine;
}
public async Task<bool> DeleteMedicineById(string medicineId)
{
if (!ObjectId.TryParse(medicineId, out var objectId))
throw new BadRequestException(HttpEnum.ErrorMessage.BadRequestInvalidFormat);
await medicineService.DeleteMedicineById(objectId);
_ = await medicineService.GetMedicineById(ObjectId.Parse(medicineId)) ??
throw new ConflictException(HttpEnum.ErrorMessage.ConflictDeleteFailed);
return true;
}
#endregion
}