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

add eicr author details #2623

Merged
merged 21 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0638875
add org to device
BobanL Sep 23, 2024
0a47e6f
Remove incorrect device author
BobanL Sep 23, 2024
aa3a228
Remove organization information in practitioner
BobanL Sep 24, 2024
d943c9f
assign practitioner role as author
BobanL Sep 24, 2024
30aad1b
update data
BobanL Sep 24, 2024
ddea6e0
Merge branch 'main' into boban/2511-eICR-author-details
BobanL Sep 25, 2024
c2c4ddd
update data
BobanL Sep 25, 2024
481e7a5
add new function for evaluatePractitionerRoleReference
BobanL Sep 25, 2024
fad7ba0
Add ecr author details to ecr metadata
BobanL Sep 25, 2024
5914748
add ecr author details to AccordionContent.tsx and EcrMetadata.tsx
BobanL Sep 25, 2024
c3ab71e
add eicr author details to content length
BobanL Sep 25, 2024
b6b2c54
Merge branch 'main' into boban/2511-eICR-author-details
BobanL Sep 30, 2024
16ea0b4
update snapshot
BobanL Sep 30, 2024
815a30f
Merge branch 'main' into boban/2511-eICR-author-details
BobanL Sep 30, 2024
ee8c085
Merge branch 'main' into boban/2511-eICR-author-details
BobanL Oct 2, 2024
83cb3bb
Merge branch 'main' into boban/2511-eICR-author-details
BobanL Oct 3, 2024
d6c8a27
Merge branch 'main' into boban/2511-eICR-author-details
BobanL Oct 7, 2024
b54c95b
Handle multiple authors in the ecr metadata service
BobanL Oct 8, 2024
f2f6f20
Change the parameter to accept Array of data display for eicr author …
BobanL Oct 8, 2024
864b460
Add eicr author details as its own section in unavailable information
BobanL Oct 8, 2024
3932944
fix missing key in the eicr author details section
BobanL Oct 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions containers/ecr-viewer/src/app/api/fhirPath.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ patientAlcoholUse: "Bundle.entry.resource.where(resourceType='Observation').wher
patientSexualOrientation: "Bundle.entry.resource.where(resourceType='Observation').where(code.coding.code='76690-7').valueString"
patientGenderIdentity: "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url='http: //hl7.org/fhir/us/ecr/StructureDefinition/us-ph-genderidentity-extension').extension.value.coding.display"

#eCR Metadata
eicrIdentifier: "Bundle.entry.resource.where(resourceType= 'Composition').id"
eicrReleaseVersion: "Bundle.entry.resource.where(resourceType='Composition').extension.where(url='https://www.hl7.org/implement/standards/product_brief.cfm?product_id=436').valueString"
eicrCustodianRef: "Bundle.entry.resource.where(resourceType= 'Composition').custodian.reference"
Expand All @@ -41,6 +42,7 @@ ehrSoftware: "Bundle.entry.resource.where(resourceType = 'Device').where(propert
ehrManufacturerModel: "Bundle.entry.resource.where(resourceType = 'Device').where(property[0].type.coding.code='software').manufacturer"
senderFacilityName: "Bundle.entry.resource.where(resourceType = 'Encounter')[0].location[0].location.display"
eRSDwarnings: "Bundle.entry.resource.where(resourceType= 'Composition').section.where(title = 'Reportability Response Information Section').extension.where(url = 'http://hl7.org/fhir/us/ecr/StructureDefinition/rr-eicr-processing-status-extension').valueCodeableConcept.coding.entries.eRSDwarnings"
compositionAuthorRefs: "Bundle.entry.resource.where(resourceType = 'Composition').author"

# Encounter Info
encounterEndDate: "Bundle.entry.resource.where(resourceType = 'Encounter').period.end"
Expand Down
126 changes: 123 additions & 3 deletions containers/ecr-viewer/src/app/services/ecrMetadataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ import {
formatAddress,
formatContactPoint,
formatDateTime,
formatName,
} from "@/app/services/formatService";
import { PathMappings, evaluateData } from "@/app/view-data/utils/utils";
import { Bundle, Organization } from "fhir/r4";
import {
CompleteData,
evaluateData,
PathMappings,
} from "@/app/view-data/utils/utils";
import { Bundle, Organization, Reference } from "fhir/r4";
import { evaluate } from "@/app/view-data/utils/evaluate";
import { evaluatePractitionerRoleReference } from "./evaluateFhirDataService";
import { DisplayDataProps } from "@/app/view-data/components/DataDisplay";
import { evaluateReference } from "@/app/services/evaluateFhirDataService";

