103 lines
4.0 KiB
C#
103 lines
4.0 KiB
C#
using Hl7.Fhir.Model;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
|
public class EncounterFhirMapper
|
|
{
|
|
private readonly FhirReferenceResolver _refs;
|
|
private readonly FhirOptions _options;
|
|
|
|
public EncounterFhirMapper(FhirReferenceResolver refs, IOptions<FhirOptions> options)
|
|
{
|
|
_refs = refs;
|
|
_options = options.Value;
|
|
}
|
|
|
|
public async Task<FhirEncounterUpsertRequest> ToUpsertRequestAsync(Hl7.Fhir.Model.Encounter fhir)
|
|
{
|
|
var identifier = _refs.ExtractPrimaryIdentifier(fhir, _options.EncounterIdentifierSystems)
|
|
?? throw new FhirMappingException("Encounter must include at least one identifier.", "required");
|
|
|
|
if (fhir.Subject is null)
|
|
throw new FhirMappingException("Encounter subject is required.", "required");
|
|
|
|
var patientId = await _refs.ResolvePatientReferenceAsync(fhir.Subject);
|
|
|
|
var actCode = fhir.Class?.Code ?? "IMP";
|
|
if (!_options.EncounterClassMap.TryGetValue(actCode, out var encounterTypeStr))
|
|
encounterTypeStr = _options.DefaultEncounterType;
|
|
|
|
var departmentStr = _options.DefaultDepartment;
|
|
var locationCode = fhir.Location?.FirstOrDefault()?.Location?.Display;
|
|
if (locationCode is not null)
|
|
{
|
|
foreach (var (key, value) in _options.DepartmentCodeMap)
|
|
{
|
|
if (locationCode.Contains(key, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
departmentStr = value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
var attending = fhir.Participant?
|
|
.FirstOrDefault(p => p.Type?.Any(t =>
|
|
t.Coding?.Any(c => c.Code == "ATND") == true) == true)
|
|
?.Individual?.Display ?? "Unknown";
|
|
|
|
var targetStatus = fhir.Status switch
|
|
{
|
|
Hl7.Fhir.Model.Encounter.EncounterStatus.Finished => EncounterStatus.Discharged,
|
|
Hl7.Fhir.Model.Encounter.EncounterStatus.Cancelled => EncounterStatus.Cancelled,
|
|
_ => EncounterStatus.Active
|
|
};
|
|
|
|
return new FhirEncounterUpsertRequest(
|
|
IdentifierSystem: identifier.System,
|
|
IdentifierValue: identifier.Value,
|
|
PatientId: patientId,
|
|
EncounterType: EncounterTypeExtensions.FromDbString(encounterTypeStr),
|
|
Department: DepartmentExtensions.FromDbString(departmentStr),
|
|
AttendingPhysician: attending,
|
|
TargetStatus: targetStatus,
|
|
AdmittedAt: fhir.Period?.StartElement?.ToDateTimeOffset(TimeSpan.Zero),
|
|
RoomBed: fhir.Location?.FirstOrDefault()?.Location?.Display,
|
|
AdmissionReason: fhir.ReasonCode?.FirstOrDefault()?.Text);
|
|
}
|
|
|
|
public Hl7.Fhir.Model.Encounter ToFhirResponse(Encounter encounter, (string System, string Value)? hospitalId)
|
|
{
|
|
var resource = new Hl7.Fhir.Model.Encounter
|
|
{
|
|
Id = encounter.Id.ToString(),
|
|
Status = encounter.Status switch
|
|
{
|
|
EncounterStatus.Active => Hl7.Fhir.Model.Encounter.EncounterStatus.InProgress,
|
|
EncounterStatus.Discharged => Hl7.Fhir.Model.Encounter.EncounterStatus.Finished,
|
|
EncounterStatus.Cancelled => Hl7.Fhir.Model.Encounter.EncounterStatus.Cancelled,
|
|
_ => Hl7.Fhir.Model.Encounter.EncounterStatus.Unknown
|
|
},
|
|
Class = new Coding("http://terminology.hl7.org/CodeSystem/v3-ActCode", "IMP"),
|
|
Subject = new ResourceReference($"Patient/{encounter.PatientId}"),
|
|
Identifier = new List<Identifier>()
|
|
};
|
|
|
|
if (hospitalId is not null)
|
|
{
|
|
resource.Identifier.Add(new Identifier
|
|
{
|
|
System = hospitalId.Value.System,
|
|
Value = hospitalId.Value.Value
|
|
});
|
|
}
|
|
|
|
resource.Identifier.Add(new Identifier
|
|
{
|
|
System = _options.InternalEncounterIdSystem,
|
|
Value = encounter.Id.ToString()
|
|
});
|
|
|
|
return resource;
|
|
}
|
|
} |