feature: FHIR R4 Inbound Facade
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user