using Hl7.Fhir.Model; using Microsoft.Extensions.Options; public class PatientFhirMapper { private readonly FhirReferenceResolver _refs; private readonly FhirOptions _options; public PatientFhirMapper(FhirReferenceResolver refs, IOptions options) { _refs = refs; _options = options.Value; } public FhirPatientUpsertRequest ToUpsertRequest(Hl7.Fhir.Model.Patient fhir) { var identifier = _refs.ExtractPrimaryIdentifier(fhir, _options.PatientIdentifierSystems) ?? throw new FhirMappingException("Patient must include at least one identifier.", "required"); var name = fhir.Name?.FirstOrDefault() ?? throw new FhirMappingException("Patient must include a name.", "required"); var given = name.Given?.FirstOrDefault() ?? ""; var family = name.Family ?? ""; if (fhir.BirthDate is null) throw new FhirMappingException("Patient birthDate is required.", "required"); return new FhirPatientUpsertRequest( IdentifierSystem: identifier.System, IdentifierValue: identifier.Value, FirstName: given, LastName: family, DateOfBirth: DateOnly.Parse(fhir.BirthDate), Gender: fhir.Gender?.ToString()?.ToLowerInvariant() ?? "unknown"); } public Hl7.Fhir.Model.Patient ToFhirResponse(Patient patient, (string System, string Value)? hospitalId) { var resource = new Hl7.Fhir.Model.Patient { Id = patient.Id.ToString(), Identifier = new List() }; if (hospitalId is not null) { resource.Identifier.Add(new Identifier { System = hospitalId.Value.System, Value = hospitalId.Value.Value, Type = new CodeableConcept("http://terminology.hl7.org/CodeSystem/v2-0203", "MR") }); } resource.Identifier.Add(new Identifier { System = _options.InternalPatientIdSystem, Value = patient.Id.ToString() }); resource.Name.Add(new HumanName { Given = new[] { patient.FirstName }, Family = patient.LastName }); resource.BirthDate = patient.DateOfBirth.ToString("yyyy-MM-dd"); resource.Gender = patient.Gender switch { "male" => AdministrativeGender.Male, "female" => AdministrativeGender.Female, _ => AdministrativeGender.Unknown }; return resource; } }