Expand All @@ -15,6 +21,14 @@ export interface ReportableConditions {
};
}

interface EcrMetadata {
eicrDetails: CompleteData;
ecrCustodianDetails: CompleteData;
rrDetails: ReportableConditions;
eicrAuthorDetails: CompleteData[];
eRSDWarnings: ERSDWarning[];
}

export interface ERSDWarning {
warning: string;
versionUsed: string;
Expand All @@ -31,7 +45,7 @@ export interface ERSDWarning {
export const evaluateEcrMetadata = (
fhirBundle: Bundle,
mappings: PathMappings,
) => {
): EcrMetadata => {
const rrDetails = evaluate(fhirBundle, mappings.rrDetails);

let reportableConditionsList: ReportableConditions = {};
Expand Down Expand Up @@ -159,10 +173,116 @@ export const evaluateEcrMetadata = (
},
];

const eicrAuthorDetails = evaluateEcrAuthorDetails(fhirBundle, mappings);

return {
eicrDetails: evaluateData(eicrDetails),
ecrCustodianDetails: evaluateData(ecrCustodianDetails),
rrDetails: reportableConditionsList,
eRSDWarnings: eRSDTextList,
eicrAuthorDetails: eicrAuthorDetails.map((details) =>
evaluateData(details),
),
};
};

const evaluateEcrAuthorDetails = (
fhirBundle: Bundle,
mappings: PathMappings,
): DisplayDataProps[][] => {
const authorRefs: Reference[] = evaluate(
fhirBundle,
mappings["compositionAuthorRefs"],
);

const authorDetails: DisplayDataProps[][] = [];
authorRefs.forEach((ref) => {
if (ref.reference?.includes("PractitionerRole/")) {
const practitionerRoleRef = ref?.reference;
const { practitioner, organization } = evaluatePractitionerRoleReference(
fhirBundle,
mappings,
practitionerRoleRef ?? "",
);

authorDetails.push([
{
title: "Author Name",
value: formatName(
practitioner?.name?.[0].given,
practitioner?.name?.[0].family,
practitioner?.name?.[0].prefix,
practitioner?.name?.[0].suffix,
),
},
{
title: "Author Address",
value: practitioner?.address?.map((address) =>
formatAddress(
address.line ?? [],
address.city ?? "",
address.state ?? "",
address.postalCode ?? "",
address.country ?? "",
),
),
},
{
title: "Author Contact",
value: formatContactPoint(practitioner?.telecom).join("\n"),
},
{
title: "Author Facility Name",
value: organization?.name,
},
{
title: "Author Facility Address",
value: organization?.address?.map((address) =>
formatAddress(
address.line ?? [],
address.city ?? "",
address.state ?? "",
address.postalCode ?? "",
address.country ?? "",
),
),
},
{
title: "Author Facility Contact",
value: formatContactPoint(organization?.telecom).join("\n"),
},
]);
}
});

if (authorDetails.length === 0) {
authorDetails.push([
{
title: "Author Name",
value: null,
},
{
title: "Author Address",
value: null,
},
{
title: "Author Contact",
value: null,
},
{
title: "Author Facility Name",
value: null,
},
{
title: "Author Facility Address",
value: null,
},
{
title: "Author Facility Contact",
value: null,
},
]);
}

return authorDetails;
};
42 changes: 31 additions & 11 deletions containers/ecr-viewer/src/app/services/evaluateFhirDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,21 +442,11 @@ export const evaluateProviderData = (
encounter,
mappings["encounterIndividualRef"],
)[0];
const practitionerRole: PractitionerRole | undefined = evaluateReference(
const { practitioner, organization } = evaluatePractitionerRoleReference(
fhirBundle,
mappings,
encounterParticipantRef ?? "",
);
const practitioner: Practitioner | undefined = evaluateReference(
fhirBundle,
mappings,
practitionerRole?.practitioner?.reference ?? "",
);
const organization: Organization | undefined = evaluateReference(
fhirBundle,
mappings,
practitionerRole?.organization?.reference ?? "",
);

const providerData = [
{
Expand Down Expand Up @@ -644,3 +634,33 @@ export const evaluateFacilityId = (

return location?.identifier?.[0].value;
};

/**
* Evaluate practitioner role reference
* @param fhirBundle - The FHIR bundle containing resources.
* @param mappings - Path mappings for resolving references.
* @param practitionerRoleRef - practitioner role reference to be searched.
* @returns practitioner and organization
*/
export const evaluatePractitionerRoleReference = (
fhirBundle: Bundle,
mappings: PathMappings,
practitionerRoleRef: string,
): { practitioner?: Practitioner; organization?: Organization } => {
const practitionerRole: PractitionerRole | undefined = evaluateReference(
fhirBundle,
mappings,
practitionerRoleRef,
);
const practitioner: Practitioner | undefined = evaluateReference(
fhirBundle,
mappings,
practitionerRole?.practitioner?.reference ?? "",
);
const organization: Organization | undefined = evaluateReference(
fhirBundle,
mappings,
practitionerRole?.organization?.reference ?? "",
);
return { practitioner, organization };
};
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@
},
"author": [
{
"reference": "Practitioner/550b9626-bc9e-7d6b-c5d8-e41c2000ab85"
"reference": "PractitionerRole/b18c20c1-123b-fd12-71cf-9dd0abae8ced"
},
{
"reference": "Device/a57ef88d-1c60-d952-e7ca-5e9e16c7ef05"
Expand All @@ -467,6 +467,93 @@
"url": "Composition/1.2.840.114350.1.13.478.3.7.8.688883.230886"
}
},
{
"resource": {
"resourceType": "PractitionerRole",
"id": "b18c20c1-123b-fd12-71cf-9dd0abae8ced",
"organization": {
"reference": "Organization/d319a926-0eb3-5847-3b21-db8b778b4f07"
},
"practitioner": {
"reference": "Practitioner/550b9626-bc9e-7d6b-c5d8-e41c2000ab85"
},
"meta": {
"source": "ecr"
}
}
},
{
"fullUrl": "urn:uuid:d319a926-0eb3-5847-3b21-db8b778b4f07",
"resource": {
"resourceType": "Organization",
"id": "d319a926-0eb3-5847-3b21-db8b778b4f07",
"identifier": [
{
"system": "urn:oid:1.2.840.114350.1.13.478.2.7.5.737384.61",
"value": "1104202761"
}
],
"name": "Vanderbilt University Medical Center",
"address": [
{
"use": "work",
"line": [
"3401 West End Ave"
],
"city": "NASHVILLE",
"state": "TN",
"country": "USA",
"postalCode": "37203",
"district": "DAVIDSON"
}
],
"telecom": [
{
"system": "phone",
"value": "+1-615-322-5000",
"use": "work"
}
],
"meta": {
"source": "ecr"
}
},
"request": {
"method": "PUT",
"url": "Organization/d319a926-0eb3-5847-3b21-db8b778b4f07"
}
},
{
"fullUrl": "urn:uuid:550b9626-bc9e-7d6b-c5d8-e41c2000ab85",
"resource": {
"resourceType": "Practitioner",
"id": "550b9626-bc9e-7d6b-c5d8-e41c2000ab85",
"meta": {
"profile": [
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner"
],
"source": "ecr"
},
"identifier": [
{
"system": "urn:oid:1.2.840.114350.1.13.478.3.7.2.697780",
"value": "EDILABIH"
}
],
"name": [
{
"family": "Interface",
"given": [
"Lab"
]
}
]
},
"request": {
"method": "PUT",
"url": "Practitioner/550b9626-bc9e-7d6b-c5d8-e41c2000ab85"
}
},
{
"fullUrl": "urn:uuid:a57ef88d-1c60-d952-e7ca-5e9e16c7ef05",
"resource": {
Expand Down
Loading
Loading