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

Extract Fields From FHIR Bundle #982

Merged
merged 100 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
ec8c33e
added method skeleton to extract fields
jorg3lopez Mar 27, 2024
e3faffd
all tests pass
jorg3lopez Mar 27, 2024
d07b9d4
fields added to ResultMock, tests are passing
jorg3lopez Mar 27, 2024
81baff3
Added fields to OrderMock, tests are passing
jorg3lopez Mar 27, 2024
369ee9f
Merge branch 'main' into story/621/extract-ids
jorg3lopez Mar 27, 2024
927c0bf
unit tests skeleton, ready for TDD
jorg3lopez Mar 27, 2024
5354a15
getSendingApplicationId
jorg3lopez Mar 28, 2024
a4a60cc
getSendingApplicationId final
jorg3lopez Mar 28, 2024
869d7ef
getSendingFacilityId
jorg3lopez Mar 28, 2024
79d4ad8
Add Place Order Number to HapiResult
saquino0827 Mar 28, 2024
757374e
Merge branch 'story/621/extract-ids' of https://github.com/CDCgov/tru…
saquino0827 Mar 28, 2024
d37b363
Add SendingApplicationId to HapiResult
saquino0827 Mar 28, 2024
6547849
Merge branch 'main' into story/621/extract-ids
jorg3lopez Mar 29, 2024
aae14a4
getReceivingApplicationId
jorg3lopez Mar 29, 2024
3b1d269
getReceivingApplicationId -> getReceivingApplicationDetails
jorg3lopez Mar 29, 2024
2519d4d
getSendingApplicationid -> getSendingApplicationDetails
jorg3lopez Mar 29, 2024
f848e30
receivingApplicationDetails full extraction
jorg3lopez Mar 29, 2024
46b2ddb
Added OrderNumber extract
jherrflexion Mar 29, 2024
7d1aee8
Added missing import
jherrflexion Mar 29, 2024
f6fc76c
messageDetails pojo
jorg3lopez Mar 31, 2024
9b8e7c8
javadocs for pojo
jorg3lopez Apr 1, 2024
7b15ad1
getStringFromFhirPath()
jorg3lopez Apr 1, 2024
8f2fc51
unit test: getStringFromFhirPath returns correct string value
jorg3lopez Apr 1, 2024
3ce9f67
unit test: getStringFromFhirPath() returns empty string
jorg3lopez Apr 1, 2024
71f29d8
unit test: getStringFromFhirPath() handles complex paths correctly
jorg3lopez Apr 1, 2024
6f70726
use .evaluateFirst() instead of .evaluate()
jorg3lopez Apr 1, 2024
3e7de2a
MessageDetails -> MessageHdDataType
jorg3lopez Apr 1, 2024
ee86133
external link to javadocs
jorg3lopez Apr 1, 2024
b30ba33
refactor javdocs
jorg3lopez Apr 1, 2024
27f8870
Merge branch 'main' into story/621/extract-ids
jorg3lopez Apr 2, 2024
f2af5b3
javadocs for getStringFromFhirPath
jorg3lopez Apr 2, 2024
391f3e7
Base.class instead of StringType.class
jorg3lopez Apr 2, 2024
7665230
Extract IDs Metadata Extract Refactoring (#999)
jorg3lopez Apr 2, 2024
73126b8
added setup() to HapiOrderTest
jorg3lopez Apr 2, 2024
b70223c
Update Order and Result data extraction
saquino0827 Apr 2, 2024
39f8f8a
Update HapiOrder to use HapiMessageHelper
saquino0827 Apr 2, 2024
3d7bc3e
Fix usage of HapiMessageHelper class in HapiOrder/HapiResult
saquino0827 Apr 2, 2024
caa7310
Change Order/Result mocks with their respective correct field names
saquino0827 Apr 2, 2024
9cdd994
Update HapiOrderTest and HapiMessageHelper handling for getSendingApp…
saquino0827 Apr 2, 2024
721c7a3
created skeletons for methods that extract values
jorg3lopez Apr 2, 2024
519ab20
merged conflicts
jorg3lopez Apr 2, 2024
815e566
add extraction logic to methods
jorg3lopez Apr 2, 2024
080c19b
fixed some failing tests and refactored
jorg3lopez Apr 3, 2024
68f0186
fixed HapiOrderConverterTests that were failing
jorg3lopez Apr 3, 2024
3c36fe3
fixed failing tests from OrderControllerTest
jorg3lopez Apr 3, 2024
363318d
All tests work except for the ones using .resolve()
jorg3lopez Apr 3, 2024
44c4f4c
extractSendingFacilityDetails() uses fhir bundle object, all current …
jorg3lopez Apr 3, 2024
727adac
all tests pass
jorg3lopez Apr 3, 2024
23deba3
Tweaked HapiResult to match HapiOrder changes
luis-pabon-tf Apr 3, 2024
c6c9fea
Update HapiResult and HapiResult
saquino0827 Apr 3, 2024
f9ca6c4
Merge branch 'story/621/extract-ids' of https://github.com/CDCgov/tru…
saquino0827 Apr 3, 2024
cc8866b
Refactor work for HapiMessageHelper, Order and Result
saquino0827 Apr 3, 2024
76f8a89
Update unit tests for HapiOrder
saquino0827 Apr 3, 2024
f593f19
fixed ResultMock
jorg3lopez Apr 3, 2024
f1fd06c
no toString() in pojo
jorg3lopez Apr 3, 2024
9fe816a
fixed MessageHDDataTypeTest
jorg3lopez Apr 3, 2024
e7da577
fixed ResultControllerTest failing tests
jorg3lopez Apr 3, 2024
d91f590
fixed HapiReslutConverterTest failing tests
jorg3lopez Apr 3, 2024
0266d2b
pojo -> record
jorg3lopez Apr 3, 2024
b1919c4
edit javadoc for pojo
jorg3lopez Apr 4, 2024
d969453
Update HapiResult unit tests
saquino0827 Apr 4, 2024
84ce7e7
Merge branch 'story/621/extract-ids' of https://github.com/CDCgov/tru…
saquino0827 Apr 4, 2024
3119aa1
Create Message.java
luis-pabon-tf Apr 4, 2024
27f8f78
Make Order and Result extend Message
luis-pabon-tf Apr 4, 2024
0832e42
Fixed missing rename
luis-pabon-tf Apr 4, 2024
a4992b2
unit test: receivingFacilityDetails happy path
jorg3lopez Apr 4, 2024
9c59827
unit test: getReceivingFacilityDetails unhappy path
jorg3lopez Apr 4, 2024
6f48e59
skeleton for HapiMessageHelperTest
jorg3lopez Apr 4, 2024
ea8134f
remove spaces from text blocks
jorg3lopez Apr 4, 2024
7c65c82
Extract Fhir paths to new FhirPath enum in a new plugin directory
saquino0827 Apr 4, 2024
30932c4
Merge branch 'story/621/extract-ids' of https://github.com/CDCgov/tru…
saquino0827 Apr 4, 2024
71b93a0
Fix HapiFhir injection for HapiMessageHelper
saquino0827 Apr 4, 2024
8390285
deleted redundant test: HapiMessageHelperTest
jorg3lopez Apr 4, 2024
46595fa
clear white spaces from long fhir paths
jorg3lopez Apr 5, 2024
b75f4dd
clear white spaces from short fhir paths
jorg3lopez Apr 5, 2024
ed83d18
refactor: HapiOrderTest
jorg3lopez Apr 5, 2024
c0ffbf6
add helper methods to HapiResultTest
jorg3lopez Apr 5, 2024
8018bc6
refactor: HapiResultTest-unhappy path cases
jorg3lopez Apr 5, 2024
f6fb1b5
refactor: HapiResultTest-getSendingApplicationDetails
jorg3lopez Apr 5, 2024
50fd379
refactor: HapiResultTest-getSendingFacilityDetails
jorg3lopez Apr 5, 2024
e12b1bf
refactor: HapiResultTest-getReceivingApplicationDetails
jorg3lopez Apr 5, 2024
c3d4be7
refactor: HapiResultTest-getReceivingFacilityDetails
jorg3lopez Apr 5, 2024
29e90e7
refactor: Order.java and Result.java :: javadocs
jorg3lopez Apr 5, 2024
229914a
javadocs: Message.java
jorg3lopez Apr 5, 2024
0dc7e1b
javadocs: HapiMessageHelper.java
jorg3lopez Apr 5, 2024
b6cb0c8
refactor: HapiOrder
jorg3lopez Apr 5, 2024
112b9a0
refactor: HapiResult
jorg3lopez Apr 5, 2024
b26b96e
javadocs: FhirPath.java
jorg3lopez Apr 5, 2024
c77cc29
unit tests for extractMessageHdDataType
jorg3lopez Apr 5, 2024
48bc904
Merge branch 'main' into story/621/extract-ids
jorg3lopez Apr 5, 2024
ab61789
fixed HapiResultTest
jorg3lopez Apr 5, 2024
709f014
renamed helper methods to include result in HapiResultTest
jorg3lopez Apr 5, 2024
7a39a9f
Message interface now extends FhirResource
luis-pabon-tf Apr 5, 2024
38735e0
Moved getFhirResourceId to FhirResource interface
luis-pabon-tf Apr 5, 2024
0134326
remove wildcard import
jorg3lopez Apr 5, 2024
06a2ac5
aded: as reference to test case
jorg3lopez Apr 5, 2024
1a9835d
Add common parent for hapiOrder and hapiResult
luis-pabon-tf Apr 5, 2024
6e8f9c5
Extending Demographics interface with FhirResource
luis-pabon-tf Apr 5, 2024
cd0b882
HapiDemographics is another implementation of the same FhirResource l…
luis-pabon-tf Apr 5, 2024
5e6f039
Move getPatientId up the chain
luis-pabon-tf Apr 5, 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
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,14 @@ public interface Order<T> {
String getFhirResourceId();

String getPatientId();

String getPlacerOrderNumber();

String getSendingApplicationDetails();
jorg3lopez marked this conversation as resolved.
Show resolved Hide resolved

String getSendingFacilityDetails();

String getReceivingApplicationDetails();

String getReceivingFacilityId();
basiliskus marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,14 @@ public interface Result<T> {
T getUnderlyingResult();

String getFhirResourceId();

String getPlacerOrderNumber();

String getSendingApplicationId();

String getSendingFacilityId();

String getReceivingApplicationId();

String getReceivingFacilityId();
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package gov.hhs.cdc.trustedintermediary.external.hapi;

import gov.hhs.cdc.trustedintermediary.etor.orders.Order;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.MessageHeader;
import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.StringType;

/**
* A concrete implementation of a {@link Order} that uses the Hapi FHIR bundle as its underlying
Expand Down Expand Up @@ -42,4 +50,170 @@ public String getPatientId() {
.findFirst()
.orElse("");
}

@Override
public String getPlacerOrderNumber() {
return null;
}

@Override
public String getSendingApplicationDetails() {
return HapiHelper.resourcesInBundle(innerOrder, MessageHeader.class)
.filter(Objects::nonNull)
.findFirst()
.map(
messageHeader -> {
String namespaceId = null;
String universalId = null;
String universalIdType = null;
String endpoint = messageHeader.getSource().getEndpoint();

for (Extension extension : messageHeader.getSource().getExtension()) {
if ("https://reportstream.cdc.gov/fhir/StructureDefinition/namespace-id"
.equals(extension.getUrl())) {
namespaceId =
Objects.toString(
extension.getValue().primitiveValue(), "");
} else if ("https://reportstream.cdc.gov/fhir/StructureDefinition/universal-id"
.equals(extension.getUrl())) {
universalId =
Objects.toString(
extension.getValue().primitiveValue(), "");
} else if ("https://reportstream.cdc.gov/fhir/StructureDefinition/universal-id-type"
.equals(extension.getUrl())) {
universalIdType =
Objects.toString(
extension.getValue().primitiveValue(), "");
}
}

return concatenateWithCaret(
namespaceId, universalId, universalIdType, endpoint);
jorg3lopez marked this conversation as resolved.
Show resolved Hide resolved
})
.orElse("");
}

@Override
public String getSendingFacilityDetails() {
String organizationReference =
HapiHelper.resourcesInBundle(innerOrder, MessageHeader.class)
.map(MessageHeader::getSender)
.filter(Objects::nonNull)
.map(Reference::getReference)
.filter(Objects::nonNull)
.findFirst()
.orElse(null);

if (organizationReference == null || organizationReference.isEmpty()) {
return "";
}

// Extract from Organization/{id}
String orgId =
organizationReference.contains("/")
? organizationReference.split("/")[1]
: organizationReference;

return HapiHelper.resourcesInBundle(innerOrder, Organization.class)
.filter(org -> orgId.equals(org.getIdElement().getIdPart()))
.findFirst()
.map(
org -> {
String facilityName = "", identifierValue = "", typeCode = "";

for (Identifier identifier : org.getIdentifier()) {
String extensionValue =
identifier.getExtension().stream()
.filter(
ext ->
"https://reportstream.cdc.gov/fhir/StructureDefinition/hl7v2Field"
.equals(ext.getUrl()))
.findFirst()
.map(
ext ->
((StringType) ext.getValue())
.getValue())
.orElse("");

// HD.1: namespace id
if ("HD.1".equals(extensionValue)) {
facilityName = identifier.getValue();
} else if ("HD.2,HD.3".equals(extensionValue)) {
identifierValue = identifier.getValue();
// HD.2: universal Id, HD.3: universal id type
typeCode =
identifier.getType() != null
&& !identifier
.getType()
.getCoding()
.isEmpty()
? identifier
.getType()
.getCoding()
.get(0)
.getCode()
: "";
}
}

return concatenateWithCaret(facilityName, identifierValue, typeCode);
})
.orElse("");
}

@Override
public String getReceivingApplicationDetails() {
return HapiHelper.resourcesInBundle(innerOrder, MessageHeader.class)
.filter(Objects::nonNull)
.findFirst()
.flatMap(
messageHeader ->
messageHeader.getDestination().stream()
.filter(Objects::nonNull)
.findFirst())
.map(
destination -> {
String name = Objects.toString(destination.getName(), "");
String universalId =
destination.getExtension().stream()
.filter(
ext ->
"https://reportstream.cdc.gov/fhir/StructureDefinition/universal-id"
.equals(ext.getUrl()))
.findFirst()
.map(
ext ->
Objects.toString(
ext.getValue().primitiveValue(),
""))
.orElse("");
String universalIdType =
destination.getExtension().stream()
.filter(
ext ->
"https://reportstream.cdc.gov/fhir/StructureDefinition/universal-id-type"
.equals(ext.getUrl()))
.findFirst()
.map(
ext ->
Objects.toString(
ext.getValue().primitiveValue(),
""))
.orElse("");

return concatenateWithCaret(name, universalId, universalIdType);
})
.orElse("");
}

@Override
public String getReceivingFacilityId() {
return null;
}

private String concatenateWithCaret(String... values) {
return Arrays.stream(values)
.filter(Objects::nonNull) // Ensure null values are ignored
.collect(Collectors.joining("^"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import gov.hhs.cdc.trustedintermediary.etor.results.Result;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.MessageHeader;
import org.hl7.fhir.r4.model.ServiceRequest;

/** Filler concrete implementation of a {@link Result} using the Hapi FHIR library */
public class HapiResult implements Result<Bundle> {
Expand All @@ -21,4 +24,48 @@ public Bundle getUnderlyingResult() {
public String getFhirResourceId() {
return innerResult.getId();
}

@Override
public String getPlacerOrderNumber() {
return HapiHelper.resourcesInBundle(innerResult, ServiceRequest.class)
.flatMap(serviceRequest -> serviceRequest.getIdentifier().stream())
.filter(
identifier ->
identifier
.getType()
.hasCoding(
"http://terminology.hl7.org/CodeSystem/v2-0203",
"PLAC"))
.map(Identifier::getValue)
.findFirst()
.orElse("");
}

@Override
public String getSendingApplicationId() {
return HapiHelper.resourcesInBundle(innerResult, MessageHeader.class)
.flatMap(header -> header.getSource().getExtension().stream())
.filter(
extension ->
"https://reportstream.cdc.gov/fhir/StructureDefinition/namespace-id"
.equals(extension.getUrl()))
.map(extension -> extension.getValue().toString())
.findFirst()
.orElse("");
}

@Override
public String getSendingFacilityId() {
return null;
}

@Override
public String getReceivingApplicationId() {
return null;
}

@Override
public String getReceivingFacilityId() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,61 @@ class OrderMock<T> implements Order<T> {
private String fhirResourceId
private String patientId
private T underlyingOrders
private String placerOrderNumber
private String sendingApplicationId
private String sendingFacilityId
private String receivingApplicationId
private String receivingFacilityId

OrderMock(String fhirResourceId, String patientId, T underlyingOrders) {
OrderMock(String fhirResourceId, String patientId, T underlyingOrders, String placerOrderNumber, String sendingApplicationId, String sendingFacilityId,
String receivingApplicationId, String receivingFacilityId) {
this.fhirResourceId = fhirResourceId
this.patientId = patientId
this.underlyingOrders = underlyingOrders
this.placerOrderNumber = placerOrderNumber
this.sendingApplicationId = sendingApplicationId
this.sendingFacilityId = sendingFacilityId
this.receivingApplicationId = receivingApplicationId
this.receivingFacilityId = receivingFacilityId
}

@Override
T getUnderlyingOrder() {
return underlyingOrders
return this.underlyingOrders
}

@Override
String getFhirResourceId() {
return fhirResourceId
return this.fhirResourceId
}

@Override
String getPatientId() {
return patientId
}

@Override
String getPlacerOrderNumber() {
return this.placerOrderNumber
jorg3lopez marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
String getSendingApplicationDetails() {
return this.sendingApplicationId
}

@Override
String getSendingFacilityDetails() {
return this.sendingFacilityId
}

@Override
String getReceivingApplicationDetails() {
return this.receivingApplicationId
}

@Override
String getReceivingFacilityId() {
return this.receivingFacilityId
}
}
Loading
Loading