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.Filter; 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 TreatmentRepository : MongoRepository, ITreatmentRepository { private readonly ApiSettings _apiSettings; public TreatmentRepository(IOptions apiSettings, IMongoDatabase database) : base(database) { if (apiSettings == null) throw new ArgumentNullException(nameof(apiSettings)); _apiSettings = apiSettings.Value; } //For testing public override string GetCollectionName() { return _apiSettings.PatientsTreatments ?? "patients_treatments"; } public async Task> GetByPatientId(ObjectId patientId) { var filter = Builders.Filter.Eq(ob => ob.PatientId, patientId); var result = await Collection.FindAsync(filter); return result.ToEnumerable(); } public async Task> GetById(ObjectId id) { var filter = Builders.Filter.Eq(ob => ob.Id, id); var result = await Collection.FindAsync(filter); return result; } public override async Task InsertOneAsync(PatientTreatment treatment) { treatment.OrderTime ??= DateTime.UtcNow; await base.InsertOneAsync(treatment); } public new async Task DeleteAsync(ObjectId id) { var filter = Builders.Filter.Eq(ob => ob.Id, id); await Collection.DeleteOneAsync(filter); } public async Task> FindByPatientIdAsync(ObjectId patientId) { var filter = Builders.Filter.Eq(ob => ob.PatientId, patientId); return await Collection.FindAsync(filter); } public async Task DeleteByPatientId(ObjectId patientId) { try { var filter = Builders.Filter.Eq(po => po.PatientId, patientId); await Collection.DeleteManyAsync(filter); return true; } catch (Exception ex) { Log.Error(ex.ToString()); return false; } } public async Task Update(PatientTreatment treatment) { try { await UpdateOneAsync(treatment.Id, treatment); return true; } catch (Exception ex) { Log.Error(ex.ToString()); return false; } } public async Task> FindBolusTreatments(ObjectId patientId) { var builder = Builders.Filter; var filter = builder.And( builder.Eq(t => t.PatientId, patientId), builder.Exists(t => t.RequestedGiveCodesStatus), builder.SizeGt(t => t.RequestedGiveCodesStatus, 0) ); var result = await Collection.FindAsync(filter); return await result.ToListAsync(); } public async Task> GetActiveTreatmentsByPatientIdAndOrder(ObjectId patientId, string order) { var builder = Builders.Filter; var filter = builder.And( builder.Or( builder.Eq(t => t.OrderControl, OrderControlType.Nw), builder.Eq(t => t.OrderControl, OrderControlType.Xo) ), builder.Eq(t => t.PatientId, patientId), builder.And( builder.Ne(t => t.PlacerOrder, null), // Verifica que no sea nulo builder.Eq(t => t.PlacerOrder!.EntityIdentifier, order) ) ); var result = await Collection.FindAsync(filter); return await result.ToListAsync(); } public async Task UpdateManyObjectId(string nameId, ObjectId id, ObjectId oldId) { await UpdateManyObjectIdAsync(nameId, id, oldId); } public async Task> FindByPatientId(ObjectId patientId) { var filter = Builders.Filter.Eq(ob => ob.PatientId, patientId); var result = await Collection.FindAsync(filter); return result.ToEnumerable(); } public IFindFluent GetPaginatedTreatments(PaginationFilter filter) { var filterBuilder = Builders.Filter; var sort = Builders.Sort.Descending("orderTime"); var filters = new List>(); if (filter.FilteredRequest == null) { AddDefaultTimeFilters(filters, filter, filterBuilder); return CreateFindFluent(filters, sort); } var requestFilter = filter.FilteredRequest; if (requestFilter.PatientId != null && ObjectId.TryParse(requestFilter.PatientId, out var patientObjectId)) filters.Add(filterBuilder.Eq(t => t.PatientId, patientObjectId)); if (requestFilter.StartDate != null) filters.Add(filterBuilder.Gt(t => t.OrderTime, requestFilter.StartDate)); if (requestFilter.EndDate != null) filters.Add(filterBuilder.Lt(t => t.OrderTime, requestFilter.EndDate)); if (string.IsNullOrWhiteSpace(requestFilter.Text)) { //TODO falta definir la búsqueda por texto } if (requestFilter.ActiveTreatments) AddActiveTreatmentFilters(filters, filterBuilder); else AddDefaultTimeFilters(filters, filter, filterBuilder); return CreateFindFluent(filters, sort); } public override async Task CreateIndexes() { var options = new CreateIndexOptions { Background = true, Unique = false }; var indexes = new List> { new("{ patientid: 1 }", options) }; await MongoUtils.EnsureIndexes(Collection, indexes); } private static void AddActiveTreatmentFilters(List> filters, FilterDefinitionBuilder filterBuilder) { var currentTime = DateTime.UtcNow; filters.Add( filterBuilder.And( filterBuilder.Ne(t => t.PlacerOrder, null), filterBuilder.Ne(t => t.PlacerOrder!.EntityIdentifier, null) ) ); filters.Add( filterBuilder.Or( filterBuilder.Eq(t => t.StartTime, null), filterBuilder.Lte(t => t.StartTime, currentTime) ) ); filters.Add( filterBuilder.Or( filterBuilder.Eq(t => t.EndTime, null), filterBuilder.Gte(t => t.EndTime, currentTime) ) ); filters.Add(filterBuilder.Ne(t => t.OrderControl, OrderControlType.Dc)); filters.Add( filterBuilder.Or( filterBuilder.Eq(t => t.OrderControl, OrderControlType.Nw), filterBuilder.Eq(t => t.OrderControl, OrderControlType.Xo) ) ); } private void AddDefaultTimeFilters(List> filters, PaginationFilter filter, FilterDefinitionBuilder filterBuilder) { filters.Add( filterBuilder.Or( filterBuilder.Eq(t => t.StartTime, null), filterBuilder.Gt(p => p.StartTime, filter.FilteredRequest?.StartDate ?? DateTime.MinValue) ) ); filters.Add( filterBuilder.Or( filterBuilder.Eq(t => t.EndTime, null), filterBuilder.Lt(p => p.EndTime, filter.FilteredRequest?.EndDate ?? DateTime.MaxValue) ) ); } private IFindFluent CreateFindFluent( List> filters, SortDefinition sort) { var combinedFilter = filters.Any() ? Builders.Filter.And(filters) : Builders.Filter.Empty; // Filtra todo si no hay filtros return Collection.Find(combinedFilter).Sort(sort); } }