using adas_core.Application.Repositories.Interfaces; using adas_core.Domain.Enums; using adas_core.Domain.Models.AppSettings; using adas_core.Domain.Models.DTO; using adas_core.Domain.Models.Filter; using adas_core.Domain.Models.MongoModels; using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Driver; using Newtonsoft.Json; using Serilog; using System.Text.RegularExpressions; namespace adas_core.Infrastructure.Repositories; public class UnitRepository : MongoRepository, IUnitRepository { #region Properties private readonly ApiSettings _apiSettings; #endregion #region Constructor public UnitRepository(IOptions apiSettings, IMongoDatabase database) : base(database) { _apiSettings = apiSettings.Value; } #endregion #region Methods #region Create public async Task InsertOneUnit(Unit unit) { try { await Collection.InsertOneAsync(unit); return await FindById(unit.Id); } catch (Exception ex) { Log.Error("Error inserting Unit: {unit}. Exception: {ex}", JsonConvert.SerializeObject(unit, Formatting.Indented), ex); return null; } } #endregion #region Read public override string GetCollectionName() { return _apiSettings.Units ?? "units"; } // public async Task FindByLocation(PatientLocation location) // { // var filter = Builders.Filter.ElemMatch(x => x.PointOfCares, poc => poc.Bed == location.Bed && poc.UnitName == location.UnitName); // var result = await Collection.Find(filter).FirstOrDefaultAsync(); // // return result; // } public async Task FindById(object id) { var result = await Collection.FindAsync(Builders.Filter.Eq(x => x.Id, id)); return await result.FirstOrDefaultAsync(); } public Task FindById(string id) { throw new NotImplementedException(); } public async Task> FindByMasterListId(ObjectId id, MasterListType masterListType) { try { var propertyName = $"{masterListType}Id"; // nombre de la propiedad dinĂ¡micamente var filter = Builders.Filter.Eq(propertyName, id); var result = await Collection.Find(filter).ToListAsync(); return result; } catch (Exception ex) { Log.Error("Error searching unit by {masterlisttype} Id {id}. Exception: {ex}", masterListType.ToString(), id, ex); throw; } } public async Task> FindByMasterListId(ObjectId id) { try { var filterBuilder = Builders.Filter; var filters = new List> { filterBuilder.Or( filterBuilder.Eq(p => p.DoctorListId, id), filterBuilder.Eq(p => p.AllergyListId, id), filterBuilder.Eq(p => p.DestinationListId, id), filterBuilder.Eq(p => p.DiagnosisListId, id), filterBuilder.Eq(p => p.InsulationListId, id), filterBuilder.Eq(p => p.OriginListId, id), filterBuilder.Eq(p => p.ProcedureListId, id), filterBuilder.Eq(p => p.TestListId, id), filterBuilder.Eq(p => p.ServiceListId, id), filterBuilder.Eq(p => p.TreatmentListId, id), filterBuilder.Eq(p => p.LanguageBarrierListId, id), filterBuilder.Eq(p => p.AltableOptionListId, id), filterBuilder.Eq(p => p.DischargeStatusListId, id), filterBuilder.Eq(p => p.DoctorTypeListId, id), filterBuilder.Eq(p => p.InternalDestinationListId, id), filterBuilder.Eq(p => p.PassiveSittingListId, id), filterBuilder.Eq(p => p.GenericListId, id), filterBuilder.Eq(p => p.VisitOptionListId, id), filterBuilder.Eq(p => p.AccessControlListId, id), filterBuilder.Eq(p => p.TherapeuticCeilingListId, id), filterBuilder.Eq(p => p.MobilityOptionListId, id) ) }; var result = await Collection.Find(Builders.Filter.And(filters)).ToListAsync(); return result; } catch (Exception ex) { Log.Error("Error searching unit by masterlist Id {id}. Exception: {ex}", id.ToString(), ex); return new List(); } } public async Task CountUnitsByMasterListId(ObjectId id, MasterListType masterListType) { var propertyName = $"{masterListType}Id"; var filter = Builders.Filter.Eq(propertyName, id); var result = await Collection.CountDocumentsAsync(filter); return result; } public async Task FindByName(string unitName) { var result = await Collection.FindAsync(Builders.Filter.Eq(x => x.Name, unitName)); return await result.FirstOrDefaultAsync(); } // public async Task> FindByPointOfCare(PointOfCare pointOfCare) // { // var filter = Builders.Filter.ElemMatch(x => x.PointOfCares, poc => poc.Bed == pointOfCare.Bed && poc.Room == pointOfCare.Room && pointOfCare.unitName == poc.unitName); // var result = await Collection.Find(filter).ToListAsync(); // // return result; // } // public async Task FindByPointOfCare(PointOfCare pointOfCare) // { // var filter = Builders.Filter.ElemMatch(x => x.PointOfCares, poc => poc.Bed == pointOfCare.Bed && poc.Room == pointOfCare.Room && pointOfCare.UnitName == poc.UnitName); // var result = await Collection.Find(filter).FirstOrDefaultAsync(); // // return result; // } // public async Task> FindByUnitName(string unitName) // { // var filter = Builders.Filter.ElemMatch(x => x.PointOfCares, poc => poc.UnitName == unitName); // var result = await Collection.Find(filter).ToListAsync(); // // return result; // } public async Task> GetAll() { var result = await Collection.FindAsync(Builders.Filter.Empty); return result.ToList(); } public IFindFluent GetPaginatedUnits(PaginationFilter filter) { var filterBuilder = Builders.Filter; var sort = Builders.Sort.Ascending("title"); var filters = new List>(); if (filter.FilteredRequest == null) return CreateFindFluent(filters, sort); if (!string.IsNullOrEmpty(filter.FilteredRequest?.Text)) { var textFilter = filter.FilteredRequest.Text; var textFilterEscaped = Regex.Escape(textFilter); filters.Add( filterBuilder.Or( filterBuilder.Regex(p => p.Name, new BsonRegularExpression(textFilterEscaped, "i")), // Case-insensitive regex match for name filterBuilder.Regex(p => p.Title, new BsonRegularExpression(textFilterEscaped, "i")) // Case-insensitive regex match for title ) ); } return CreateFindFluent(filters, sort); } private IFindFluent CreateFindFluent(List> filters, SortDefinition sort) { var combinedFilter = filters.Any() ? Builders.Filter.And(filters) : Builders.Filter.Empty; return Collection.Find(combinedFilter).Sort(sort); } #endregion #region Update public async Task UpdateUnit(Unit unit) { var filter = Builders.Filter.Eq("_id", unit.Id); var update = Builders.Update //.Set(c => c.Id, unit.Id) .Set(c => c.Title, unit.Title) .Set(c => c.Name, unit.Name) .Set(c => c.Configuration, unit.Configuration) .Set(c => c.AllergyListId, unit.AllergyListId) .Set(c => c.DestinationListId, unit.DestinationListId) .Set(c => c.InternalDestinationListId, unit.InternalDestinationListId) .Set(c => c.DiagnosisListId, unit.DiagnosisListId) .Set(c => c.DoctorListId, unit.DoctorListId) .Set(c => c.DoctorTypeListId, unit.DoctorTypeListId) .Set(c => c.InsulationListId, unit.InsulationListId) .Set(c => c.MobilityOptionListId, unit.MobilityOptionListId) .Set(c => c.OriginListId, unit.OriginListId) .Set(c => c.PatientStatusListId, unit.PatientStatusListId) .Set(c => c.ProcedureListId, unit.ProcedureListId) .Set(c => c.TestListId, unit.TestListId) .Set(c => c.ServiceListId, unit.ServiceListId) .Set(c => c.TherapeuticCeilingListId, unit.TherapeuticCeilingListId) .Set(c => c.TreatmentListId, unit.TreatmentListId) .Set(c => c.VisitOptionListId, unit.VisitOptionListId) .Set(c => c.AccessControlListId, unit.AccessControlListId) .Set(c => c.DischargeStatusListId, unit.DischargeStatusListId); return await Collection.FindOneAndUpdateAsync(filter, update, new FindOneAndUpdateOptions { ReturnDocument = ReturnDocument.After }); } public async Task UpdateUnitInfo(ObjectId unitId, string name, string title) { var filter = Builders.Filter.Eq("_id", unitId); var update = Builders.Update //.Set(c => c.Id, unit.Id) .Set(c => c.Title, title) .Set(c => c.Name, name); return await Collection.FindOneAndUpdateAsync(filter, update, new FindOneAndUpdateOptions { ReturnDocument = ReturnDocument.After }); } public async Task UpdateUnitMasterList(UpdateUnitIdListDto updateUnitListDto) { var filter = Builders.Filter.Eq("_id", updateUnitListDto.UnitId); var update = Builders.Update; var updates = new List>(); foreach (var masterListData in updateUnitListDto.MasterListData) if (masterListData.MasterListType.HasValue) switch (masterListData.MasterListType.Value) { case MasterListType.AltableOptionList: updates.Add(update.Set(u => u.AltableOptionListId, masterListData.MasterListId)); break; case MasterListType.AllergyList: updates.Add(update.Set(u => u.AllergyListId, masterListData.MasterListId)); break; case MasterListType.DestinationList: updates.Add(update.Set(u => u.DestinationListId, masterListData.MasterListId)); break; case MasterListType.DiagnosisList: updates.Add(update.Set(u => u.DiagnosisListId, masterListData.MasterListId)); break; case MasterListType.DischargeStatusList: updates.Add(update.Set(u => u.DischargeStatusListId, masterListData.MasterListId)); break; case MasterListType.DoctorList: updates.Add(update.Set(u => u.DoctorListId, masterListData.MasterListId)); break; case MasterListType.DoctorTypeList: updates.Add(update.Set(u => u.DoctorTypeListId, masterListData.MasterListId)); break; case MasterListType.InternalDestinationList: updates.Add(update.Set(u => u.InternalDestinationListId, masterListData.MasterListId)); break; case MasterListType.InsulationList: updates.Add(update.Set(u => u.InsulationListId, masterListData.MasterListId)); break; case MasterListType.LanguageBarrierList: updates.Add(update.Set(u => u.LanguageBarrierListId, masterListData.MasterListId)); break; case MasterListType.PassiveSittingList: updates.Add(update.Set(u => u.PassiveSittingListId, masterListData.MasterListId)); break; case MasterListType.GenericList: updates.Add(update.Set(u => u.GenericListId, masterListData.MasterListId)); break; case MasterListType.MobilityOptionList: updates.Add(update.Set(u => u.MobilityOptionListId, masterListData.MasterListId)); break; case MasterListType.OriginList: updates.Add(update.Set(u => u.OriginListId, masterListData.MasterListId)); break; case MasterListType.PatientStatusList: updates.Add(update.Set(u => u.PatientStatusListId, masterListData.MasterListId)); break; case MasterListType.ProcedureList: updates.Add(update.Set(u => u.ProcedureListId, masterListData.MasterListId)); break; case MasterListType.TestList: updates.Add(update.Set(u => u.TestListId, masterListData.MasterListId)); break; case MasterListType.ServiceList: updates.Add(update.Set(u => u.ServiceListId, masterListData.MasterListId)); break; case MasterListType.TherapeuticCeilingList: updates.Add(update.Set(u => u.TherapeuticCeilingListId, masterListData.MasterListId)); break; case MasterListType.TreatmentList: updates.Add(update.Set(u => u.TreatmentListId, masterListData.MasterListId)); break; case MasterListType.VisitOptionList: updates.Add(update.Set(u => u.VisitOptionListId, masterListData.MasterListId)); break; case MasterListType.AccessControlList: updates.Add(update.Set(u => u.AccessControlListId, masterListData.MasterListId)); break; } if (updates.Any()) { var combinedUpdate = update.Combine(updates); return await Collection.FindOneAndUpdateAsync(filter, combinedUpdate, new FindOneAndUpdateOptions { ReturnDocument = ReturnDocument.After }); } return null; } public async Task UpdateConfiguration(ObjectId unitIdParsed, UnitConfiguration unitConfiguration) { var filter = Builders.Filter.Eq("_id", unitIdParsed); var update = Builders.Update .Set(c => c.Configuration, unitConfiguration); try { var result = await Collection.UpdateOneAsync(filter, update); return result.ModifiedCount > 0; } catch (Exception ex) { Log.Error("Error UpdateConfiguration from unit: {name}. Exception: {ex}", unitIdParsed, ex); return false; } } #endregion #region Delete public new async Task DeleteAsync(ObjectId id) { var filter = Builders.Filter.Eq(unit => unit.Id, id); try { return await Collection.FindOneAndDeleteAsync(filter); } catch (Exception e) { Log.Error(e.Message); return null; } } #endregion #endregion }