478 lines
17 KiB
C#
478 lines
17 KiB
C#
using adas_core.Application.Repositories.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.Masters;
|
|
using adas_core.Domain.Models.MongoModels;
|
|
using Microsoft.Extensions.Options;
|
|
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
using Serilog;
|
|
using MongoUtils = adas_core.Infrastructure.Utils.MongoUtils;
|
|
|
|
namespace adas_core.Infrastructure.Repositories;
|
|
|
|
public class AdmissionRepository : MongoRepository<Admission>, IAdmissionRepository
|
|
{
|
|
private readonly ApiSettings _apiSettings;
|
|
|
|
public AdmissionRepository(IOptions<ApiSettings> apiSettings, IMongoDatabase database) : base(database)
|
|
{
|
|
if (apiSettings == null) throw new ArgumentNullException(nameof(apiSettings));
|
|
_apiSettings = apiSettings.Value;
|
|
}
|
|
|
|
|
|
public override string GetCollectionName()
|
|
{
|
|
return _apiSettings.Admissions;
|
|
}
|
|
|
|
|
|
public override async Task InsertOneAsync(Admission admission)
|
|
{
|
|
try
|
|
{
|
|
admission.AdmissionDate = DateTime.UtcNow;
|
|
await base.InsertOneAsync(admission);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Warning("Exception trying to insert admission: {admission}. Exception {e}", admission, e);
|
|
}
|
|
}
|
|
|
|
public async Task Delete(ObjectId id)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<Admission>.Filter.Eq(x => x.Id, id);
|
|
await Collection.DeleteOneAsync(filter, null);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Error("Exception trying to delete admission: {id}. Exception {e}", id, e);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task Update(Admission admission)
|
|
{
|
|
try
|
|
{
|
|
await UpdateOneAsync(admission.Id, admission);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Error("Exception trying to update admission: {admission}. Exception {e}", admission, e);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task UpdateLocation(ObjectId id, ObjectId newLocation)
|
|
{
|
|
var filterBuilder = Builders<Admission>.Filter;
|
|
var filter = filterBuilder.Eq(p => p.Id, id);
|
|
|
|
var update = Builders<Admission>.Update
|
|
.Set(p => p.PointOfCareId, newLocation);
|
|
|
|
await Collection.UpdateOneAsync(filter, update);
|
|
}
|
|
|
|
|
|
public async Task UpdatePatient(ObjectId id, Person patient)
|
|
{
|
|
var filterBuilder = Builders<Admission>.Filter;
|
|
var filter = filterBuilder.Eq(p => p.Id, id);
|
|
|
|
var update = Builders<Admission>.Update
|
|
.Set(p => p.Person, patient);
|
|
|
|
await Collection.UpdateOneAsync(filter, update);
|
|
}
|
|
|
|
public async Task<IEnumerable<Admission>> FindAll()
|
|
{
|
|
try
|
|
{
|
|
var result = await Collection.FindAsync(_ => true);
|
|
return await result.ToListAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error getting all admissions. Exception: {ex}", ex);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public async Task<Admission?> SearchByPatientNumberAndDistinctUnit(string patientNumber, ObjectId unitId)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(patientNumber)) return null;
|
|
|
|
// Paciente ubicado en un PoC pero en diferente unidad
|
|
var patient = await Collection.Find(Builders<Admission>.Filter.And(
|
|
Builders<Admission>.Filter.Eq(p => p.Nhc, patientNumber),
|
|
Builders<Admission>.Filter.Ne(p => p.UnitId, unitId)
|
|
)).ToListAsync();
|
|
// Si hay mas de una coincidencia devolvemos null por que puede no estar completo el patientNumber
|
|
if (patient.Count > 1) return null;
|
|
return patient.FirstOrDefault();
|
|
}
|
|
|
|
public async Task<Admission?> FindById(ObjectId id)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<Admission>.Filter.Eq(p => p.Id, id);
|
|
var result = await Collection.FindAsync(filter);
|
|
|
|
return await result.FirstOrDefaultAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error searching admission by id: {id}. Exception: {ex}", id, ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<Admission?> FindByNhc(string nhc)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<Admission>.Filter.Eq(p => p.Nhc, nhc);
|
|
var result = await Collection.FindAsync(filter);
|
|
|
|
return await result.FirstOrDefaultAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error searching admission by NHC: {nhc}. Exception: {ex}", nhc, ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<List<Admission>> FindByLocation(PatientLocation location)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<Admission>.Filter.Where(p =>
|
|
p.PatientLocation != null &&
|
|
location.UnitName == p.PatientLocation.UnitName &&
|
|
location.Bed == p.PatientLocation.Bed &&
|
|
location.Room == p.PatientLocation.Room);
|
|
|
|
return await Collection.Find(filter).ToListAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error searching admission by location: {location}. Exception: {ex}", location, ex);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public async Task<IEnumerable<Admission>?> FindByOrigin(string origin)
|
|
{
|
|
try
|
|
{
|
|
var filter = string.IsNullOrEmpty(origin)
|
|
? Builders<Admission>.Filter.Empty
|
|
: Builders<Admission>.Filter.Where(p => p.Origin != null && origin.Equals(p.Origin.Name));
|
|
|
|
var result = await Collection.FindAsync(filter);
|
|
|
|
return result.ToEnumerable();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error searching admissions by origin: {origin}. Exception: {ex}", origin, ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<Admission?> InsertOneAsyncAndReturn(Admission origin)
|
|
{
|
|
try
|
|
{
|
|
await Collection.InsertOneAsync(origin);
|
|
return origin;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<List<Admission>> GetAdmissionByUnitIdWithOutPoC(ObjectId unitId)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<Admission>.Filter.Where(p => p.UnitId == unitId && p.PointOfCareId == null);
|
|
var result = await Collection.FindAsync(filter);
|
|
|
|
return result.ToList();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex.Message);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public async Task<long> CountByUnitId(ObjectId unitId)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<Admission>.Filter.Where(p => p.UnitId == unitId);
|
|
var result = await Collection.CountDocumentsAsync(filter);
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex.Message);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public async Task<List<Admission>> FindByPointOfCareId(ObjectId pocId)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<Admission>.Filter.Where(p => p.PointOfCareId == pocId);
|
|
var result = await Collection.FindAsync(filter);
|
|
|
|
return result.ToList();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex.Message);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public async Task<List<Admission>> FindByUnitIds(List<ObjectId> unitIds)
|
|
{
|
|
var filterUnit = Builders<Admission>.Filter.In("unitId", unitIds);
|
|
return await Collection.Find(filterUnit).ToListAsync();
|
|
}
|
|
|
|
public async Task<IEnumerable<Admission>> UpdateMasterListOption(List<ObjectId> unitIds,
|
|
UpdateOptionMasterListDto opt, string typeName)
|
|
{
|
|
var isParsed = Enum.TryParse<MasterListType>(typeName, out var parsedTypeName);
|
|
if (isParsed)
|
|
{
|
|
var filterUnit = Builders<Admission>.Filter.In("unitId", unitIds);
|
|
switch (parsedTypeName)
|
|
{
|
|
case MasterListType.OriginList:
|
|
var originFilter = Builders<Admission>.Filter.Eq(
|
|
"origin.name", opt.OldOption?.Name
|
|
);
|
|
var filterUpdateorigin = Builders<Admission>.Filter.And(filterUnit, originFilter);
|
|
var updateorigin = Builders<Admission>.Update
|
|
.Set("origin.name", opt.UpdatedOption?.Name);
|
|
await Collection.UpdateManyAsync(filterUpdateorigin, updateorigin);
|
|
|
|
await Collection.UpdateManyAsync(Builders<Admission>.Filter.And(filterUnit,
|
|
Builders<Admission>.Filter.Eq(
|
|
"originAux", opt.OldOption?.Name
|
|
)), Builders<Admission>.Update
|
|
.Set("originAux", opt.UpdatedOption?.Name));
|
|
|
|
// Filtro para devolver los documentos actualizados (OR entre diagnosis.name y diagnosisAux)
|
|
var originFilterToReturn = Builders<Admission>.Filter.Eq("origin.name", opt.UpdatedOption?.Name);
|
|
var originAuxFilterToReturn = Builders<Admission>.Filter.Eq("originAux", opt.UpdatedOption?.Name);
|
|
var filterToReturnorigin = Builders<Admission>.Filter.And(
|
|
filterUnit,
|
|
Builders<Admission>.Filter.Or(originFilterToReturn, originAuxFilterToReturn)
|
|
);
|
|
|
|
// Devolver los documentos actualizados
|
|
var updatedDocumentsorigin = await Collection.Find(filterToReturnorigin).ToListAsync();
|
|
return updatedDocumentsorigin;
|
|
case MasterListType.DiagnosisList:
|
|
var diagnosisFilter = Builders<Admission>.Filter.Eq(
|
|
"diagnosis.name", opt.OldOption?.Name
|
|
);
|
|
var filterUpdateDiagnosis = Builders<Admission>.Filter.And(filterUnit, diagnosisFilter);
|
|
var updateDiagnosis = Builders<Admission>.Update
|
|
.Set("diagnosis.name", opt.UpdatedOption?.Name)
|
|
.Set("diagnosis.description", opt.UpdatedOption?.Description);
|
|
await Collection.UpdateManyAsync(filterUpdateDiagnosis, updateDiagnosis);
|
|
|
|
await Collection.UpdateManyAsync(Builders<Admission>.Filter.And(filterUnit,
|
|
Builders<Admission>.Filter.Eq(
|
|
"diagnosisAux", opt.OldOption?.Name
|
|
)), Builders<Admission>.Update
|
|
.Set("diagnosisAux", opt.UpdatedOption?.Name));
|
|
|
|
// Filtro para devolver los documentos actualizados (OR entre diagnosis.name y diagnosisAux)
|
|
var diagnosisFilterToReturn =
|
|
Builders<Admission>.Filter.Eq("diagnosis.name", opt.UpdatedOption?.Name);
|
|
var diagnosisAuxFilterToReturn =
|
|
Builders<Admission>.Filter.Eq("diagnosisAux", opt.UpdatedOption?.Name);
|
|
var filterToReturn = Builders<Admission>.Filter.And(
|
|
filterUnit,
|
|
Builders<Admission>.Filter.Or(diagnosisFilterToReturn, diagnosisAuxFilterToReturn)
|
|
);
|
|
|
|
// Devolver los documentos actualizados
|
|
var updatedDocuments = await Collection.Find(filterToReturn).ToListAsync();
|
|
return updatedDocuments;
|
|
case MasterListType.AllergyList:
|
|
// allergies []
|
|
break;
|
|
case MasterListType.InsulationList:
|
|
// insulation
|
|
break;
|
|
case MasterListType.LanguageBarrierList:
|
|
// languageBarrier
|
|
break;
|
|
case MasterListType.PassiveSittingList:
|
|
// passiveSitting
|
|
break;
|
|
}
|
|
}
|
|
|
|
return new List<Admission>();
|
|
}
|
|
|
|
public async Task<IEnumerable<Admission>> DeleteMasterListOption(List<ObjectId> unitIds, OptionList opt,
|
|
string typeName)
|
|
{
|
|
var isParsed = Enum.TryParse<MasterListType>(typeName, out var parsedTypeName);
|
|
if (isParsed)
|
|
{
|
|
var filterUnit = Builders<Admission>.Filter.In("unitId", unitIds);
|
|
switch (parsedTypeName)
|
|
{
|
|
case MasterListType.OriginList:
|
|
// origin
|
|
// originAux
|
|
// Filtro para devolver los documentos actualizados (OR entre diagnosis.name y diagnosisAux)
|
|
var originFilterToReturn = Builders<Admission>.Filter.Eq("origin.name", opt.Name);
|
|
var originAuxFilterToReturn = Builders<Admission>.Filter.Eq("originAux", opt.Name);
|
|
var filterToReturnOrigin = Builders<Admission>.Filter.And(
|
|
filterUnit,
|
|
Builders<Admission>.Filter.Or(originFilterToReturn, originAuxFilterToReturn)
|
|
);
|
|
|
|
// Devolver los documentos actualizados
|
|
var updatedDocumentOrigin = await Collection.Find(filterToReturnOrigin).ToListAsync();
|
|
|
|
var originFilter = Builders<Admission>.Filter.Eq(
|
|
"origin.name", opt.Name
|
|
);
|
|
var filterUpdateOrigin = Builders<Admission>.Filter.And(filterUnit, originFilter);
|
|
var updateorigin = Builders<Admission>.Update
|
|
.Set(x => x.Origin, null);
|
|
await Collection.UpdateManyAsync(filterUpdateOrigin, updateorigin);
|
|
|
|
await Collection.UpdateManyAsync(Builders<Admission>.Filter.And(filterUnit,
|
|
Builders<Admission>.Filter.Eq(
|
|
"originAux", opt.Name
|
|
)), Builders<Admission>.Update
|
|
.Set(x => x.OriginAux, ""));
|
|
|
|
|
|
return updatedDocumentOrigin;
|
|
|
|
case MasterListType.DiagnosisList:
|
|
|
|
// Filtro para devolver los documentos actualizados (OR entre diagnosis.name y diagnosisAux)
|
|
var diagnosisFilterToReturn = Builders<Admission>.Filter.Eq("diagnosis.name", opt.Name);
|
|
var diagnosisAuxFilterToReturn = Builders<Admission>.Filter.Eq("diagnosisAux", opt.Name);
|
|
var filterToReturn = Builders<Admission>.Filter.And(
|
|
filterUnit,
|
|
Builders<Admission>.Filter.Or(diagnosisFilterToReturn, diagnosisAuxFilterToReturn)
|
|
);
|
|
|
|
// Devolver los documentos actualizados
|
|
var updatedDocuments = await Collection.Find(filterToReturn).ToListAsync();
|
|
|
|
var diagnosisFilter = Builders<Admission>.Filter.Eq(
|
|
"diagnosis.name", opt.Name
|
|
);
|
|
var filterUpdateDiagnosis = Builders<Admission>.Filter.And(filterUnit, diagnosisFilter);
|
|
var updateDiagnosis = Builders<Admission>.Update
|
|
.Set(x => x.Diagnosis, null);
|
|
await Collection.UpdateManyAsync(filterUpdateDiagnosis, updateDiagnosis);
|
|
|
|
await Collection.UpdateManyAsync(Builders<Admission>.Filter.And(filterUnit,
|
|
Builders<Admission>.Filter.Eq(
|
|
"diagnosisAux", opt.Name
|
|
)), Builders<Admission>.Update
|
|
.Set(x => x.DiagnosisAux, null));
|
|
|
|
|
|
return updatedDocuments;
|
|
case MasterListType.AllergyList:
|
|
// allergies []
|
|
break;
|
|
case MasterListType.InsulationList:
|
|
// insulation
|
|
break;
|
|
case MasterListType.LanguageBarrierList:
|
|
// languageBarrier
|
|
break;
|
|
case MasterListType.PassiveSittingList:
|
|
// passiveSitting
|
|
break;
|
|
}
|
|
}
|
|
|
|
return new List<Admission>();
|
|
}
|
|
|
|
public async Task<bool> DeleteAdmissionsByUnitId(ObjectId unitId)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<Admission>.Filter.Eq(p => p.UnitId, unitId);
|
|
await Collection.DeleteManyAsync(filter);
|
|
return true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Logger.Error(e.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public override async Task CreateIndexes()
|
|
{
|
|
var optionsUq = new CreateIndexOptions<Admission>
|
|
{
|
|
Background = true,
|
|
Unique = true,
|
|
PartialFilterExpression = Builders<Admission>.Filter.Exists(p => p.Nhc)
|
|
};
|
|
|
|
var indexes = new List<CreateIndexModel<Admission>>
|
|
{
|
|
new("{ nhc: 1 }", optionsUq)
|
|
};
|
|
|
|
await MongoUtils.EnsureIndexes(Collection, indexes);
|
|
}
|
|
|
|
public async Task<IEnumerable<Admission>?> FindByDiagnosis(string diagnosis)
|
|
{
|
|
try
|
|
{
|
|
var filter =
|
|
Builders<Admission>.Filter.Where(p => p.Diagnosis != null && diagnosis.Equals(p.Diagnosis.Name));
|
|
var result = await Collection.FindAsync(filter);
|
|
|
|
return result.ToEnumerable();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("Error searching admissions by diagnosis: {origin}. Exception: {ex}", diagnosis, ex);
|
|
return null;
|
|
}
|
|
}
|
|
} |