rama creada apartir de master en j
This commit is contained in:
@@ -15,6 +15,10 @@ using MongoDB.Driver;
|
||||
|
||||
namespace adas_core.Application.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Provides the implementation of the <see cref="IDiagnosisService"/> contract,
|
||||
/// offering diagnosis-related operations as defined by the interface.
|
||||
/// </summary>
|
||||
public class DiagnosisService : IDiagnosisService
|
||||
{
|
||||
private readonly ILocalAuditService _auditService;
|
||||
@@ -81,283 +85,366 @@ public class DiagnosisService : IDiagnosisService
|
||||
// await _clientMessageService.SendAsync(subscriber.Id, OperationType.Diagnosis, diagnosis);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Archives the specified patient by delegating to the archival routine keyed by the patient's identifier.
|
||||
/// </summary>
|
||||
/// <param name="patient">The patient to be archived. Its <c>Id</c> is used to locate the record to archive.</param>
|
||||
public async Task Archive(Patient patient)
|
||||
{
|
||||
await ArchiveByPatientId(patient.Id);
|
||||
}
|
||||
{
|
||||
await ArchiveByPatientId(patient.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Archives all diagnoses associated with the specified patient by copying them to the diagnosis archive repository and then deleting the original records.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the patient whose diagnoses will be archived.</param>
|
||||
public async Task ArchiveByPatientId(ObjectId id)
|
||||
{
|
||||
_logger.LogDebug("Archive Diagnoses by Patient Id {id}", id);
|
||||
using (var cursor = await FindByPatientIdAsync(id))
|
||||
{
|
||||
while (await cursor.MoveNextAsync())
|
||||
foreach (var current in cursor.Current)
|
||||
await _diagnosisArchiveRepository.InsertOneAsync(current);
|
||||
_logger.LogDebug("Archive Diagnoses by Patient Id {id}", id);
|
||||
using (var cursor = await FindByPatientIdAsync(id))
|
||||
{
|
||||
while (await cursor.MoveNextAsync())
|
||||
foreach (var current in cursor.Current)
|
||||
await _diagnosisArchiveRepository.InsertOneAsync(current);
|
||||
}
|
||||
|
||||
await DeleteByPatientId(id);
|
||||
}
|
||||
|
||||
await DeleteByPatientId(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all diagnoses associated with the specified patient identifier and records an audit log entry capturing the previous state of the records.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the patient whose diagnoses should be deleted.</param>
|
||||
public async Task DeleteByPatientId(ObjectId id)
|
||||
{
|
||||
_logger.LogDebug("Delete Diagnoses by Patient Id {id}", id);
|
||||
var oldPatient = await _diagnosisRepository.GetByPatient(id);
|
||||
await _diagnosisRepository.DeleteByPatientId(id);
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, oldPatient, null);
|
||||
}
|
||||
{
|
||||
_logger.LogDebug("Delete Diagnoses by Patient Id {id}", id);
|
||||
var oldPatient = await _diagnosisRepository.GetByPatient(id);
|
||||
await _diagnosisRepository.DeleteByPatientId(id);
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, oldPatient, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves the list of patient diagnoses associated with the specified patient identifier by delegating to the diagnosis repository.
|
||||
/// </summary>
|
||||
/// <param name="patientId">The unique identifier of the patient whose diagnoses are being retrieved.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing a list of <see cref="PatientDiagnosis"/> records for the given patient.</returns>
|
||||
public async Task<List<PatientDiagnosis>> GetByPatientId(ObjectId patientId)
|
||||
{
|
||||
var diagnosis = await _diagnosisRepository.GetByPatient(patientId);
|
||||
|
||||
return diagnosis;
|
||||
}
|
||||
{
|
||||
var diagnosis = await _diagnosisRepository.GetByPatient(patientId);
|
||||
|
||||
return diagnosis;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously saves the specified API request by delegating to an overload that accepts a secondary parameter, which is passed as null.
|
||||
/// </summary>
|
||||
/// <param name="apiRequest">The API request to save.</param>
|
||||
/// <returns>A task that represents the asynchronous save operation.</returns>
|
||||
public Task SaveRequest(ApiRequest apiRequest)
|
||||
{
|
||||
return Task.FromResult(Task.Run(async () => { await SaveRequest(apiRequest, null); }));
|
||||
}
|
||||
{
|
||||
return Task.FromResult(Task.Run(async () => { await SaveRequest(apiRequest, null); }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously saves the specified API request by delegating to the underlying save operation with a null secondary parameter.
|
||||
/// </summary>
|
||||
/// <param name="apiRequest">The API request instance to persist.</param>
|
||||
/// <returns>A task that represents the asynchronous save operation.</returns>
|
||||
public Task SaveRequestAsync(ApiRequest apiRequest)
|
||||
{
|
||||
return Task.FromResult(Task.Run(async () => { await SaveRequest(apiRequest, null); }));
|
||||
}
|
||||
{
|
||||
return Task.FromResult(Task.Run(async () => { await SaveRequest(apiRequest, null); }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a diagnosis observation from an API request and persists it as a patient diagnosis. Maps SNOMED-coded observation values to diagnosis properties (description, label, code, state, category, start/end time), falling back to the current date when the observation time is missing, and skipping processing if the observations collection is null.
|
||||
/// </summary>
|
||||
/// <param name="apiRequest">The API request containing the observation codes, values, message time, and optional observation time used to build the diagnosis.</param>
|
||||
/// <param name="patient">The patient associated with the diagnosis, whose identifier is assigned to the new <see cref="PatientDiagnosis"/>.</param>
|
||||
/// <returns>A task that represents the asynchronous insertion of the resulting <see cref="PatientDiagnosis"/>.</returns>
|
||||
public async Task ProcessDiagnosisObservation(ApiRequest apiRequest, Patient patient)
|
||||
{
|
||||
_logger.LogDebug("INSERT DiagnosisObservation from obsservation");
|
||||
|
||||
var time = apiRequest.ObservationData?.Time;
|
||||
if (time == null)
|
||||
_logger.LogWarning("Processing diagnosis without time. Set Datetime now {DateTimeNow}. ", DateTime.Now);
|
||||
|
||||
var obs = new PatientDiagnosis
|
||||
{
|
||||
CodingSystem = _diagnosisSystem,
|
||||
Time = time ?? DateTime.Now,
|
||||
PatientId = patient.Id,
|
||||
MessageTime = apiRequest.MessageTime
|
||||
};
|
||||
|
||||
if (apiRequest.Observations == null)
|
||||
{
|
||||
_logger.LogError("ApiRequest Observations null. ");
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i <= apiRequest.Observations.Count - 1; i++)
|
||||
{
|
||||
var value = apiRequest.Observations[i].Value;
|
||||
|
||||
var strValue = value.ToString() ?? "null";
|
||||
|
||||
switch (apiRequest.Observations[i].Code)
|
||||
_logger.LogDebug("INSERT DiagnosisObservation from obsservation");
|
||||
|
||||
var time = apiRequest.ObservationData?.Time;
|
||||
if (time == null)
|
||||
_logger.LogWarning("Processing diagnosis without time. Set Datetime now {DateTimeNow}. ", DateTime.Now);
|
||||
|
||||
var obs = new PatientDiagnosis
|
||||
{
|
||||
case "272099008":
|
||||
obs.Description = strValue;
|
||||
break;
|
||||
|
||||
case "1000000013":
|
||||
obs.Label = strValue;
|
||||
break;
|
||||
|
||||
case "1000000014":
|
||||
obs.Code = strValue;
|
||||
break;
|
||||
|
||||
case "394731006":
|
||||
obs.State = strValue;
|
||||
break;
|
||||
|
||||
case "272125009":
|
||||
obs.Category = strValue;
|
||||
break;
|
||||
|
||||
case "398201009":
|
||||
if (DateTime.TryParse(apiRequest.Observations[i].Value.ToString(), out var startTime))
|
||||
obs.StartTime = startTime;
|
||||
break;
|
||||
|
||||
case "397898000":
|
||||
if (DateTime.TryParse(apiRequest.Observations[i].Value.ToString(), out var endTime))
|
||||
obs.EndTime = endTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await InsertDiagnosis(obs);
|
||||
}
|
||||
|
||||
public async Task SaveRequest(ApiRequest apiRequest, Patient? patient)
|
||||
{
|
||||
if (patient == null)
|
||||
{
|
||||
_logger.LogDebug("message:ApiRequest Diagnosis");
|
||||
if (string.IsNullOrEmpty(apiRequest.PatientNumber) &&
|
||||
string.IsNullOrEmpty(apiRequest.Location?.UnitName))
|
||||
CodingSystem = _diagnosisSystem,
|
||||
Time = time ?? DateTime.Now,
|
||||
PatientId = patient.Id,
|
||||
MessageTime = apiRequest.MessageTime
|
||||
};
|
||||
|
||||
if (apiRequest.Observations == null)
|
||||
{
|
||||
_logger.LogDebug("person and PointOfCare are nulls");
|
||||
throw new ApiRequestException("person and PointOfCare are nulls");
|
||||
_logger.LogError("ApiRequest Observations null. ");
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogDebug("patientNumber: {apiRequestpatientNumber} location: {apiRequestlocation}",
|
||||
apiRequest.PatientNumber, apiRequest.Location);
|
||||
_logger.LogDebug("RequestType: {apiRequesttype}", apiRequest.Type);
|
||||
|
||||
patient = await _patientService.Value.FindPatientByApiRequest(apiRequest);
|
||||
}
|
||||
|
||||
if (patient == null)
|
||||
{
|
||||
// NO PATIENTS OR LOCATIONS WERE FOUND
|
||||
_logger.LogWarning(
|
||||
"Observation for patient: {apiRequestpatientNumber} with location: {apiRequestlocation} not found, ignoring",
|
||||
apiRequest.PatientNumber, apiRequest.Location);
|
||||
return;
|
||||
}
|
||||
|
||||
var unitConfig = await _unitService.FindById(patient.UnitId);
|
||||
if (!Hl7Utils.ManageAutoAdt(unitConfig, null, _logger, "ORU Diagnosis")) return;
|
||||
|
||||
switch (apiRequest.Type)
|
||||
{
|
||||
//* ORU_R01 - Unsolicited transmission of an observation message
|
||||
//* ORU_R40 - Unsolicited transmission of an alert observation message
|
||||
|
||||
case "ORU_R01":
|
||||
case "ORU_R40":
|
||||
|
||||
// OBSERVATIONS
|
||||
if (apiRequest.Observation != null && apiRequest.Observations?.FirstOrDefault() == null)
|
||||
apiRequest.Observations = [apiRequest.Observation];
|
||||
|
||||
if (apiRequest.Observations != null)
|
||||
|
||||
for (var i = 0; i <= apiRequest.Observations.Count - 1; i++)
|
||||
{
|
||||
var value = apiRequest.Observations[i].Value;
|
||||
|
||||
var strValue = value.ToString() ?? "null";
|
||||
|
||||
switch (apiRequest.Observations[i].Code)
|
||||
{
|
||||
var obrcode = apiRequest.ObservationData?.Code;
|
||||
|
||||
if (apiRequest.ObservationData?.Value != null)
|
||||
apiRequest.Observations.Add(new PatientObservation
|
||||
{ Value = apiRequest.ObservationData.Value });
|
||||
|
||||
if (obrcode != null && _diagnosisCode.Contains(obrcode))
|
||||
_ = ProcessDiagnosisObservation(apiRequest, patient);
|
||||
case "272099008":
|
||||
obs.Description = strValue;
|
||||
break;
|
||||
|
||||
case "1000000013":
|
||||
obs.Label = strValue;
|
||||
break;
|
||||
|
||||
case "1000000014":
|
||||
obs.Code = strValue;
|
||||
break;
|
||||
|
||||
case "394731006":
|
||||
obs.State = strValue;
|
||||
break;
|
||||
|
||||
case "272125009":
|
||||
obs.Category = strValue;
|
||||
break;
|
||||
|
||||
case "398201009":
|
||||
if (DateTime.TryParse(apiRequest.Observations[i].Value.ToString(), out var startTime))
|
||||
obs.StartTime = startTime;
|
||||
break;
|
||||
|
||||
case "397898000":
|
||||
if (DateTime.TryParse(apiRequest.Observations[i].Value.ToString(), out var endTime))
|
||||
obs.EndTime = endTime;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
_logger.LogWarning("ApiRequest type {apiRequesttype} sis not valid for Diagnosis",
|
||||
apiRequest.Type);
|
||||
throw new ApiRequestException("ApiRequest type " + apiRequest.Type +
|
||||
" is not valid for Diagnosis");
|
||||
}
|
||||
|
||||
await InsertDiagnosis(obs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes an incoming API request for diagnosis-related observations, resolving the patient from the request when not supplied. Validates that at least one of the patient number or location unit name is provided, handles ORU_R01 and ORU_R40 observation messages, and triggers diagnosis observation processing when the observation code is recognized.
|
||||
/// </summary>
|
||||
/// <param name="apiRequest">The API request containing the type, patient identifiers, location, and observation data to be processed.</param>
|
||||
/// <param name="patient">An optional pre-resolved patient; when null, the patient is resolved via the patient service using the request data.</param>
|
||||
/// <exception cref="ApiRequestException">Thrown when both the patient number and the location unit name are missing from the request, or when the request type is not valid for diagnosis processing.</exception>
|
||||
public async Task SaveRequest(ApiRequest apiRequest, Patient? patient)
|
||||
{
|
||||
if (patient == null)
|
||||
{
|
||||
_logger.LogDebug("message:ApiRequest Diagnosis");
|
||||
if (string.IsNullOrEmpty(apiRequest.PatientNumber) &&
|
||||
string.IsNullOrEmpty(apiRequest.Location?.UnitName))
|
||||
{
|
||||
_logger.LogDebug("person and PointOfCare are nulls");
|
||||
throw new ApiRequestException("person and PointOfCare are nulls");
|
||||
}
|
||||
|
||||
_logger.LogDebug("patientNumber: {apiRequestpatientNumber} location: {apiRequestlocation}",
|
||||
apiRequest.PatientNumber, apiRequest.Location);
|
||||
_logger.LogDebug("RequestType: {apiRequesttype}", apiRequest.Type);
|
||||
|
||||
patient = await _patientService.Value.FindPatientByApiRequest(apiRequest);
|
||||
}
|
||||
|
||||
if (patient == null)
|
||||
{
|
||||
// NO PATIENTS OR LOCATIONS WERE FOUND
|
||||
_logger.LogWarning(
|
||||
"Observation for patient: {apiRequestpatientNumber} with location: {apiRequestlocation} not found, ignoring",
|
||||
apiRequest.PatientNumber, apiRequest.Location);
|
||||
return;
|
||||
}
|
||||
|
||||
var unitConfig = await _unitService.FindById(patient.UnitId);
|
||||
if (!Hl7Utils.ManageAutoAdt(unitConfig, null, _logger, "ORU Diagnosis")) return;
|
||||
|
||||
switch (apiRequest.Type)
|
||||
{
|
||||
//* ORU_R01 - Unsolicited transmission of an observation message
|
||||
//* ORU_R40 - Unsolicited transmission of an alert observation message
|
||||
|
||||
case "ORU_R01":
|
||||
case "ORU_R40":
|
||||
|
||||
// OBSERVATIONS
|
||||
if (apiRequest.Observation != null && apiRequest.Observations?.FirstOrDefault() == null)
|
||||
apiRequest.Observations = [apiRequest.Observation];
|
||||
|
||||
if (apiRequest.Observations != null)
|
||||
{
|
||||
var obrcode = apiRequest.ObservationData?.Code;
|
||||
|
||||
if (apiRequest.ObservationData?.Value != null)
|
||||
apiRequest.Observations.Add(new PatientObservation
|
||||
{ Value = apiRequest.ObservationData.Value });
|
||||
|
||||
if (obrcode != null && _diagnosisCode.Contains(obrcode))
|
||||
_ = ProcessDiagnosisObservation(apiRequest, patient);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
_logger.LogWarning("ApiRequest type {apiRequesttype} sis not valid for Diagnosis",
|
||||
apiRequest.Type);
|
||||
throw new ApiRequestException("ApiRequest type " + apiRequest.Type +
|
||||
" is not valid for Diagnosis");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a list of patient diagnoses by associating each entry with the specified patient and message time, then inserting them as diagnosis observations.
|
||||
/// </summary>
|
||||
/// <param name="diagnosis">The list of patient diagnoses to be processed and inserted.</param>
|
||||
/// <param name="patient">The patient whose identifier is assigned to each diagnosis entry.</param>
|
||||
/// <param name="messageTime">The timestamp assigned to each diagnosis entry during processing.</param>
|
||||
public async Task ProcessDiagnosis(List<PatientDiagnosis> diagnosis, Patient patient, DateTime messageTime)
|
||||
{
|
||||
_logger.LogDebug("INSERT DiagnosisObservation from diagnosis");
|
||||
|
||||
foreach (var d in diagnosis)
|
||||
{
|
||||
d.PatientId = patient.Id;
|
||||
d.Time = messageTime;
|
||||
await InsertDiagnosis(d);
|
||||
_logger.LogDebug("INSERT DiagnosisObservation from diagnosis");
|
||||
|
||||
foreach (var d in diagnosis)
|
||||
{
|
||||
d.PatientId = patient.Id;
|
||||
d.Time = messageTime;
|
||||
await InsertDiagnosis(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates many diagnosis records, replacing the <paramref name="oldId"/> with the new <paramref name="id"/> for the specified <paramref name="nameId"/> field, by delegating to the diagnosis repository.
|
||||
/// </summary>
|
||||
/// <param name="nameId">The name of the identifier field used to locate the records to update.</param>
|
||||
/// <param name="id">The new ObjectId to assign to the matching records.</param>
|
||||
/// <param name="oldId">The existing ObjectId to be replaced in the matching records.</param>
|
||||
public async Task UpdateManyObjectId(string nameId, ObjectId id, ObjectId oldId)
|
||||
{
|
||||
await _diagnosisRepository.UpdateManyObjectId(nameId, id, oldId);
|
||||
}
|
||||
{
|
||||
await _diagnosisRepository.UpdateManyObjectId(nameId, id, oldId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all diagnoses associated with the specified patient identifier from the diagnosis repository.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the patient whose diagnoses are being requested.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing a list of <see cref="PatientDiagnosis"/> records for the given patient.</returns>
|
||||
public async Task<List<PatientDiagnosis>> GetByPatient(ObjectId id)
|
||||
{
|
||||
return await _diagnosisRepository.GetByPatient(id);
|
||||
}
|
||||
{
|
||||
return await _diagnosisRepository.GetByPatient(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a patient diagnosis into the repository after mapping it to the underlying data model, and broadcasts the stored record.
|
||||
/// If the diagnosis cannot be mapped (returns null), the insert and broadcast operations are skipped.
|
||||
/// </summary>
|
||||
/// <param name="diagnosis">The patient diagnosis to insert.</param>
|
||||
public async Task Insert(PatientDiagnosis diagnosis)
|
||||
{
|
||||
_logger.LogDebug("Insert {diagnosis}", diagnosis);
|
||||
var diag = await MapDiagnosis(diagnosis);
|
||||
if (diag != null)
|
||||
{
|
||||
await _diagnosisRepository.InsertOneAsync(diag);
|
||||
await SendBroadcast(diag);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<PatientDiagnosis?> MapDiagnosis(PatientDiagnosis diagnosis)
|
||||
{
|
||||
var diagnosis2 = await _calculatedObservations.Value.Map(diagnosis);
|
||||
if (diagnosis2 == null) _logger.LogDebug("Mapping {diagnosis}: Ignored", diagnosis2);
|
||||
|
||||
return diagnosis2;
|
||||
}
|
||||
|
||||
private async Task SendBroadcast(PatientDiagnosis diagnosis)
|
||||
{
|
||||
var patient = await _patientService.Value.FindById(diagnosis.PatientId);
|
||||
if (patient == null) return;
|
||||
|
||||
var displaySubscribers = _subscribersService.GetSubscribers().Where(s =>
|
||||
!s.Locations.IsNullOrEmpty() && s.Locations.Any(c =>
|
||||
c.UnitName == patient.Location.UnitName &&
|
||||
c.Bed == patient.Location.Bed &&
|
||||
c.Room == patient.Location.Room
|
||||
)).ToList();
|
||||
|
||||
displaySubscribers.ForEach(Action);
|
||||
return;
|
||||
|
||||
void Action(WsSubscriber subscriber)
|
||||
{
|
||||
_clientMessageService.SendAsync(subscriber.Id, OperationType.Diagnosis, diagnosis);
|
||||
}
|
||||
}
|
||||
|
||||
public Task<IAsyncCursor<PatientDiagnosis>> FindByPatientIdAsync(ObjectId patientId)
|
||||
{
|
||||
return _diagnosisRepository.FindByPatientIdAsync(patientId);
|
||||
}
|
||||
|
||||
public async Task InsertDiagnosis(PatientDiagnosis diagnosis)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogDebug("Insert {diagnosis}", diagnosis);
|
||||
var diag = await MapDiagnosis(diagnosis);
|
||||
if (diag == null)
|
||||
if (diag != null)
|
||||
{
|
||||
_logger.LogError("Mepped diagnosis is null. Diagnosis: {diagnosis}", diagnosis);
|
||||
await _diagnosisRepository.InsertOneAsync(diag);
|
||||
await SendBroadcast(diag);
|
||||
}
|
||||
else
|
||||
{
|
||||
var dgdb = await _diagnosisRepository.FindByPatientIdAndCode(diag.PatientId, diag.Code,
|
||||
diag.CodingSystem);
|
||||
}
|
||||
|
||||
if (dgdb != null)
|
||||
/// <summary>
|
||||
/// Maps a <see cref="PatientDiagnosis"/> through the calculated observations mapper to produce a transformed diagnosis instance.
|
||||
/// When the mapper yields a <see langword="null"/> result, indicating the diagnosis is not applicable or cannot be mapped, a debug message is logged and the result is returned as-is.
|
||||
/// </summary>
|
||||
/// <param name="diagnosis">The patient diagnosis to be mapped.</param>
|
||||
/// <returns>The mapped <see cref="PatientDiagnosis"/> produced by the calculated observations mapper, or <see langword="null"/> if the diagnosis was ignored.</returns>
|
||||
private async Task<PatientDiagnosis?> MapDiagnosis(PatientDiagnosis diagnosis)
|
||||
{
|
||||
var diagnosis2 = await _calculatedObservations.Value.Map(diagnosis);
|
||||
if (diagnosis2 == null) _logger.LogDebug("Mapping {diagnosis}: Ignored", diagnosis2);
|
||||
|
||||
return diagnosis2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a patient diagnosis broadcast to all subscribers whose registered location matches the patient's location (unit, room, and bed). Returns early without broadcasting if the patient cannot be found.
|
||||
/// </summary>
|
||||
/// <param name="diagnosis">The patient diagnosis payload to broadcast to the matching subscribers.</param>
|
||||
private async Task SendBroadcast(PatientDiagnosis diagnosis)
|
||||
{
|
||||
var patient = await _patientService.Value.FindById(diagnosis.PatientId);
|
||||
if (patient == null) return;
|
||||
|
||||
var displaySubscribers = _subscribersService.GetSubscribers().Where(s =>
|
||||
!s.Locations.IsNullOrEmpty() && s.Locations.Any(c =>
|
||||
c.UnitName == patient.Location.UnitName &&
|
||||
c.Bed == patient.Location.Bed &&
|
||||
c.Room == patient.Location.Room
|
||||
)).ToList();
|
||||
|
||||
displaySubscribers.ForEach(Action);
|
||||
return;
|
||||
|
||||
void Action(WsSubscriber subscriber)
|
||||
{
|
||||
_clientMessageService.SendAsync(subscriber.Id, OperationType.Diagnosis, diagnosis);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves all patient diagnosis records associated with the specified patient identifier by delegating to the diagnosis repository.
|
||||
/// </summary>
|
||||
/// <param name="patientId">The unique identifier of the patient whose diagnosis records are to be retrieved.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing an asynchronous cursor over the matching <see cref="PatientDiagnosis"/> records.</returns>
|
||||
public Task<IAsyncCursor<PatientDiagnosis>> FindByPatientIdAsync(ObjectId patientId)
|
||||
{
|
||||
return _diagnosisRepository.FindByPatientIdAsync(patientId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts or updates a patient diagnosis, creating an audit log entry. If a diagnosis
|
||||
/// already exists for the same patient, code, and coding system, it is updated while
|
||||
/// preserving its identifier and original timestamp; otherwise a new record is inserted.
|
||||
/// A broadcast is dispatched asynchronously after a successful insert or update.
|
||||
/// </summary>
|
||||
/// <param name="diagnosis">The patient diagnosis to persist.</param>
|
||||
public async Task InsertDiagnosis(PatientDiagnosis diagnosis)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogDebug("Insert {diagnosis}", diagnosis);
|
||||
var diag = await MapDiagnosis(diagnosis);
|
||||
if (diag == null)
|
||||
{
|
||||
var auxDgdb = dgdb;
|
||||
diag.Id = dgdb.Id;
|
||||
diag.Time = dgdb.Time;
|
||||
diag.UpdateDate = diagnosis.Time;
|
||||
await _diagnosisRepository.UpdateOneAsync(diag.Id, diag);
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, auxDgdb, dgdb);
|
||||
_logger.LogError("Mepped diagnosis is null. Diagnosis: {diagnosis}", diagnosis);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _diagnosisRepository.InsertOneAsync(diagnosis);
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, null, diagnosis);
|
||||
var dgdb = await _diagnosisRepository.FindByPatientIdAndCode(diag.PatientId, diag.Code,
|
||||
diag.CodingSystem);
|
||||
|
||||
if (dgdb != null)
|
||||
{
|
||||
var auxDgdb = dgdb;
|
||||
diag.Id = dgdb.Id;
|
||||
diag.Time = dgdb.Time;
|
||||
diag.UpdateDate = diagnosis.Time;
|
||||
await _diagnosisRepository.UpdateOneAsync(diag.Id, diag);
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, auxDgdb, dgdb);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _diagnosisRepository.InsertOneAsync(diagnosis);
|
||||
await _auditService.CreateAuditLogAsync(_httpContextAccessor.HttpContext?.User!, null, diagnosis);
|
||||
}
|
||||
|
||||
_ = SendBroadcast(diagnosis);
|
||||
}
|
||||
|
||||
_ = SendBroadcast(diagnosis);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("Error inserting diagnosis. Diagnosis: {diagnosis}. Exception:{ex}", diagnosis, ex);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("Error inserting diagnosis. Diagnosis: {diagnosis}. Exception:{ex}", diagnosis, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user