Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add proficiency and mode to patient language #3083

Merged
merged 11 commits into from
Jan 6, 2025

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion containers/ecr-viewer/src/app/api/fhirPath.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ patientRace: "Bundle.entry.resource.where(resourceType = 'Patient').extension.wh
patientRaceDetailed: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-race').extension.where(url = 'detailed').valueCoding.display"
patientEthnicity: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity').extension.where(url = 'ombCategory').valueCoding.display"
patientEthnicityDetailed: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity').extension.where(url = 'detailed').valueCoding.display"
patientLanguage: "Bundle.entry.resource.where(resourceType = 'Patient').communication.first().language.coding.first().display"
patientCommunication: "Bundle.entry.resource.where(resourceType = 'Patient').communication"
patientTribalAffiliation: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url='http://hl7.org/fhir/us/ecr/StructureDefinition/us-ph-tribal-affiliation-extension').extension.where(url='TribeName').value"
patientEmergencyContact: "Bundle.entry.resource.where(resourceType = 'Patient').contact"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import {
Coding,
Condition,
Encounter,
Extension,
HumanName,
Location,
Organization,
PatientCommunication,
PatientContact,
Practitioner,
PractitionerRole,
Expand Down Expand Up @@ -337,7 +339,7 @@ export const evaluateDemographicsData = (
},
{
title: "Preferred Language",
value: evaluate(fhirBundle, mappings.patientLanguage)[0],
value: evaluatePatientLanguage(fhirBundle, mappings),
},
{
title: "Patient Address",
Expand Down Expand Up @@ -630,7 +632,10 @@ export const evaluateReference = (
* @param path - The path within the resource to extract the value from.
* @returns - The evaluated value as a string.
*/
export const evaluateValue = (entry: Element, path: string | Path): string => {
export const evaluateValue = (
entry: Element | Element[],
path: string | Path,
): string => {
let originalValue = evaluate(entry, path, undefined, fhirpath_r4_model)[0];

let value = "";
Expand Down Expand Up @@ -737,3 +742,52 @@ export const evaluateEncounterDiagnosis = (
.map((condition) => condition.code?.coding?.[0].display)
.join(", ");
};

/**
* Evaluate patient's prefered language
* @param fhirBundle - The FHIR bundle containing resources.
* @param mappings - Path mappings for resolving references.
* @returns String containing language, proficiency, and mode
*/
export const evaluatePatientLanguage = (
fhirBundle: Bundle,
mappings: PathMappings,
) => {
let patientCommunication: PatientCommunication[] = evaluate(
fhirBundle,
mappings.patientCommunication,
);
const preferedPatientCommunication = patientCommunication.filter(
(communication) => communication.preferred,
);

if (preferedPatientCommunication.length > 0) {
patientCommunication = preferedPatientCommunication;
}

return patientCommunication
.map((communication) => {
const patientProficiencyExtension: Extension[] = evaluate(
communication,
"extension.where(url = 'http://hl7.org/fhir/StructureDefinition/patient-proficiency')",
);
const patientLanguage: string | undefined = evaluateValue(
communication,
"language.coding",
);
const languageProficency: string | undefined = evaluateValue(
patientProficiencyExtension,
"extension.where(url = 'level').value",
);
const languageMode: string | undefined = evaluateValue(
patientProficiencyExtension,
"extension.where(url = 'type').value",
);

return [patientLanguage, languageProficency, languageMode]
.filter(Boolean)
.join("\n");
})
.filter(Boolean)
.join("\n\n");
};
37 changes: 36 additions & 1 deletion containers/ecr-viewer/src/app/tests/assets/BundlePatient.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,17 @@
}
],
"communication": [
{
"language": {
"coding": [
{
"system": "urn:ietf:bcp:47",
"code": "es",
"display": "Spanish"
}
]
}
},
{
"language": {
"coding": [
Expand All @@ -169,7 +180,31 @@
"display": "English"
}
]
}
},
"preferred": true,
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/patient-proficiency",
"extension": [
{
"url": "type",
"valueCoding": {
"system": "http://terminology.hl7.org/CodeSystem/v3-LanguageAbilityMode",
"code": "ESP",
"display": "Expressed spoken"
}
},
{
"url": "level",
"valueCoding": {
"system": "http://terminology.hl7.org/CodeSystem/v3-LanguageAbilityProficiency",
"code": "G",
"display": "Good"
}
}
]
}
]
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
evaluateDemographicsData,
evaluateEncounterCareTeamTable,
evaluateAlcoholUse,
evaluatePatientLanguage,
} from "@/app/services/evaluateFhirDataService";
import { Bundle, Patient } from "fhir/r4";
import BundleWithMiscNotes from "@/app/tests/assets/BundleMiscNotes.json";
Expand Down Expand Up @@ -538,3 +539,114 @@ describe("Evaluate Alcohol Use", () => {
expect(actual).toEqual("");
});
});

