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

change so that the Observation code is the code for the Questionnare … #265

Merged
merged 4 commits into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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 @@ -9,6 +9,8 @@

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static org.opencds.cqf.common.helpers.ClientHelper.getClient;

Expand All @@ -26,7 +28,7 @@ public Bundle extractObservationFromQuestionnaireResponse(@OperationParam(name =
}
Bundle observationsFromQuestionnaireResponse = createObservationBundle(questionnaireResponse);
Bundle returnBundle = sendObservationBundle(observationsFromQuestionnaireResponse);
return returnBundle;
return observationsFromQuestionnaireResponse;
}

private Bundle createObservationBundle(QuestionnaireResponse questionnaireResponse){
Expand All @@ -37,37 +39,44 @@ private Bundle createObservationBundle(QuestionnaireResponse questionnaireRespon
bundleId.setValue("QuestionnaireResponse/" + questionnaireResponse.getIdElement().getIdPart());
newBundle.setType(Bundle.BundleType.TRANSACTION);
newBundle.setIdentifier(bundleId);
//dstu3 requires the questionnaire to be a reference, like below, instead of just an id like r4
// "questionnaire": {
// "reference":"http://localhost:8080/cqf-ruler-dstu3/fhir/Questionnaire/mypain-questionnaire"
// },
Map questionnaireCodeMap = getQuestionnaireCodeMap(questionnaireResponse.getQuestionnaire().getReference());

questionnaireResponse.getItem().stream().forEach(item ->{
processItems(item, authored, questionnaireResponse, newBundle);
processItems(item, authored, questionnaireResponse, newBundle, questionnaireCodeMap);
});
return newBundle;
}

private void processItems(QuestionnaireResponse.QuestionnaireResponseItemComponent item, Date authored,
QuestionnaireResponse questionnaireResponse, Bundle newBundle){
QuestionnaireResponse questionnaireResponse, Bundle newBundle,
Map questionnaireCodeMap){
if(item.hasAnswer()){
item.getAnswer().forEach(answer ->{
Bundle.BundleEntryComponent newBundleEntryComponent = createObservationFromItemAnswer(answer, item.getLinkId(), authored, questionnaireResponse);
Bundle.BundleEntryComponent newBundleEntryComponent = createObservationFromItemAnswer(answer, item.getLinkId(), authored, questionnaireResponse, questionnaireCodeMap);
if(null != newBundleEntryComponent){
newBundle.addEntry(newBundleEntryComponent);
}
if(answer.hasItem()){
answer.getItem().forEach(answerItem->{
processItems(answerItem, authored, questionnaireResponse, newBundle);
processItems(answerItem, authored, questionnaireResponse, newBundle, questionnaireCodeMap);
});
}
});
}
if(item.hasItem()){
item.getItem().forEach(itemItem ->{
processItems(itemItem, authored, questionnaireResponse, newBundle);
processItems(itemItem, authored, questionnaireResponse, newBundle, questionnaireCodeMap);
});
}
}

private Bundle.BundleEntryComponent createObservationFromItemAnswer(QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent answer,
String linkId, Date authored, QuestionnaireResponse questionnaireResponse){
String linkId, Date authored, QuestionnaireResponse questionnaireResponse,
Map questionnaireCodeMap){
Observation obs = new Observation();
obs.setEffective(new DateTimeType(authored));
obs.setStatus(Observation.ObservationStatus.FINAL);
Expand All @@ -76,11 +85,7 @@ private Bundle.BundleEntryComponent createObservationFromItemAnswer(Questionnair
qrCategoryCoding.setCode("survey");
qrCategoryCoding.setSystem("http://hl7.org/fhir/observation-category");
obs.setCategory(Collections.singletonList(new CodeableConcept().addCoding(qrCategoryCoding)));
Coding qrCoding = new Coding();
qrCoding.setSystem("http://loinc.org");
qrCoding.setCode("74465-6");
qrCoding.setDisplay("Questionnaire response Document");
obs.setCode(new CodeableConcept().addCoding(qrCoding));
obs.setCode(new CodeableConcept().addCoding((Coding) questionnaireCodeMap.get(linkId)));
obs.setId("qr" + questionnaireResponse.getIdElement().getIdPart() + "." + linkId);
switch(answer.getValue().fhirType()){
case "string":
Expand Down Expand Up @@ -130,4 +135,37 @@ private Bundle sendObservationBundle(Bundle observationsBundle) throws IllegalAr
.execute();
return outcomeBundle;
}

private Map getQuestionnaireCodeMap(String questionnaireId){
String url = HapiProperties.getQuestionnaireResponseExtractEndpoint();
if (null == url || url.length() < 1) {
throw new IllegalArgumentException("Unable to transmit observation bundle. No observation.endpoint defined in hapi.properties.");
}
String user = HapiProperties.getQuestionnaireResponseExtractUserName();
String password = HapiProperties.getQuestionnaireResponseExtractPassword();

IGenericClient client = getClient(fhirContext, url, user, password);
Questionnaire questionnaire = client.read().resource(Questionnaire.class).withUrl (questionnaireId).execute();

return createCodeMap(questionnaire);
}

// this is based on "if a questionnaire.item has items then this item is a header and will not have a specific code to be used with an answer"
private Map createCodeMap(Questionnaire questionnaire){
Map <String, Coding>questionnaireCodeMap = new HashMap();
questionnaire.getItem().forEach((item) ->{
processQuestionnaireItems(item, questionnaireCodeMap);
});
return questionnaireCodeMap;
}

private void processQuestionnaireItems(Questionnaire.QuestionnaireItemComponent item, Map questionnaireCodeMap){
if(item.hasItem()){
item.getItem().forEach(qItem -> {
processQuestionnaireItems(qItem, questionnaireCodeMap);
});
}else{
questionnaireCodeMap.put(item.getLinkId(), item.getCodeFirstRep());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static org.opencds.cqf.common.helpers.ClientHelper.getClient;

Expand All @@ -25,8 +27,9 @@ public Bundle extractObservationFromQuestionnaireResponse(@OperationParam(name =
throw new IllegalArgumentException("Unable to perform operation $extract. The QuestionnaireResponse was null");
}
Bundle observationsFromQuestionnaireResponse = createObservationBundle(questionnaireResponse);
Bundle returnBundle = sendObservationBundle(observationsFromQuestionnaireResponse);
return returnBundle;
// Bundle returnBundle = sendObservationBundle(observationsFromQuestionnaireResponse);
return observationsFromQuestionnaireResponse;
// return returnBundle;
}

private Bundle createObservationBundle(QuestionnaireResponse questionnaireResponse){
Expand All @@ -37,37 +40,40 @@ private Bundle createObservationBundle(QuestionnaireResponse questionnaireRespon
bundleId.setValue("QuestionnaireResponse/" + questionnaireResponse.getIdElement().getIdPart());
newBundle.setType(Bundle.BundleType.TRANSACTION);
newBundle.setIdentifier(bundleId);
Map questionnaireCodeMap = getQuestionnaireCodeMap(questionnaireResponse.getQuestionnaire());

questionnaireResponse.getItem().stream().forEach(item ->{
processItems(item, authored, questionnaireResponse, newBundle);
processItems(item, authored, questionnaireResponse, newBundle, questionnaireCodeMap);
});
return newBundle;
}

private void processItems(QuestionnaireResponse.QuestionnaireResponseItemComponent item, Date authored,
QuestionnaireResponse questionnaireResponse, Bundle newBundle){
QuestionnaireResponse questionnaireResponse, Bundle newBundle,
Map questionnaireCodeMap){
if(item.hasAnswer()){
item.getAnswer().forEach(answer ->{
Bundle.BundleEntryComponent newBundleEntryComponent = createObservationFromItemAnswer(answer, item.getLinkId(), authored, questionnaireResponse);
Bundle.BundleEntryComponent newBundleEntryComponent = createObservationFromItemAnswer(answer, item.getLinkId(), authored, questionnaireResponse, questionnaireCodeMap);
if(null != newBundleEntryComponent){
newBundle.addEntry(newBundleEntryComponent);
}
if(answer.hasItem()){
answer.getItem().forEach(answerItem->{
processItems(answerItem, authored, questionnaireResponse, newBundle);
processItems(answerItem, authored, questionnaireResponse, newBundle, questionnaireCodeMap);
});
}
});
}
if(item.hasItem()){
item.getItem().forEach(itemItem ->{
processItems(itemItem, authored, questionnaireResponse, newBundle);
processItems(itemItem, authored, questionnaireResponse, newBundle, questionnaireCodeMap);
});
}
}

private Bundle.BundleEntryComponent createObservationFromItemAnswer(QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent answer,
String linkId, Date authored, QuestionnaireResponse questionnaireResponse){
String linkId, Date authored, QuestionnaireResponse questionnaireResponse,
Map questionnaireCodeMap){
Observation obs = new Observation();
obs.setEffective(new DateTimeType(authored));
obs.setStatus(Observation.ObservationStatus.FINAL);
Expand All @@ -76,11 +82,7 @@ private Bundle.BundleEntryComponent createObservationFromItemAnswer(Questionnair
qrCategoryCoding.setCode("survey");
qrCategoryCoding.setSystem("http://hl7.org/fhir/observation-category");
obs.setCategory(Collections.singletonList(new CodeableConcept().addCoding(qrCategoryCoding)));
Coding qrCoding = new Coding();
qrCoding.setSystem("http://loinc.org");
qrCoding.setCode("74465-6");
qrCoding.setDisplay("Questionnaire response Document");
obs.setCode(new CodeableConcept().addCoding(qrCoding));
obs.setCode(new CodeableConcept().addCoding((Coding) questionnaireCodeMap.get(linkId)));
obs.setId("qr" + questionnaireResponse.getIdElement().getIdPart() + "." + linkId);
switch(answer.getValue().fhirType()){
case "string":
Expand Down Expand Up @@ -127,4 +129,37 @@ private Bundle sendObservationBundle(Bundle observationsBundle) throws IllegalAr
.execute();
return outcomeBundle;
}

private Map getQuestionnaireCodeMap(String questionnaireId){
String url = HapiProperties.getQuestionnaireResponseExtractEndpoint();
if (null == url || url.length() < 1) {
throw new IllegalArgumentException("Unable to transmit observation bundle. No observation.endpoint defined in hapi.properties.");
}
String user = HapiProperties.getQuestionnaireResponseExtractUserName();
String password = HapiProperties.getQuestionnaireResponseExtractPassword();

IGenericClient client = getClient(fhirContext, url, user, password);
Questionnaire questionnaire = client.read().resource(Questionnaire.class).withUrl (url + "/Questionnaire/" + questionnaireId).execute();

return createCodeMap(questionnaire);
}

// this is based on "if a questionnaire.item has items then this item is a header and will not have a specific code to be used with an answer"
private Map createCodeMap(Questionnaire questionnaire){
Map <String, Coding>questionnaireCodeMap = new HashMap();
questionnaire.getItem().forEach((item) ->{
processQuestionnaireItems(item, questionnaireCodeMap);
});
return questionnaireCodeMap;
}

private void processQuestionnaireItems(Questionnaire.QuestionnaireItemComponent item, Map questionnaireCodeMap){
if(item.hasItem()){
item.getItem().forEach(qItem -> {
processQuestionnaireItems(qItem, questionnaireCodeMap);
});
}else{
questionnaireCodeMap.put(item.getLinkId(), item.getCodeFirstRep());
}
}
}