Creado apartir del commit b888de6c92056de294456f581a56e25e734d4ab7 de develop
This commit is contained in:
@@ -0,0 +1,711 @@
|
||||
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.Pumps;
|
||||
using adas_core.Domain.Utils;
|
||||
using adas_core.Domain.Utils.Interfaces;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Bson;
|
||||
|
||||
namespace adas_core.Application.Customizations.HUVH.UCIN;
|
||||
|
||||
public class CalculatedObservations : ICalculatedObservations
|
||||
{
|
||||
private const string Spo2PreObservationName = "SpO2";
|
||||
private const string Spo2PostObservationName = "SpO2_Post";
|
||||
|
||||
private const string Spo2PrePostObservationName = "SpO2_Pre_Post";
|
||||
private const string CodingSystem = "ADAS";
|
||||
|
||||
private readonly List<string> _complexityObservations =
|
||||
[
|
||||
"Respiratory_Device_Multivalue", "Intravenous_Routes_Multivalue", "Medication_Multivalue",
|
||||
"System_Multivalue", "Newborn_Weight", "Surgery_Multivalue"
|
||||
];
|
||||
|
||||
private readonly ILogger<CalculatedObservations> _logger;
|
||||
private readonly IMappingUtils _mappingUtils;
|
||||
private readonly Lazy<IMedicineService> _medicineService;
|
||||
private readonly Lazy<IObservationService> _observationService;
|
||||
|
||||
private readonly Lazy<ITreatmentService> _treatmentService;
|
||||
|
||||
|
||||
public CalculatedObservations(IServiceProvider serviceProvider)
|
||||
{
|
||||
_treatmentService = serviceProvider.GetRequiredService<Lazy<ITreatmentService>>();
|
||||
_medicineService = serviceProvider.GetRequiredService<Lazy<IMedicineService>>();
|
||||
_observationService = serviceProvider.GetRequiredService<Lazy<IObservationService>>();
|
||||
_logger = serviceProvider.GetRequiredService<ILogger<CalculatedObservations>>();
|
||||
|
||||
var apiSettings = serviceProvider.GetRequiredService<IOptions<ApiSettings>>(); //apiSettings;
|
||||
_mappingUtils = new MappingUtils(apiSettings);
|
||||
}
|
||||
|
||||
|
||||
public Task CalculateActiveBolus(ObjectId patientId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
public async Task<T?> Map<T>(T obs, bool onlyByName = false) where T : BasePatientObservation
|
||||
{
|
||||
if (obs.Name is "Intervention_In" or "Intervention_Out") await CalculateInterventionMultiValueObservation(obs);
|
||||
if (obs.Name is "Surgery") await CalculateMultiValueObservation(obs);
|
||||
if (obs.Name != null && _complexityObservations.Contains(obs.Name))
|
||||
{
|
||||
_logger.LogDebug("Mapping observation Complexity {obs}", obs);
|
||||
//TODO ver si hay un máximo de puntuación por grupo de observaciones
|
||||
_ = CalculateComplexity(obs);
|
||||
}
|
||||
|
||||
if (obs.Name is Spo2PreObservationName or Spo2PostObservationName)
|
||||
{
|
||||
_logger.LogDebug("Pre-post saturation observation {obs}", obs);
|
||||
_ = CalculateSaturation_DiffObservation(obs);
|
||||
}
|
||||
|
||||
if (obs.Name is "ALPS" or "NPASS_Sedation" or "NPASS_Analgesia") _ = CalculatePainScale(obs);
|
||||
|
||||
|
||||
if (obs.Name is "Last_Defecation") obs = (T)CalculateLastDefecationValue(obs);
|
||||
|
||||
return obs;
|
||||
}
|
||||
|
||||
|
||||
public async Task<PatientTreatment> Map(PatientTreatment treatment)
|
||||
{
|
||||
var order = treatment.PlacerOrder?.EntityIdentifier; //aquí almacenamos el número de orden
|
||||
if (string.IsNullOrEmpty(order)) return treatment;
|
||||
|
||||
//comprobamos el estado de los tratamientos anteriores
|
||||
var oldTreatments = await CheckExpiredPatientTreatments(treatment);
|
||||
|
||||
treatment.OrderControl = oldTreatments.Any() ? OrderControlType.Xo : OrderControlType.Nw;
|
||||
|
||||
if (treatment.EndTime != null)
|
||||
//el tratamiento ha expirado
|
||||
treatment.OrderControl = OrderControlType.Dc;
|
||||
|
||||
await CheckTreatmentMedicines(treatment);
|
||||
|
||||
return treatment;
|
||||
}
|
||||
|
||||
public async Task<PumpObservation> Map(PumpObservation pumpObservation)
|
||||
{
|
||||
return await Task.FromResult(pumpObservation);
|
||||
|
||||
}
|
||||
|
||||
public async Task CalculateMedicineObservation(List<Medicine> activeMedicines, ObjectId patientId)
|
||||
{
|
||||
var medicineObs = new PatientObservation
|
||||
{
|
||||
PatientId = patientId,
|
||||
Name = "Medication_Multivalue",
|
||||
CodingSystem = CodingSystem,
|
||||
Value = activeMedicines.Select(m => m.Name ?? string.Empty).Distinct().ToArray(),
|
||||
Time = DateTime.Now
|
||||
};
|
||||
|
||||
var lastMedicationsObs =
|
||||
await _observationService.Value.FindLastObservations(patientId, 1, ["Medication_Multivalue"]);
|
||||
var lastMedicationObs = lastMedicationsObs.FirstOrDefault();
|
||||
if (lastMedicationObs != null)
|
||||
{
|
||||
//expiramos la anterior
|
||||
lastMedicationObs.Expired = true;
|
||||
_ = _observationService.Value.UpdateObservation(lastMedicationObs);
|
||||
}
|
||||
|
||||
await _observationService.Value
|
||||
.InsertObservation(
|
||||
medicineObs); //mapObs:volvemos a mapear la observación para que pase por el cálculo de la complejidad
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PatientTreatment?>> GetActiveTreatmentsByPatient(ObjectId id)
|
||||
{
|
||||
var activeTreatments = await _treatmentService.Value.GetActiveTreatmentsByPatient(id);
|
||||
return activeTreatments;
|
||||
}
|
||||
|
||||
|
||||
public Task<PatientDiagnosis> Map(PatientDiagnosis diagnosis)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
public async Task<PatientObservation?> FixTimeInconsistencyWithLast(PatientObservation newObservation)
|
||||
{
|
||||
if (string.IsNullOrEmpty(newObservation.Name))
|
||||
{
|
||||
_logger.LogError(
|
||||
"Error FixTimeInconsistencyWithLast. Observation name is null or empty. Observation: {newObservation}",
|
||||
newObservation);
|
||||
return newObservation;
|
||||
}
|
||||
|
||||
var lastObservations = await _observationService.Value.FindLastObservations(newObservation.PatientId, 1,
|
||||
[newObservation.Name]);
|
||||
var lastObservation = lastObservations.FirstOrDefault();
|
||||
|
||||
if (lastObservation != null && DateTime.Compare(
|
||||
new DateTime(lastObservation.Time.Year, lastObservation.Time.Month,
|
||||
lastObservation.Time.Day, lastObservation.Time.Hour,
|
||||
lastObservation.Time.Minute, lastObservation.Time.Second),
|
||||
new DateTime(newObservation.Time.Year, newObservation.Time.Month,
|
||||
newObservation.Time.Day, newObservation.Time.Hour,
|
||||
newObservation.Time.Minute, newObservation.Time.Second)
|
||||
) >= 0)
|
||||
newObservation.Time = lastObservation.Time.AddSeconds(1);
|
||||
|
||||
return newObservation;
|
||||
}
|
||||
|
||||
public Task<List<PatientObservation>> PreMapList(List<PatientObservation> listToInsert)
|
||||
{
|
||||
return Task.FromResult(listToInsert);
|
||||
}
|
||||
|
||||
public Task<PatientObservation> MapSourceAlarm(PatientObservation obs, PatientObservationAlarm alarmToInsert)
|
||||
{
|
||||
return Task.FromResult(obs);
|
||||
}
|
||||
|
||||
public Task SendAlarm(PatientObservation obs, string name, AlarmEnum.Name? code)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private async Task CalculatePainScale(BasePatientObservation obs)
|
||||
{
|
||||
if (obs is not PatientObservation pobs) return;
|
||||
|
||||
|
||||
object valueObs;
|
||||
|
||||
switch (pobs.Name)
|
||||
{
|
||||
case "ALPS":
|
||||
valueObs = pobs.Value;
|
||||
break;
|
||||
case "NPASS_Sedation":
|
||||
{
|
||||
//Buscamos la complementaria "NPASS Analgesia"
|
||||
var analgesiaObs =
|
||||
await _observationService.Value.FindLastObservations(obs.PatientId, 1, ["NPASS_Analgesia"]);
|
||||
var analgesiaValue = analgesiaObs.FirstOrDefault()?.Value.ToString() ?? "0";
|
||||
|
||||
valueObs = $"{pobs.Value}/{analgesiaValue}";
|
||||
}
|
||||
break;
|
||||
case "NPASS_Analgesia":
|
||||
{
|
||||
//Buscamos la complementaria "NPASS Sedation"
|
||||
var sedationObs =
|
||||
await _observationService.Value.FindLastObservations(obs.PatientId, 1, ["NPASS_Sedation"]);
|
||||
var sedationValue = sedationObs.FirstOrDefault()?.Value.ToString() ?? "0";
|
||||
|
||||
valueObs = $"{sedationValue}/{pobs.Value}";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
var painScaleObs = new PatientObservation
|
||||
{
|
||||
PatientId = obs.PatientId,
|
||||
Time = DateTime.UtcNow,
|
||||
CodingSystem = "ADAS",
|
||||
Name = "Pain_Scale",
|
||||
Value = valueObs
|
||||
};
|
||||
|
||||
_ = _observationService.Value.InsertObservation(painScaleObs, mapObs: false);
|
||||
}
|
||||
|
||||
private static BasePatientObservation CalculateLastDefecationValue(BasePatientObservation obs)
|
||||
{
|
||||
if (obs is not PatientObservation pobs) return obs;
|
||||
//Assign obs time to value
|
||||
//Convert the UTC DateTime to local time.
|
||||
var localTime = pobs.Time.ToLocalTime();
|
||||
|
||||
//Format the local time into a short date/time string.
|
||||
pobs.Value = localTime.ToString("dd/MM/yyyy HH:mm");
|
||||
|
||||
return pobs;
|
||||
}
|
||||
|
||||
|
||||
private async Task CalculateMultiValueObservation(BasePatientObservation obs)
|
||||
{
|
||||
//El valor de la observación es un array de strings
|
||||
if (obs is not PatientObservation pobs || string.IsNullOrEmpty(obs.Name)) return;
|
||||
|
||||
var newObsName = $"{obs.Name}_Multivalue";
|
||||
var actualObsInBd =
|
||||
await _observationService.Value.FindLastObservations(obs.PatientId, 1, [newObsName]);
|
||||
|
||||
|
||||
var newValue = new List<string>();
|
||||
|
||||
if (pobs.Value is not string stringValueName) return;
|
||||
|
||||
|
||||
if (actualObsInBd.Count > 0)
|
||||
if (actualObsInBd.First().Value is string[] oldValue)
|
||||
{
|
||||
oldValue = oldValue.Where(x => x != stringValueName).ToArray();
|
||||
newValue.AddRange(oldValue);
|
||||
}
|
||||
|
||||
newValue.Add(stringValueName);
|
||||
|
||||
if (newValue.Count == 0) return;
|
||||
|
||||
//Expiramos la anterior
|
||||
var actualObs = actualObsInBd.FirstOrDefault();
|
||||
if (actualObs != null)
|
||||
{
|
||||
actualObs.Expired = true;
|
||||
|
||||
await _observationService.Value.UpdateObservation(actualObs);
|
||||
}
|
||||
|
||||
var newObservation = new PatientObservation
|
||||
{
|
||||
PatientId = obs.PatientId,
|
||||
Time = DateTime.UtcNow,
|
||||
CodingSystem = CodingSystem,
|
||||
Name = newObsName,
|
||||
Value = newValue.ToArray()
|
||||
};
|
||||
|
||||
_logger.LogDebug(
|
||||
"Calculate {name}_Multivalue {outpatient} Insert Calculated {time} value {value}",
|
||||
newObsName, newObservation.PatientId, newObservation.Time,
|
||||
newObservation.Value.ToJson());
|
||||
|
||||
await _observationService.Value.InsertObservation(newObservation);
|
||||
}
|
||||
|
||||
private async Task CalculateInterventionMultiValueObservation(BasePatientObservation obs)
|
||||
{
|
||||
if (obs is not PatientObservation pobs || string.IsNullOrEmpty(obs.Name) ||
|
||||
pobs.Value is not string valueObs) return;
|
||||
|
||||
if (!GetInterventionValue(valueObs, out var r) || r == null) return;
|
||||
|
||||
var obsType = r.Value.type; //"Intravenous_Routes";
|
||||
var obsGroup = r.Value.Name; // "Vía arterial";
|
||||
var newObsName = $"{obsType}_Multivalue";
|
||||
|
||||
// Obtener la última observación multivalue
|
||||
var result = await _observationService.Value.FindLastObservations(obs.PatientId, 1, [newObsName]);
|
||||
var actualMultiValueObsInDb = result.FirstOrDefault(o => !o.Expired);
|
||||
|
||||
var oldValue = actualMultiValueObsInDb?.Value as string[] ?? [];
|
||||
var newValue = new List<string>(oldValue);
|
||||
|
||||
if (obs.Name.Contains("_In"))
|
||||
{
|
||||
//Por seguridad solo tomamos el último valor que nos llega
|
||||
//Puede ser que no se acuerden de cancelar el anterior antes de añadir un nuevo dispositivo y no puede haber dos dispositivos del mismo tipo activos al mismo tiempo
|
||||
if (obsType == "Respiratory_Device")
|
||||
newValue.Clear();
|
||||
|
||||
// Inserción dispositivo
|
||||
if (!oldValue.Contains(obsGroup))
|
||||
newValue.Add(obsGroup);
|
||||
}
|
||||
else if (obs.Name.Contains("_Out"))
|
||||
{
|
||||
// Retirada del dispositivo
|
||||
//Buscamos la inserción
|
||||
var name = $"{obs.Name.Split('_')[0]}_In";
|
||||
var inObs = await _observationService.Value.FindLastNotExpiredObservatonsByPatient(obs.PatientId, name);
|
||||
|
||||
var sameValueObs = inObs.Where(o => o.Value == pobs.Value).ToList();
|
||||
|
||||
if (sameValueObs.Any())
|
||||
// Si hay más de una observación del mismo tipo, no eliminar del multivalue
|
||||
if (sameValueObs.Count > 1)
|
||||
return;
|
||||
|
||||
// Actualizar valor eliminando el grupo
|
||||
newValue.Remove(obsGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Expiramos la anterior
|
||||
if (actualMultiValueObsInDb is { Expired: false })
|
||||
{
|
||||
actualMultiValueObsInDb.Expired = true;
|
||||
await _observationService.Value.UpdateObservation(actualMultiValueObsInDb);
|
||||
}
|
||||
|
||||
// Si no hay valores nuevos, no se crea una nueva observación
|
||||
if (!newValue.Any())
|
||||
return;
|
||||
|
||||
|
||||
// Crear y registrar nueva observación
|
||||
var newObservation = new PatientObservation
|
||||
{
|
||||
PatientId = obs.PatientId,
|
||||
Time = DateTime.UtcNow,
|
||||
CodingSystem = CodingSystem,
|
||||
Name = newObsName,
|
||||
Value = newValue.ToArray()
|
||||
};
|
||||
|
||||
_logger.LogDebug(
|
||||
"Calculate {name}_Multivalue {patientid} Insert Calculated {time} value {value}",
|
||||
newObsName, newObservation.PatientId, newObservation.Time,
|
||||
newObservation.Value.ToJson()
|
||||
);
|
||||
|
||||
await _observationService.Value.InsertObservation(newObservation);
|
||||
}
|
||||
|
||||
private bool GetInterventionValue(string valueObs, out (string type, string Name, string Group)? r)
|
||||
{
|
||||
var code = valueObs.Split(" ")[0]; //
|
||||
if (code.EndsWith(".")) // Verifica si termina con un punto
|
||||
code = code.Substring(0, code.Length - 1).Replace('.', ','); // Remueve el último carácter
|
||||
|
||||
if (!double.TryParse(code, out var codeParsed))
|
||||
{
|
||||
r = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
r = _mappingUtils.SearchByCode(codeParsed, "Intervention"); //TODO validar este parámetro con Lola
|
||||
|
||||
return r != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculamos la complejidad basándonos en el valor de Respiratorio/Vías/Medicación/Sistemas/Peso nacimiento/cirugía
|
||||
* cuando entra una nueva observación que afecte a complejidad, se recalcula de 0 para no tener que estar pendiente de qué puntos corresponden a qué observación
|
||||
* Valor máximo 46 Guardamos la observación que nos llega y recalculamos complejidad.
|
||||
*/
|
||||
private async Task CalculateComplexity(BasePatientObservation obs)
|
||||
{
|
||||
var pobs = obs as PatientObservation;
|
||||
if (pobs == null) return;
|
||||
|
||||
var complexity = new PatientObservation
|
||||
{
|
||||
PatientId = obs.PatientId,
|
||||
Time = DateTime.UtcNow,
|
||||
CodingSystem = CodingSystem,
|
||||
Name = "Complexity",
|
||||
Value = 0
|
||||
};
|
||||
|
||||
var complexityValue = 0;
|
||||
|
||||
// Diccionario para manejar las operaciones basadas en el nombre de la observación
|
||||
var operations = new Dictionary<string, Func<ObjectId, PatientObservation?, Task<int>>>
|
||||
{
|
||||
{
|
||||
"Respiratory_Device_Multivalue",
|
||||
(patientId, observation) =>
|
||||
CalculateMultivalueObservationComplexityValue(patientId, "Respiratory_Device_Multivalue",
|
||||
observation)
|
||||
},
|
||||
{
|
||||
"Intravenous_Routes_Multivalue",
|
||||
(patientId, observation) =>
|
||||
CalculateMultivalueObservationComplexityValue(patientId, "Intravenous_Routes_Multivalue",
|
||||
observation)
|
||||
},
|
||||
{
|
||||
"Medication_Multivalue",
|
||||
(patientId, observation) =>
|
||||
CalculateMultivalueObservationComplexityValue(patientId, "Medication_Multivalue", observation)
|
||||
},
|
||||
{
|
||||
"System_Multivalue",
|
||||
(patientId, observation) =>
|
||||
CalculateMultivalueObservationComplexityValue(patientId, "System_Multivalue", observation)
|
||||
},
|
||||
{ "Newborn_Weight", CalculateWeightNewBornValue },
|
||||
{
|
||||
"Surgery_Multivalue",
|
||||
(patientId, observation) =>
|
||||
CalculateMultivalueObservationComplexityValue(patientId, "Surgery_Multivalue", observation)
|
||||
}
|
||||
};
|
||||
|
||||
// Realizar cálculos iterando sobre las operaciones
|
||||
foreach (var operation in operations)
|
||||
complexityValue += await operation.Value(pobs.PatientId, operation.Key.Equals(pobs.Name) ? pobs : null);
|
||||
|
||||
complexity.Value = Math.Min(complexityValue, 46); // Limitar el valor máximo a 46
|
||||
|
||||
_logger.LogDebug(
|
||||
"complexity for patient {patientid} => inserting complexity value: {complexityValue} for patient: {complexityPatientid} at time {fixedTimeComplexityTime}",
|
||||
complexity.PatientId, complexity.Value, complexity.PatientId, complexity.Time);
|
||||
|
||||
await _observationService.Value.InsertObservation(complexity, mapObs: false);
|
||||
}
|
||||
|
||||
private async Task<int> CalculateMultivalueObservationComplexityValue(ObjectId patientId, string observationName,
|
||||
PatientObservation? observation = null)
|
||||
{
|
||||
var result =
|
||||
await _observationService.Value.FindLastObservations(patientId, 1, [observationName]);
|
||||
var actualObsInBd = result.FirstOrDefault();
|
||||
|
||||
var valueObj = observation == null ? actualObsInBd?.Value : observation.Value;
|
||||
var valueList = valueObj as string[];
|
||||
|
||||
var valueToReturn = valueList?.Sum(v => _mappingUtils.GetComplexityValue(v)) ?? 0;
|
||||
|
||||
_logger.LogDebug(
|
||||
"complexity for patient {patientid} => observation: {observationName} plus complexity: {Value}", patientId,
|
||||
observationName, valueToReturn);
|
||||
|
||||
return valueToReturn;
|
||||
}
|
||||
|
||||
|
||||
private async Task<int> CalculateWeightNewBornValue(ObjectId patientId, PatientObservation? pobs = null)
|
||||
{
|
||||
var result =
|
||||
await _observationService.Value.FindLastObservations(patientId, 1, ["Newborn_Weight"]);
|
||||
var actualObsInBd = result.FirstOrDefault();
|
||||
|
||||
string? strValue;
|
||||
string? obsName;
|
||||
if (pobs == null)
|
||||
{
|
||||
if (actualObsInBd?.Value == null) return 0;
|
||||
|
||||
strValue = actualObsInBd.Value.ToString();
|
||||
obsName = actualObsInBd.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pobs.Units == "kg") pobs = ParseWeight(pobs);
|
||||
|
||||
strValue = pobs.Value.ToString();
|
||||
obsName = pobs.Name;
|
||||
}
|
||||
|
||||
if (!double.TryParse(strValue, out var valueParsed) || obsName == null)
|
||||
return 0;
|
||||
|
||||
var weightNewBornValue = _mappingUtils.GetComplexityValue(obsName, valueParsed);
|
||||
|
||||
|
||||
_logger.LogDebug(
|
||||
"complexity for patient {patientid} => Weight_Newborn plus complexity: {Weight_NewbornValue}",
|
||||
patientId, weightNewBornValue);
|
||||
|
||||
return weightNewBornValue;
|
||||
}
|
||||
|
||||
private PatientObservation ParseWeight(PatientObservation obs)
|
||||
{
|
||||
if (!double.TryParse(obs.Value.ToString(), out var dValue))
|
||||
{
|
||||
_logger.LogError("Error casting weight Observation {obs}:", obs);
|
||||
return obs;
|
||||
}
|
||||
|
||||
obs.Units = "gr";
|
||||
obs.Value = dValue * 1000;
|
||||
return obs;
|
||||
}
|
||||
|
||||
|
||||
private async Task CalculateSaturation_DiffObservation(BasePatientObservation obs)
|
||||
{
|
||||
var toSearchList = new List<string>();
|
||||
PatientObservation? pre;
|
||||
PatientObservation? post;
|
||||
|
||||
toSearchList.AddRange(new List<string> { Spo2PreObservationName, Spo2PostObservationName });
|
||||
|
||||
var values = await _observationService.Value.FindLastObservations(obs.PatientId, 1, toSearchList);
|
||||
var time = obs.Time;
|
||||
|
||||
if (obs.Name == Spo2PreObservationName)
|
||||
{
|
||||
pre = (PatientObservation)obs;
|
||||
post = values.FirstOrDefault(o => o.Name == Spo2PostObservationName);
|
||||
|
||||
if (post?.Time != null && time.CompareTo(post.Time) > 0) time = post.Time;
|
||||
}
|
||||
else
|
||||
{
|
||||
post = (PatientObservation)obs;
|
||||
pre = values.FirstOrDefault(o => o.Name == Spo2PreObservationName);
|
||||
|
||||
if (pre?.Time != null && time.CompareTo(pre.Time) > 0) time = pre.Time;
|
||||
}
|
||||
|
||||
if (pre?.Value != null && post?.Value != null)
|
||||
{
|
||||
var preSuccess = double.TryParse(pre.Value.ToString(), out var preValue);
|
||||
if (!preSuccess) preValue = 0;
|
||||
var postSuccess = double.TryParse(post.Value.ToString(), out var postValue);
|
||||
if (!postSuccess) postValue = 0;
|
||||
|
||||
var saturationDiff = Math.Round(preValue - postValue, 2);
|
||||
|
||||
var saturationDiffObs = new PatientObservation
|
||||
{
|
||||
Name = "SpO2_Diff",
|
||||
CodingSystem = CodingSystem,
|
||||
PatientId = obs.PatientId,
|
||||
Time = time,
|
||||
Value = saturationDiff
|
||||
};
|
||||
var saturationPrePost = new PatientObservation
|
||||
{
|
||||
Name = Spo2PrePostObservationName,
|
||||
CodingSystem = CodingSystem,
|
||||
PatientId = obs.PatientId,
|
||||
Time = time,
|
||||
Value = pre.Value + "/" + post.Value
|
||||
};
|
||||
|
||||
await _observationService.Value.InsertObservation(saturationDiffObs);
|
||||
await _observationService.Value.InsertObservation(saturationPrePost);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<PatientTreatment>> CheckExpiredPatientTreatments(PatientTreatment treatment)
|
||||
{
|
||||
//si el tratamiento ha expirado actualizamos el OrderControl a DC y devolvemos las que siguen activas
|
||||
var result = new List<PatientTreatment>();
|
||||
var oldTreatments = await _treatmentService.Value.GetActiveTreatmentsByPatient(treatment.PatientId);
|
||||
|
||||
foreach (var t in oldTreatments)
|
||||
{
|
||||
if (t == null) continue;
|
||||
|
||||
if (t.PlacerOrder?.EntityIdentifier == treatment.PlacerOrder?.EntityIdentifier)
|
||||
{
|
||||
//Es el mismo tratamiento actualizamos
|
||||
|
||||
if (t.EndTime != null && t.EndTime > DateTime.UtcNow) treatment.OrderControl = OrderControlType.Dc;
|
||||
|
||||
treatment.Id = t.Id; //Asignamos el ID del tratamiento existente para actualizarlo
|
||||
_ = _treatmentService.Value.UpdateTreatment(treatment);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task CheckTreatmentMedicines(PatientTreatment treatment)
|
||||
{
|
||||
var newMedicines = new List<Medicine>();
|
||||
var hasVasoactives = false;
|
||||
foreach (var code in treatment.RequestedGiveCodes)
|
||||
{
|
||||
var m = await _medicineService.Value.GetByCode(code.Identifier);
|
||||
if (m == null) continue;
|
||||
|
||||
//Si el código es de tipo nutrición entonces creamos una observación de ese tipo que tendrá el valor mapeado con el nombre correspondiente
|
||||
//CreateNutritionObservation y NO agregamos a medicamentos
|
||||
var r = _mappingUtils.SearchByCode(m.Codes.First(), "Treatment");
|
||||
if (r is { type: "Nutrition" })
|
||||
{
|
||||
await CreateNutritionObservation(r.Value.group, treatment.PatientId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (r is { type: "Medication", group: "Drogas vasoactivas" })
|
||||
hasVasoactives = true;
|
||||
|
||||
newMedicines.Add(m);
|
||||
}
|
||||
|
||||
if (hasVasoactives)
|
||||
{
|
||||
var vObs = new PatientObservation
|
||||
{
|
||||
Name = "HasVasoactive",
|
||||
Value = true,
|
||||
Time = DateTime.UtcNow,
|
||||
CodingSystem = CodingSystem
|
||||
};
|
||||
|
||||
await _observationService.Value.InsertObservation(vObs, mapObs: false);
|
||||
}
|
||||
|
||||
if (newMedicines.Count == 0)
|
||||
return;
|
||||
|
||||
var _ = await GetActiveTreatmentsByPatient(treatment.PatientId);
|
||||
|
||||
var activeTreatments = _.ToList();
|
||||
|
||||
var __ = await _medicineService.Value.GetMedicinesOfTreatments(activeTreatments); //Todo revisar
|
||||
var activeMedicines = __.ToList();
|
||||
|
||||
// Combina ambas listas y selecciona solo elementos únicos con el mismo nombre
|
||||
var uniqueMedicines = newMedicines
|
||||
.Concat(activeMedicines)
|
||||
.GroupBy(m => m.Name)
|
||||
.Select(g => g.First())
|
||||
.ToList();
|
||||
|
||||
await CalculateMedicineObservation(uniqueMedicines, treatment.PatientId);
|
||||
}
|
||||
|
||||
private async Task CreateNutritionObservation(string value, ObjectId patientId)
|
||||
{
|
||||
var nutritionObs = new PatientObservation
|
||||
{
|
||||
PatientId = patientId,
|
||||
Name = "Feeding_Type",
|
||||
CodingSystem = CodingSystem,
|
||||
Value = value,
|
||||
Time = DateTime.Now
|
||||
};
|
||||
|
||||
if (value.ToLower().Contains("parenteral"))
|
||||
{
|
||||
nutritionObs.Name = "Parenteral";
|
||||
nutritionObs.Value = "SI";
|
||||
}
|
||||
|
||||
var lastNutritionObsList =
|
||||
await _observationService.Value.FindLastObservations(patientId, 1, [nutritionObs.Name]);
|
||||
var lastNutritionObs = lastNutritionObsList.FirstOrDefault();
|
||||
if (lastNutritionObs is { Expired: false })
|
||||
{
|
||||
//expiramos la anterior
|
||||
lastNutritionObs.Expired = true;
|
||||
_ = _observationService.Value.UpdateObservation(lastNutritionObs);
|
||||
}
|
||||
|
||||
await _observationService.Value.InsertObservation(nutritionObs);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user