describe("Evaluate Patient language", () => {
it("Should display language, proficiency, and mode", () => {
const actual = evaluatePatientLanguage(
BundleWithPatient as unknown as Bundle,
mappings,
);

expect(actual).toEqual("English\nGood\nExpressed spoken");
});

it("Should only display preferred languages", () => {
const patient = {
resourceType: "Bundle",
entry: [
{
resource: {
resourceType: "Patient",
communication: [
{
language: {
coding: [
{
system: "urn:ietf:bcp:47",
code: "es",
display: "Spanish",
},
],
},
},
{
preferred: true,
language: {
coding: [
{
system: "urn:ietf:bcp:47",
BobanL marked this conversation as resolved.
Show resolved Hide resolved
code: "en",
display: "English",
},
],
},
},
{
preferred: true,
language: {
coding: [
{
system: "urn:ietf:bcp:47",
code: "hi",
display: "Hindi",
},
],
},
},
],
},
},
],
};

const actual = evaluatePatientLanguage(
patient as unknown as Bundle,
mappings,
);

expect(actual).toEqual("English\n\nHindi");
});
it("Should display language when there are no preferred languages", () => {
const patient = {
resourceType: "Bundle",
entry: [
{
resource: {
resourceType: "Patient",
communication: [
{
language: {
coding: [
{
system: "urn:ietf:bcp:47",
code: "es",
display: "Spanish",
},
],
},
},
{
language: {
coding: [
{
system: "urn:ietf:bcp:47",
code: "en",
display: "English",
},
],
},
},
],
},
},
],
};

const actual = evaluatePatientLanguage(
patient as unknown as Bundle,
mappings,
);

expect(actual).toEqual("Spanish\n\nEnglish");
});
});
2 changes: 1 addition & 1 deletion containers/fhir-converter/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build

# Download FHIR-Converter
RUN git clone https://github.com/skylight-hq/FHIR-Converter.git --branch v7.0-skylight-19 --single-branch /build/FHIR-Converter
RUN git clone https://github.com/skylight-hq/FHIR-Converter.git --branch v7.0-skylight-20 --single-branch /build/FHIR-Converter

WORKDIR /build/FHIR-Converter

Expand Down
1 change: 1 addition & 0 deletions containers/fhir-converter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ Both repos should be checked out and set up per the instructions above. We use r
#### Tips & Tricks

* To run the service tests, use the command `python -m pytest` (make sure the correct environment is activated).
* To update snapshots run `python -m pytest --snapshot-update`
* Make sure your docker image has pulled in the latest changes by building with no cache `make build-image-no-cache`.
* To run the tool tests, run the commands found in the github actions workflow.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,21 @@
'birthDate': '2005-05-01',
'communication': list([
dict({
'extension': list([
dict({
'extension': list([
dict({
'url': str,
'valueCoding': dict({
'code': 'ESP',
'display': 'Expressed spoken',
'system': 'http://terminology.hl7.org/CodeSystem/v3-LanguageAbilityMode',
}),
}),
]),
'url': str,
}),
]),
'language': dict({
'coding': list([
dict({
Expand Down Expand Up @@ -2494,6 +2509,21 @@
'birthDate': '1977-03-25',
'communication': list([
dict({
'extension': list([
dict({
'extension': list([
dict({
'url': str,
'valueCoding': dict({
'code': 'EWR',
'display': 'Expressed written',
'system': 'http://terminology.hl7.org/CodeSystem/v3-LanguageAbilityMode',
}),
}),
]),
'url': str,
}),
]),
'language': dict({
'coding': list([
dict({
Expand Down
Loading