diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml
index 3a7742e2efd..35bdfa907a3 100644
--- a/hapi-fhir-validation/pom.xml
+++ b/hapi-fhir-validation/pom.xml
@@ -9,9 +9,11 @@
../hapi-deployable-pom/pom.xml
+ fi.kela.kanta.phr
+
hapi-fhir-validation
bundle
- 3.6.4-PHRFIX
+ 3.6.5-PHRFIX
HAPI FHIR - Validation
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/DefaultEnableWhenEvaluator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/DefaultEnableWhenEvaluator.java
index 9588fa0373c..06c9f18d792 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/DefaultEnableWhenEvaluator.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/DefaultEnableWhenEvaluator.java
@@ -196,6 +196,7 @@ public class DefaultEnableWhenEvaluator implements IEnableWhenEvaluator {
}
return true;
}
+
private List findSubItems(Element item) {
List results = item.getChildren(ITEM_ELEMENT)
.stream()
@@ -212,7 +213,5 @@ public class DefaultEnableWhenEvaluator implements IEnableWhenEvaluator {
}
return false;
}
-
-
}
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java
index 101da940c23..24c32900f17 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java
@@ -2640,8 +2640,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
element.getNamedChildren("answer", answers);
if (inProgress)
warning(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), isAnswerRequirementFulfilled(qItem, answers), "No response answer found for required item "+qItem.getLinkId());
- else
+ else if(myEnableWhenEvaluator.isQuestionEnabled(qItem, questionnaireResponseRoot))
rule(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), isAnswerRequirementFulfilled(qItem, answers), "No response answer found for required item "+qItem.getLinkId());
+ else if (!answers.isEmpty()) // items without answers should be allowed, but not items with answers to questions that are disabled
+ rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), !isAnswerRequirementFulfilled(qItem, answers), "Item has answer, even though it is not enabled "+qItem.getLinkId());
+
+
if (answers.size() > 1)
rule(errors, IssueType.INVALID, answers.get(1).line(), answers.get(1).col(), stack.getLiteralPath(), qItem.getRepeats(), "Only one response answer item with this linkId allowed");
@@ -2785,8 +2789,8 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
// ok, now we have a list of known items, grouped by linkId. We"ve made an error for anything out of order
for (QuestionnaireItemComponent qItem : qItems) {
List mapItem = map.get(qItem.getLinkId());
- if (mapItem != null){
- rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), myEnableWhenEvaluator.isQuestionEnabled(qItem, questionnaireResponseRoot), "Item has answer, even though it is not enabled "+qItem.getLinkId());
+ if (mapItem != null) {
+ //rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), myEnableWhenEvaluator.isQuestionEnabled(qItem, questionnaireResponseRoot), "Item has answer, even though it is not enabled "+qItem.getLinkId());
validateQuestionannaireResponseItem(qsrc, qItem, errors, mapItem, stack, inProgress, questionnaireResponseRoot);
} else {
//item is missing, is the question enabled?
@@ -2796,6 +2800,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
}
}
}
+
private String misplacedItemError(QuestionnaireItemComponent qItem) {
return qItem.hasLinkId() ?
diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireResponseValidatorDstu3Test.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireResponseValidatorDstu3Test.java
index e1ffa326572..ad36908620d 100644
--- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireResponseValidatorDstu3Test.java
+++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireResponseValidatorDstu3Test.java
@@ -351,23 +351,18 @@ public class QuestionnaireResponseValidatorDstu3Test {
public void testRequiredQuestionWithEnableWhenHidesQuestionHasAnswerTrue() {
Questionnaire q = new Questionnaire();
- q.addItem().setLinkId("link0").setRequired(true).setType(QuestionnaireItemType.STRING);
+ q.addItem().setLinkId("link0").setRequired(false).setType(QuestionnaireItemType.STRING);
// create the questionnaire
QuestionnaireItemComponent item1 = new QuestionnaireItemComponent();
- item1.setLinkId("link1").setRequired(true);
+ item1.setLinkId("link1").setRequired(true).addEnableWhen().setQuestion("link0").setHasAnswer(true);
q.addItem(item1);
- QuestionnaireItemEnableWhenComponent enable = new QuestionnaireItemEnableWhenComponent();
- item1.addEnableWhen(enable);
- enable.setQuestion("link0");
- enable.setHasAnswer(true);
-
-
+
QuestionnaireResponse qa = new QuestionnaireResponse();
qa.setStatus(QuestionnaireResponseStatus.COMPLETED);
qa.getQuestionnaire().setReference(QUESTIONNAIRE_URL);
-
+
String reference = qa.getQuestionnaire().getReference();
when(myValSupport.fetchResource(any(FhirContext.class), eq(Questionnaire.class), eq(reference))).thenReturn(q);
ValidationResult errors = myVal.validateWithResult(qa);
@@ -531,6 +526,50 @@ public class QuestionnaireResponseValidatorDstu3Test {
assertThat(errors.toString(), Matchers.not(containsString("No issues")));
}
+ @Test
+ public void testGivenQuestionIsNotEnabledWithEnableWhenButHasItemsWithoutAnswersAreOk() throws Exception {
+ Questionnaire q = new Questionnaire();
+ q.addItem().setLinkId("link0").setRequired(false).setType(QuestionnaireItemType.STRING);
+ q.addItem().setLinkId("link2").setRequired(false).setType(QuestionnaireItemType.STRING).addEnableWhen().setQuestion("link0").setHasAnswer(true);
+
+ QuestionnaireResponse qr = new QuestionnaireResponse();
+ qr.setStatus(QuestionnaireResponseStatus.COMPLETED);
+ qr.getQuestionnaire().setReference(QUESTIONNAIRE_URL);
+
+ qr.addItem().setLinkId("link2");
+
+ String reference = qr.getQuestionnaire().getReference();
+ when(myValSupport.fetchResource(any(FhirContext.class), eq(Questionnaire.class), eq(reference))).thenReturn(q);
+
+ ValidationResult errors = myVal.validateWithResult(qr);
+
+ assertThat(errors.toString(), containsString("No issues"));
+ }
+
+ @Test
+ public void testGivenQuestionIsNotEnabledWithEnableWhenButHasItemsWithoutAnswersAreOk2() throws Exception {
+ Questionnaire q = new Questionnaire();
+ q.addItem().setLinkId("link0").setRequired(false).setType(QuestionnaireItemType.STRING);
+ q.addItem().setLinkId("link1").setRequired(false).setType(QuestionnaireItemType.STRING);
+ q.addItem().setLinkId("link2").setRequired(true).setType(QuestionnaireItemType.STRING).addEnableWhen().setQuestion("link0").setHasAnswer(true);
+
+ QuestionnaireResponse qr = new QuestionnaireResponse();
+ qr.setStatus(QuestionnaireResponseStatus.COMPLETED);
+ qr.getQuestionnaire().setReference(QUESTIONNAIRE_URL);
+ qr.addItem().setLinkId("link0");
+
+ qr.addItem().setLinkId("link1").addAnswer().setValue(new StringType("Answer"));
+
+ qr.addItem().setLinkId("link2");
+
+ String reference = qr.getQuestionnaire().getReference();
+ when(myValSupport.fetchResource(any(FhirContext.class), eq(Questionnaire.class), eq(reference))).thenReturn(q);
+
+ ValidationResult errors = myVal.validateWithResult(qr);
+
+ assertThat(errors.toString(), containsString("No issues"));
+ }
+
@Test
public void testGivenQuestionnaireResponseHasSiblingItemsWhenTheyShouldBeChildItems() throws Exception {
Questionnaire q = new Questionnaire();