rama creada apartir de master en j

This commit is contained in:
jrojas
2026-06-26 10:29:23 +02:00
parent 319fd3dfb0
commit c1517fda87
2810 changed files with 1927392 additions and 25392 deletions
@@ -25,26 +25,51 @@ public class MedicineService(
{
private readonly List<string> _notesIndicatingMedication = apiSettings.Value.NotesIndicatingMedication ?? [];
/// <summary>
/// Retrieves all medicines from the repository asynchronously.
/// </summary>
/// <returns>A task representing the asynchronous operation, containing a list of all <see cref="Medicine"/> entities.</returns>
public async Task<List<Medicine>> GetAll()
{
return await medicineRepository.GetAll();
}
/// <summary>
/// Retrieves a medicine from the repository by its unique code, returning null if no matching medicine is found.
/// </summary>
/// <param name="code">The unique code identifier of the medicine to retrieve.</param>
/// <returns>A <see cref="Medicine"/> instance if a medicine with the specified code exists; otherwise, null.</returns>
public async Task<Medicine?> GetByCode(string code)
{
return await medicineRepository.GetMedicine(code);
}
/// <summary>
/// Retrieves a list of medicines that match the provided codes or notes by delegating to the medicine repository.
/// </summary>
/// <param name="codeNote">A list of strings representing the codes or notes used to search for matching medicines.</param>
/// <returns>A task that represents the asynchronous operation, containing the list of <see cref="Medicine"/> objects that match the specified codes or notes.</returns>
public async Task<List<Medicine>> GetByCodeOrNote(List<string> codeNote)
{
return await medicineRepository.GetMedicineByCodeOrNote(codeNote);
}
/// <summary>
/// Retrieves a <see cref="Medicine"/> from the repository by its name.
/// Returns <c>null</c> when no matching medicine is found.
/// </summary>
/// <param name="name">The name of the medicine to look up.</param>
/// <returns>A <see cref="Medicine"/> if a match is found; otherwise, <c>null</c>.</returns>
public async Task<Medicine?> GetByName(string name)
{
return await medicineRepository.GetMedicineByName(name);
}
/// <summary>
/// Retrieves the medicines associated with a collection of patient treatments, resolving each treatment's requested give codes against the medicine repository. Falls back to parental nutrition calculation when no medicine is found, and to note-based detection when notes indicate medication; medicines of type "Nutrition" returned by the repository are excluded except when produced through the parental nutrition path.
/// </summary>
/// <param name="treatments">The patient treatments to resolve medicines for. Null entries are skipped.</param>
/// <returns>An enumerable of medicines resolved from the supplied treatments, aggregating types, codes, groups, and notes when a treatment specifies a <c>RequestedGiveTreatment</c> name.</returns>
public async Task<IEnumerable<Medicine>> GetMedicinesOfTreatments(IEnumerable<PatientTreatment?> treatments)
{
var totalMedicines = new List<Medicine>();
@@ -94,21 +119,21 @@ public class MedicineService(
medicines =
[
new Medicine
{
Name = treatment.RequestedGiveTreatment,
Type = medicines.FindAll(t => t.Type.Any())
.Select(m => m.Type.Aggregate((x, y) => x + "," + y)).Distinct()
.ToList(),
Codes = medicines.FindAll(t => t.Codes.Any())
.Select(m => m.Codes.Aggregate((x, y) => x + "," + y)).Distinct()
.ToList(),
Group = medicines.FindAll(t => t.Group.Any())
.Select(m => m.Group.Aggregate((x, y) => x + "," + y)).Distinct()
.ToList(),
Notes = medicines.FindAll(t => t.Notes.Any())
.Select(m => m.Notes.Aggregate((x, y) => x + "," + y)).Distinct()
.ToList()
}
{
Name = treatment.RequestedGiveTreatment,
Type = medicines.FindAll(t => t.Type.Any())
.Select(m => m.Type.Aggregate((x, y) => x + "," + y)).Distinct()
.ToList(),
Codes = medicines.FindAll(t => t.Codes.Any())
.Select(m => m.Codes.Aggregate((x, y) => x + "," + y)).Distinct()
.ToList(),
Group = medicines.FindAll(t => t.Group.Any())
.Select(m => m.Group.Aggregate((x, y) => x + "," + y)).Distinct()
.ToList(),
Notes = medicines.FindAll(t => t.Notes.Any())
.Select(m => m.Notes.Aggregate((x, y) => x + "," + y)).Distinct()
.ToList()
}
];
}
catch (Exception ex)
@@ -128,6 +153,11 @@ public class MedicineService(
return totalMedicines.AsEnumerable();
}
/// <summary>
/// Retrieves all active medicines associated with a patient by first resolving their active treatments and then collecting the medicines prescribed within them.
/// </summary>
/// <param name="patientId">The unique identifier of the patient whose active medicines are being queried.</param>
/// <returns>A task that represents the asynchronous operation, containing an enumerable collection of <see cref="Medicine"/> instances linked to the patient's active treatments.</returns>
public async Task<IEnumerable<Medicine>> GetActiveMedicinesByPatient(ObjectId patientId)
{
var activeTreatments = await treatmentService.GetActiveTreatmentsByPatient(patientId);
@@ -135,6 +165,11 @@ public class MedicineService(
}
/// <summary>
/// Retrieves a paginated collection of medicines based on the specified pagination filter, including the total document count for the current query.
/// </summary>
/// <param name="filter">The pagination filter containing the page number and page size used to determine which subset of medicines to return.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains a <see cref="PaginationResponse{Medicine}"/> with the medicines for the requested page, the current page number, the page size, and the total count of medicines matching the query.</returns>
public async Task<PaginationResponse<Medicine>> GetPaginatedMedicines(PaginationFilter filter)
{
var result = medicineRepository.GetPaginatedMedicines(filter);
@@ -152,12 +187,25 @@ public class MedicineService(
}
/// <summary>
/// Retrieves a medicine by its unique identifier from the repository.
/// Throws a <see cref="NotFoundException"/> when no medicine is found matching the provided identifier.
/// </summary>
/// <param name="medicineId">The unique identifier of the medicine to retrieve.</param>
/// <returns>The <see cref="Medicine"/> entity if found; otherwise, the method throws an exception.</returns>
/// <exception cref="NotFoundException">Thrown when no medicine is found for the specified <paramref name="medicineId"/>.</exception>
public async Task<Medicine?> GetMedicineById(ObjectId medicineId)
{
return await medicineRepository.GetMedicineById(medicineId) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
}
/// <summary>
/// Creates a new medicine record in the repository and records an audit log entry for the operation. Throws a conflict exception when the repository fails to produce a result.
/// </summary>
/// <param name="medicine">The medicine entity to create.</param>
/// <returns>The newly created <see cref="Medicine"/> entity.</returns>
/// <exception cref="ConflictException">Thrown when the repository returns a null result, indicating the creation failed.</exception>
public async Task<Medicine?> PostMedicine(Medicine medicine)
{
var result = await medicineRepository.PostMedicine(medicine) ??
@@ -166,6 +214,11 @@ public class MedicineService(
return result;
}
/// <summary>
/// Updates an existing medicine record and records the change in the audit log.
/// </summary>
/// <param name="medicine">The medicine entity containing the updated information.</param>
/// <returns>The updated <see cref="Medicine"/>, or <c>null</c> if the update did not produce a result.</returns>
public async Task<Medicine?> UpdateMedicine(Medicine medicine)
{
var oldMedicine = GetMedicineById(medicine.Id);
@@ -174,6 +227,11 @@ public class MedicineService(
return newMedicine;
}
/// <summary>
/// Deletes a medicine identified by its unique identifier and records the operation in the audit log.
/// Captures the existing medicine state prior to deletion to preserve audit trail details.
/// </summary>
/// <param name="medicineId">The unique identifier of the medicine to delete.</param>
public async Task DeleteMedicineById(ObjectId medicineId)
{
var oldMedicine = GetMedicineById(medicineId);
@@ -181,6 +239,10 @@ public class MedicineService(
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldMedicine, null);
}
/// <summary>
/// Asynchronously retrieves all distinct medicine types from the repository. Returns an empty list if an exception occurs during the retrieval process.
/// </summary>
/// <returns>A task representing the asynchronous operation, containing a list of distinct medicine type strings, or an empty list if an error occurs.</returns>
public async Task<List<string>> GetAllTypes()
{
try
@@ -195,6 +257,11 @@ public class MedicineService(
}
}
/// <summary>
/// Asynchronously retrieves all distinct "group" values from the medicine repository and returns them as a list of strings.
/// Returns an empty list if an error occurs while fetching or converting the data.
/// </summary>
/// <returns>A task that represents the asynchronous operation, containing a list of distinct group strings, or an empty list if an exception is encountered.</returns>
public async Task<List<string>> GetAllGroups()
{
try
@@ -209,6 +276,10 @@ public class MedicineService(
}
}
/// <summary>
/// Retrieves all distinct medicine names from the repository asynchronously, returning an empty list if any error occurs during the data retrieval or mapping process.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains a list of medicine names, or an empty list if the operation fails.</returns>
public async Task<List<string>> GetAllNames()
{
try
@@ -223,6 +294,11 @@ public class MedicineService(
}
}
/// <summary>
/// Asynchronously retrieves all distinct code values from the medicine repository.
/// Returns an empty list if an exception occurs during retrieval.
/// </summary>
/// <returns>A task representing the asynchronous operation, containing a list of code strings, or an empty list if an error occurs.</returns>
public async Task<List<string>> GetAllCodes()
{
try
@@ -238,6 +314,12 @@ public class MedicineService(
}
//Exclusive for H12O, not in calculatedObservations of H12O to dont repeat code in multiple places.
/// <summary>
/// Calculates a <see cref="Medicine"/> representing the parental nutrition for a patient treatment, returning <c>null</c> when the treatment does not contain a note with the "NPT" comment.
/// The medicine name is taken from the first note with the "formularybaseformulation" comment type, defaulting to "UNKNOWN" when absent, and its type is set to ParenteralNutritionLipids when a neonatal lipids note is present, otherwise ParenteralNutrition.
/// </summary>
/// <param name="treatment">The patient treatment whose notes are used to derive the parental nutrition medicine.</param>
/// <returns>A task containing the calculated <see cref="Medicine"/>, or <c>null</c> when no "NPT" note is found or when an error is logged during processing.</returns>
private Task<Medicine?> CalculateParentalNutritionMedicine(PatientTreatment treatment)
{
Medicine? medicine = null;