More work on QuestionnaireAnswersValidator
This commit is contained in:
parent
27a1d68d5f
commit
7988cc3993
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -10,9 +12,11 @@ import org.hl7.fhir.instance.model.QuestionnaireAnswers;
|
|||
import org.hl7.fhir.instance.model.ValueSet;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.valuesets.IssueType;
|
||||
import org.hl7.fhir.instance.utils.WorkerContext;
|
||||
import org.hl7.fhir.instance.validation.QuestionnaireAnswersValidator;
|
||||
import org.hl7.fhir.instance.validation.ValidationMessage;
|
||||
import org.hl7.fhir.instance.validation.ValidationMessage.Source;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
|
@ -87,7 +91,9 @@ public class FhirQuestionnaireAnswersValidator extends BaseValidatorBridge {
|
|||
for (ResourceReferenceInfo nextRefInfo : refs) {
|
||||
IIdType nextRef = nextRefInfo.getResourceReference().getReferenceElement();
|
||||
String resourceType = nextRef.getResourceType();
|
||||
if ("ValueSet".equals(resourceType)) {
|
||||
if (isBlank(resourceType)) {
|
||||
theMessages.add(new ValidationMessage(Source.QuestionnaireAnswersValidator, IssueType.INVALID, null, "Invalid reference '" + nextRef.getValue() + "' - Does not identify resource type", IssueSeverity.FATAL));
|
||||
} else if ("ValueSet".equals(resourceType)) {
|
||||
if (!theWorkerCtx.getValueSets().containsKey(nextRef.getValue())) {
|
||||
ValueSet resource = tryToLoad(ValueSet.class, nextRef, theMessages);
|
||||
if (resource == null) {
|
||||
|
|
|
@ -64,7 +64,7 @@ public class BaseValidator {
|
|||
*/
|
||||
protected boolean fail(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String msg) {
|
||||
if (!thePass) {
|
||||
String path = StringUtils.join(pathParts, '.');
|
||||
String path = toPath(pathParts);
|
||||
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.FATAL));
|
||||
}
|
||||
return thePass;
|
||||
|
@ -79,7 +79,7 @@ public class BaseValidator {
|
|||
*/
|
||||
protected boolean fail(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String theMessage, Object... theMessageArguments) {
|
||||
if (!thePass) {
|
||||
String path = StringUtils.join(pathParts, '.');
|
||||
String path = toPath(pathParts);
|
||||
errors.add(new ValidationMessage(source, type, -1, -1, path, formatMessage(theMessage, theMessageArguments), IssueSeverity.FATAL));
|
||||
}
|
||||
return thePass;
|
||||
|
@ -151,7 +151,7 @@ public class BaseValidator {
|
|||
*/
|
||||
protected boolean hint(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String theMessage, Object... theMessageArguments) {
|
||||
if (!thePass) {
|
||||
String path = StringUtils.join(pathParts, '.');
|
||||
String path = toPath(pathParts);
|
||||
String message = formatMessage(theMessage, theMessageArguments);
|
||||
errors.add(new ValidationMessage(source, type, -1, -1, path, message, IssueSeverity.INFORMATION));
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ public class BaseValidator {
|
|||
*/
|
||||
protected boolean rule(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String msg) {
|
||||
if (!thePass) {
|
||||
String path = StringUtils.join(pathParts, '.');
|
||||
String path = toPath(pathParts);
|
||||
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.ERROR));
|
||||
}
|
||||
return thePass;
|
||||
|
@ -196,13 +196,20 @@ public class BaseValidator {
|
|||
*/
|
||||
protected boolean rule(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String theMessage, Object... theMessageArguments) {
|
||||
if (!thePass) {
|
||||
String path = StringUtils.join(pathParts, '.');
|
||||
String path = toPath(pathParts);
|
||||
String message = formatMessage(theMessage, theMessageArguments);
|
||||
errors.add(new ValidationMessage(source, type, -1, -1, path, message, IssueSeverity.ERROR));
|
||||
}
|
||||
return thePass;
|
||||
}
|
||||
|
||||
private String toPath(List<String> pathParts) {
|
||||
if (pathParts == null || pathParts.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return "//" + StringUtils.join(pathParts, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a rule and add a {@link IssueSeverity#ERROR} validation message if the validation fails
|
||||
*
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.Attachment;
|
||||
import org.hl7.fhir.instance.model.BooleanType;
|
||||
|
@ -19,6 +20,7 @@ import org.hl7.fhir.instance.model.DateType;
|
|||
import org.hl7.fhir.instance.model.DecimalType;
|
||||
import org.hl7.fhir.instance.model.InstantType;
|
||||
import org.hl7.fhir.instance.model.IntegerType;
|
||||
import org.hl7.fhir.instance.model.OperationOutcome.IssueSeverity;
|
||||
import org.hl7.fhir.instance.model.Quantity;
|
||||
import org.hl7.fhir.instance.model.Questionnaire;
|
||||
import org.hl7.fhir.instance.model.Questionnaire.AnswerFormat;
|
||||
|
@ -82,11 +84,13 @@ public class QuestionnaireAnswersValidator extends BaseValidator {
|
|||
}
|
||||
|
||||
private List<org.hl7.fhir.instance.model.QuestionnaireAnswers.GroupComponent> findGroupByLinkId(List<org.hl7.fhir.instance.model.QuestionnaireAnswers.GroupComponent> theGroups, String theLinkId) {
|
||||
Validate.notBlank(theLinkId, "theLinkId must not be blank");
|
||||
|
||||
ArrayList<org.hl7.fhir.instance.model.QuestionnaireAnswers.GroupComponent> retVal = new ArrayList<QuestionnaireAnswers.GroupComponent>();
|
||||
for (org.hl7.fhir.instance.model.QuestionnaireAnswers.GroupComponent next : theGroups) {
|
||||
if (theLinkId.equals(next.getLinkId())) {
|
||||
if (theLinkId == null) {
|
||||
if (next.getLinkId() == null) {
|
||||
retVal.add(next);
|
||||
}
|
||||
} else if (theLinkId.equals(next.getLinkId())) {
|
||||
retVal.add(next);
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +108,9 @@ public class QuestionnaireAnswersValidator extends BaseValidator {
|
|||
|
||||
Reference questionnaireRef = theAnswers.getQuestionnaire();
|
||||
Questionnaire questionnaire = getQuestionnaire(theAnswers, questionnaireRef);
|
||||
if (questionnaire == null && theErrors.size() > 0 && theErrors.get(theErrors.size() - 1).getLevel() == IssueSeverity.FATAL) {
|
||||
return;
|
||||
}
|
||||
if (!fail(theErrors, IssueType.INVALID, pathStack, questionnaire != null, "Questionnaire {0} is not found in the WorkerContext", theAnswers.getQuestionnaire().getReference())) {
|
||||
return;
|
||||
}
|
||||
|
@ -115,7 +122,7 @@ public class QuestionnaireAnswersValidator extends BaseValidator {
|
|||
}
|
||||
|
||||
pathStack.removeLast();
|
||||
pathStack.add("group(0)");
|
||||
pathStack.add("group[0]");
|
||||
validateGroup(theErrors, questionnaire.getGroup(), theAnswers.getGroup(), pathStack, theAnswers, validateRequired);
|
||||
}
|
||||
|
||||
|
@ -173,7 +180,7 @@ public class QuestionnaireAnswersValidator extends BaseValidator {
|
|||
// Check that there are no extra answers
|
||||
for (int i = 0; i < theAnsGroup.getQuestion().size(); i++) {
|
||||
org.hl7.fhir.instance.model.QuestionnaireAnswers.QuestionComponent nextQuestion = theAnsGroup.getQuestion().get(i);
|
||||
thePathStack.add("question(" + i + ")");
|
||||
thePathStack.add("question[" + i + "]");
|
||||
rule(theErrors, IssueType.BUSINESSRULE, thePathStack, allowedQuestions.contains(nextQuestion.getLinkId()), "Found answer with linkId[{0}] but this ID is not allowed at this position",
|
||||
nextQuestion.getLinkId());
|
||||
thePathStack.remove();
|
||||
|
@ -214,7 +221,7 @@ public class QuestionnaireAnswersValidator extends BaseValidator {
|
|||
|
||||
org.hl7.fhir.instance.model.QuestionnaireAnswers.QuestionComponent answerQuestion = answers.get(0);
|
||||
try {
|
||||
thePathStack.add("question(" + answers.indexOf(answerQuestion) + ")");
|
||||
thePathStack.add("question[" + answers.indexOf(answerQuestion) + "]");
|
||||
validateQuestionAnswers(theErrors, theQuestion, thePathStack, type, answerQuestion, theAnswers, theValidateRequired);
|
||||
validateQuestionGroups(theErrors, theQuestion, answerQuestion, thePathStack, theAnswers, theValidateRequired);
|
||||
} finally {
|
||||
|
@ -234,6 +241,14 @@ public class QuestionnaireAnswersValidator extends BaseValidator {
|
|||
|
||||
private void validateGroups(List<ValidationMessage> theErrors, List<GroupComponent> theQuestionGroups, List<org.hl7.fhir.instance.model.QuestionnaireAnswers.GroupComponent> theAnswerGroups,
|
||||
LinkedList<String> thePathStack, QuestionnaireAnswers theAnswers, boolean theValidateRequired) {
|
||||
Set<String> linkIds = new HashSet<String>();
|
||||
for (GroupComponent nextQuestionGroup : theQuestionGroups) {
|
||||
String nextLinkId = StringUtils.defaultString(nextQuestionGroup.getLinkId());
|
||||
if (!linkIds.add(nextLinkId)) {
|
||||
rule(theErrors, IssueType.BUSINESSRULE, thePathStack, false, "Questionnaire in invalid, unable to validate QuestionnaireAnswers: Multiple groups found at this position with linkId[{0}]", nextLinkId);
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> allowedGroups = new HashSet<String>();
|
||||
for (GroupComponent nextQuestionGroup : theQuestionGroups) {
|
||||
String linkId = nextQuestionGroup.getLinkId();
|
||||
|
@ -253,14 +268,14 @@ public class QuestionnaireAnswersValidator extends BaseValidator {
|
|||
if (answerGroups.size() > 1) {
|
||||
if (nextQuestionGroup.getRepeats() == false) {
|
||||
int index = theAnswerGroups.indexOf(answerGroups.get(1));
|
||||
thePathStack.add("group(" + index + ")");
|
||||
thePathStack.add("group[" + index + "]");
|
||||
rule(theErrors, IssueType.BUSINESSRULE, thePathStack, false, "Multiple repetitions of group with linkId[{0}] found at this position, but this group can not repeat", linkId);
|
||||
thePathStack.removeLast();
|
||||
}
|
||||
}
|
||||
for (org.hl7.fhir.instance.model.QuestionnaireAnswers.GroupComponent nextAnswerGroup : answerGroups) {
|
||||
int index = theAnswerGroups.indexOf(answerGroups.get(1));
|
||||
thePathStack.add("group(" + index + ")");
|
||||
int index = theAnswerGroups.indexOf(nextAnswerGroup);
|
||||
thePathStack.add("group[" + index + "]");
|
||||
validateGroup(theErrors, nextQuestionGroup, nextAnswerGroup, thePathStack, theAnswers, theValidateRequired);
|
||||
thePathStack.removeLast();
|
||||
}
|
||||
|
@ -271,7 +286,7 @@ public class QuestionnaireAnswersValidator extends BaseValidator {
|
|||
for (org.hl7.fhir.instance.model.QuestionnaireAnswers.GroupComponent next : theAnswerGroups) {
|
||||
idx++;
|
||||
if (!allowedGroups.contains(next.getLinkId())) {
|
||||
thePathStack.add("group(" + idx + ")");
|
||||
thePathStack.add("group[" + idx + "]");
|
||||
rule(theErrors, IssueType.BUSINESSRULE, thePathStack, false, "Group with linkId[{0}] found at this position, but this group does not exist at this position in Questionnaire",
|
||||
next.getLinkId());
|
||||
thePathStack.removeLast();
|
||||
|
@ -300,7 +315,7 @@ public class QuestionnaireAnswersValidator extends BaseValidator {
|
|||
for (QuestionAnswerComponent nextAnswer : answerQuestion.getAnswer()) {
|
||||
answerIdx++;
|
||||
try {
|
||||
thePathStack.add("answer(" + answerIdx + ")");
|
||||
thePathStack.add("answer[" + answerIdx + "]");
|
||||
Type nextValue = nextAnswer.getValue();
|
||||
if (!allowedAnswerTypes.contains(nextValue.getClass())) {
|
||||
rule(theErrors, IssueType.BUSINESSRULE, thePathStack, false, "Answer to question with linkId[{0}] found of type [{1}] but this is invalid for question of type [{2}]", linkId,
|
||||
|
|
|
@ -52,7 +52,8 @@ public class ValidationMessage {
|
|||
Schematron,
|
||||
Publisher,
|
||||
Ontology,
|
||||
ProfileComparer
|
||||
ProfileComparer,
|
||||
QuestionnaireAnswersValidator
|
||||
}
|
||||
//@formatter:on
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
import static org.hamcrest.Matchers.any;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.junit.Assert.*;
|
||||
|
@ -7,6 +8,8 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -20,6 +23,7 @@ import org.hl7.fhir.instance.model.QuestionnaireAnswers;
|
|||
import org.hl7.fhir.instance.model.Reference;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
import org.hl7.fhir.instance.model.ValueSet;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.Questionnaire.AnswerFormat;
|
||||
import org.hl7.fhir.instance.model.QuestionnaireAnswers.QuestionnaireAnswersStatus;
|
||||
import org.hl7.fhir.instance.utils.WorkerContext;
|
||||
|
@ -28,6 +32,8 @@ import org.hl7.fhir.instance.validation.ValidationMessage;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
|
@ -122,7 +128,7 @@ public class QuestionnaireAnswersValidatorIntegrationTest {
|
|||
ourLog.info(result.getMessages().toString());
|
||||
assertThat(result.getMessages().toString(), containsString("Missing answer to required question with linkId[link0],mySeverity=error"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCodedAnswer() {
|
||||
|
@ -153,13 +159,22 @@ public class QuestionnaireAnswersValidatorIntegrationTest {
|
|||
qa.getGroup().addQuestion().setLinkId("link0").addAnswer().setValue(new Coding().setSystem("urn:system").setCode("code1"));
|
||||
result = myVal.validateWithResult(qa);
|
||||
ourLog.info(result.getMessages().toString());
|
||||
assertThat(result.getMessages().toString(), containsString("myLocationString=QuestionnaireAnswers.group(0).question(0).answer(0)"));
|
||||
assertThat(result.getMessages().toString(), containsString("myLocationString=//QuestionnaireAnswers/group[0]/question[0]/answer[0]"));
|
||||
assertThat(result.getMessages().toString(),
|
||||
containsString("myMessage=Question with linkId[link0] has answer with system[urn:system] and code[code1] but this is not a valid answer for ValueSet[http://somevalueset/ValueSet/123]"));
|
||||
|
||||
result.toOperationOutcome();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidReference() {
|
||||
QuestionnaireAnswers qa = new QuestionnaireAnswers();
|
||||
qa.getQuestionnaire().setReference("someReference"); // not relative
|
||||
ValidationResult result = myVal.validateWithResult(qa);
|
||||
assertEquals(result.getMessages().toString(), 1, result.getMessages().size());
|
||||
assertThat(result.getMessages().toString(), containsString("Invalid reference 'someReference"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnknownValueSet() {
|
||||
String questionnaireRef = "http://example.com/Questionnaire/q1";
|
||||
|
@ -181,4 +196,39 @@ public class QuestionnaireAnswersValidatorIntegrationTest {
|
|||
assertThat(result.getMessages().toString(), containsString("myMessage=Reference could not be found: http://some"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample provided by Eric van der Zwan
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testSampleQuestionnaire() {
|
||||
when(myResourceLoaderMock.load(Mockito.any(Class.class), Mockito.any(IdType.class))).thenAnswer(new Answer<IBaseResource>() {
|
||||
@Override
|
||||
public IBaseResource answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
IdType id = (IdType) theInvocation.getArguments()[1];
|
||||
String name = "/nice/" + id.getIdPart() + ".xml";
|
||||
InputStream in = getClass().getResourceAsStream(name);
|
||||
if (in == null) {
|
||||
throw new IllegalArgumentException(name);
|
||||
}
|
||||
InputStreamReader reader = new InputStreamReader(in);
|
||||
String body = IOUtils.toString(reader);
|
||||
|
||||
if (Questionnaire.class.equals(theInvocation.getArguments()[0])) {
|
||||
return ourCtx.newXmlParser().parseResource(Questionnaire.class, body);
|
||||
} else if (ValueSet.class.equals(theInvocation.getArguments()[0])) {
|
||||
return ourCtx.newXmlParser().parseResource(ValueSet.class, body);
|
||||
} else {
|
||||
throw new IllegalArgumentException(id.getValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
QuestionnaireAnswers qa = ourCtx.newXmlParser().parseResource(QuestionnaireAnswers.class, new InputStreamReader(getClass().getResourceAsStream("/nice/answer-1-admission.xml")));
|
||||
|
||||
ValidationResult result = myVal.validateWithResult(qa);
|
||||
ourLog.info(result.getMessages().toString());
|
||||
assertThat(result.getMessages().toString(), containsString("Answer to question with linkId[partialBSN] found of type [IntegerType] but this is invalid for question of type [string]"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.instance.model.Coding;
|
||||
import org.hl7.fhir.instance.model.Questionnaire;
|
||||
import org.hl7.fhir.instance.model.Questionnaire.AnswerFormat;
|
||||
import org.hl7.fhir.instance.model.Questionnaire.GroupComponent;
|
||||
import org.hl7.fhir.instance.model.QuestionnaireAnswers;
|
||||
import org.hl7.fhir.instance.model.QuestionnaireAnswers.QuestionnaireAnswersStatus;
|
||||
import org.hl7.fhir.instance.model.Reference;
|
||||
import org.hl7.fhir.instance.model.StringType;
|
||||
import org.hl7.fhir.instance.model.ValueSet;
|
||||
import org.hl7.fhir.instance.model.Questionnaire.AnswerFormat;
|
||||
import org.hl7.fhir.instance.model.QuestionnaireAnswers.QuestionnaireAnswersStatus;
|
||||
import org.hl7.fhir.instance.utils.WorkerContext;
|
||||
import org.hl7.fhir.instance.validation.QuestionnaireAnswersValidator;
|
||||
import org.hl7.fhir.instance.validation.ValidationMessage;
|
||||
|
@ -55,6 +56,48 @@ public class QuestionnaireAnswersValidatorTest {
|
|||
assertThat(errors.toString(), containsString("Answer to question with linkId[link0] found of type [StringType] but this is invalid for question of type [boolean]"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGroupWithNoLinkIdInQuestionnaireAnswers() {
|
||||
Questionnaire q = new Questionnaire();
|
||||
GroupComponent qGroup = q.getGroup().addGroup();
|
||||
qGroup.addQuestion().setLinkId("link0").setRequired(true).setType(AnswerFormat.BOOLEAN);
|
||||
|
||||
QuestionnaireAnswers qa = new QuestionnaireAnswers();
|
||||
qa.getQuestionnaire().setReference("http://example.com/Questionnaire/q1");
|
||||
org.hl7.fhir.instance.model.QuestionnaireAnswers.GroupComponent qaGroup = qa.getGroup().addGroup();
|
||||
qaGroup.addQuestion().setLinkId("link0").addAnswer().setValue(new StringType("FOO"));
|
||||
|
||||
myWorkerCtx.getQuestionnaires().put(qa.getQuestionnaire().getReference(), q);
|
||||
List<ValidationMessage> errors = new ArrayList<ValidationMessage>();
|
||||
myVal.validate(errors, qa);
|
||||
|
||||
ourLog.info(errors.toString());
|
||||
assertThat(errors.toString(), containsString("Answer to question with linkId[link0] found of type [StringType] but this is invalid for question of type [boolean]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleGroupsWithNoLinkIdInQuestionnaireAnswers() {
|
||||
Questionnaire q = new Questionnaire();
|
||||
GroupComponent qGroup = q.getGroup().addGroup();
|
||||
qGroup.addQuestion().setLinkId("link0").setRequired(true).setType(AnswerFormat.BOOLEAN);
|
||||
GroupComponent qGroup2 = q.getGroup().addGroup();
|
||||
qGroup2.addQuestion().setLinkId("link1").setRequired(true).setType(AnswerFormat.BOOLEAN);
|
||||
|
||||
QuestionnaireAnswers qa = new QuestionnaireAnswers();
|
||||
qa.getQuestionnaire().setReference("http://example.com/Questionnaire/q1");
|
||||
org.hl7.fhir.instance.model.QuestionnaireAnswers.GroupComponent qaGroup = qa.getGroup().addGroup();
|
||||
qaGroup.addQuestion().setLinkId("link0").addAnswer().setValue(new StringType("FOO"));
|
||||
|
||||
myWorkerCtx.getQuestionnaires().put(qa.getQuestionnaire().getReference(), q);
|
||||
List<ValidationMessage> errors = new ArrayList<ValidationMessage>();
|
||||
myVal.validate(errors, qa);
|
||||
|
||||
ourLog.info(errors.toString());
|
||||
assertThat(errors.toString(), containsString("Questionnaire in invalid, unable to validate QuestionnaireAnswers: Multiple groups found at this position with linkId[]"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCodedAnswer() {
|
||||
String questionnaireRef = "http://example.com/Questionnaire/q1";
|
||||
|
@ -95,16 +138,17 @@ public class QuestionnaireAnswersValidatorTest {
|
|||
errors = new ArrayList<ValidationMessage>();
|
||||
myVal.validate(errors, qa);
|
||||
ourLog.info(errors.toString());
|
||||
assertThat(errors.toString(), containsString("location=QuestionnaireAnswers.group(0).question(0).answer(0)"));
|
||||
assertThat(errors.toString(), containsString("location=//QuestionnaireAnswers/group[0]/question[0]/answer[0]"));
|
||||
assertThat(errors.toString(), containsString("message=Question with linkId[link0] has answer with system[urn:system] and code[code1] but this is not a valid answer for ValueSet[http://somevalueset]"));
|
||||
|
||||
qa = new QuestionnaireAnswers();
|
||||
|
||||
qa.getQuestionnaire().setReference(questionnaireRef);
|
||||
qa.getGroup().addQuestion().setLinkId("link0").addAnswer().setValue(new Coding().setSystem("urn:system2").setCode("code3"));
|
||||
errors = new ArrayList<ValidationMessage>();
|
||||
myVal.validate(errors, qa);
|
||||
ourLog.info(errors.toString());
|
||||
assertThat(errors.toString(), containsString("location=QuestionnaireAnswers.group(0).question(0).answer(0)"));
|
||||
assertThat(errors.toString(), containsString("location=//QuestionnaireAnswers/group[0]/question[0]/answer[0]"));
|
||||
assertThat(errors.toString(), containsString("message=Question with linkId[link0] has answer with system[urn:system2] and code[code3] but this is not a valid answer for ValueSet[http://somevalueset]"));
|
||||
|
||||
}
|
||||
|
@ -144,7 +188,7 @@ public class QuestionnaireAnswersValidatorTest {
|
|||
myVal.validate(errors, qa);
|
||||
|
||||
ourLog.info(errors.toString());
|
||||
assertThat(errors.toString(), containsString("location=QuestionnaireAnswers.group(0).question"));
|
||||
assertThat(errors.toString(), containsString("location=//QuestionnaireAnswers/group[0]/question[0]"));
|
||||
assertThat(errors.toString(), containsString("message=Found answer with linkId[link1] but this ID is not allowed at this position"));
|
||||
}
|
||||
|
||||
|
@ -162,7 +206,7 @@ public class QuestionnaireAnswersValidatorTest {
|
|||
myVal.validate(errors, qa);
|
||||
|
||||
ourLog.info(errors.toString());
|
||||
assertThat(errors.toString(), containsString("location=QuestionnaireAnswers.group(0).group(0)"));
|
||||
assertThat(errors.toString(), containsString("location=//QuestionnaireAnswers/group[0]/group[0]"));
|
||||
assertThat(errors.toString(), containsString("Group with linkId[link1] found at this position, but this group does not exist at this position in Questionnaire"));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<ValueSet xmlns="http://hl7.org/fhir"><id value="104"/><define><concept><code value="1"/><definition value="Geen reactie"/></concept><concept><code value="2"/><definition value="Reactie op pijnprikkel"/></concept><concept><code value="3"/><definition value="Reactie op verbale prikkel"/></concept><concept><code value="4"/><definition value="Spontane reactie"/></concept></define></ValueSet>
|
|
@ -0,0 +1 @@
|
|||
<ValueSet xmlns="http://hl7.org/fhir"><id value="198"/><define><concept><code value="1"/><definition value="Geen reactie"/></concept><concept><code value="2"/><definition value="Strekken"/></concept><concept><code value="3"/><definition value="Decorticatie reflex (abnormaal buigen)"/></concept><concept><code value="4"/><definition value="Spastische reactie (terugtrekken)"/></concept><concept><code value="5"/><definition value="Lokaliseert pijn"/></concept><concept><code value="6"/><definition value="Volgt verbale commando's op"/></concept></define></ValueSet>
|
|
@ -0,0 +1 @@
|
|||
<ValueSet xmlns="http://hl7.org/fhir"><id value="435"/><define><concept><code value="1"/><definition value="Geen reactie"/></concept><concept><code value="2"/><definition value="Onbegrijpelijke geluiden"/></concept><concept><code value="3"/><definition value="Onduidelijke woorden"/></concept><concept><code value="4"/><definition value="Verwarde conversatie"/></concept><concept><code value="6"/><definition value="Helder en adequaat"/></concept></define></ValueSet>
|
|
@ -0,0 +1 @@
|
|||
<ValueSet xmlns="http://hl7.org/fhir"><id value="AdmissionSource"/><extensible value="false"/><define><concept><code value="1"/><definition value="Operatiekamer vanaf verpleegafdeling zelfde ziekenhuis"/></concept><concept><code value="2"/><definition value="Operatiekamer vanaf Eerste Hulp afdeling zelfde ziekenhuis"/></concept><concept><code value="3"/><definition value="Eerste Hulp afdeling zelfde ziekenhuis"/></concept><concept><code value="4"/><definition value="Verpleegafdeling zelfde ziekenhuis"/></concept><concept><code value="5"/><definition value="CCU/IC zelfde ziekenhuis"/></concept><concept><code value="6"/><definition value="Recovery zelfde ziekenhuis (alleen bij niet geplande IC-opname)"/></concept><concept><code value="7"/><definition value="Special/Medium care zelfde ziekenhuis"/></concept><concept><code value="8"/><definition value="Operatiekamer vanaf verpleegafdeling ander ziekenhuis"/></concept><concept><code value="9"/><definition value="Operatiekamer vanaf Eerste Hulp afdeling ander ziekenhuis"/></concept><concept><code value="10"/><definition value="Eerste Hulp afdeling ander ziekenhuis"/></concept><concept><code value="11"/><definition value="Verpleegafdeling ander ziekenhuis"/></concept><concept><code value="12"/><definition value="CCU/IC ander ziekenhuis"/></concept><concept><code value="13"/><definition value="Recovery ander ziekenhuis"/></concept><concept><code value="14"/><definition value="Special/Medium care ander ziekenhuis"/></concept><concept><code value="15"/><definition value="Huis"/></concept><concept><code value="16"/><definition value="Anders"/></concept><concept><code value="17"/><definition value="Andere locatie zelfde ziekenhuis, transport per ambulance"/></concept></define></ValueSet>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
<ValueSet xmlns="http://hl7.org/fhir"><id value="Discharged_to"/><extensible value="false"/><define><concept><code value="1"/><definition value="verpleegafdeling zelfde ziekenhuis (inclusief andere lokatie)"/></concept><concept><code value="2"/><definition value="CCU/ICU zelfde ziekenhuis"/></concept><concept><code value="3"/><definition value="Recovery/Medium Care zelfde ziekenhuis"/></concept><concept><code value="4"/><definition value="Verpleegafdeling ander ziekenhuis"/></concept><concept><code value="5"/><definition value="CCU/ICU ander ziekenhuis"/></concept><concept><code value="6"/><definition value="Recovery/Medium Care ander ziekenhuis"/></concept><concept><code value="7"/><definition value="Mortuarium"/></concept><concept><code value="8"/><definition value="Huis"/></concept><concept><code value="9"/><definition value="Anders"/></concept></define></ValueSet>
|
|
@ -0,0 +1,91 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<QuestionnaireAnswers xmlns="http://hl7.org/fhir">
|
||||
|
||||
<text>
|
||||
First message at the moment of admission.
|
||||
</text>
|
||||
|
||||
<questionnaire>
|
||||
<reference value="Questionnaire/nice-pilot-questionnaire" /> <!-- Should reference the nice-pilot-questionnaire.xml -->
|
||||
</questionnaire>
|
||||
<status value="in-progress"/>
|
||||
|
||||
<group>
|
||||
<linkId value="NICE-FHIR-Pilot"/>
|
||||
|
||||
<!-- 1 -->
|
||||
<group>
|
||||
<linkId value="opname identificatie"/>
|
||||
<question>
|
||||
<linkId value="hospno"/>
|
||||
<answer>
|
||||
<valueInteger value="88"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="icno"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="admno"/>
|
||||
<answer>
|
||||
<valueInteger value="1239827"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 2 -->
|
||||
<group>
|
||||
<linkId value="patientinformation" />
|
||||
<question>
|
||||
<linkId value="patno"/>
|
||||
<answer>
|
||||
<valueString value="KSJDHFSDFMNCVXJK"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="partialBSN"/>
|
||||
<answer>
|
||||
<valueInteger value="1232456"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="date_of_birth"/>
|
||||
<answer>
|
||||
<valueDate value="1964-03-09"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 3 -->
|
||||
<group>
|
||||
<linkId value="opnamegegevens"/>
|
||||
<question>
|
||||
<linkId value="adm_hosp"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-21T14:04:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_icu"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-21T14:04:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_source"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="cardio_vas_insuf"/>
|
||||
<answer>
|
||||
<valueBoolean value="true"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
</group>
|
||||
</QuestionnaireAnswers>
|
|
@ -0,0 +1,181 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<QuestionnaireAnswers xmlns="http://hl7.org/fhir">
|
||||
<text>
|
||||
Most of the items requested by NICE is collected within the first 24hours of ICU admission.
|
||||
Therefore we would like an update of the message with these values.
|
||||
</text>
|
||||
<questionnaire>
|
||||
<reference value="Questionnaire/nice-pilot-questionnaire" /> <!-- Should reference the nice-pilot-questionnaire.xml -->
|
||||
</questionnaire>
|
||||
<status value="in-progress"/>
|
||||
|
||||
<group>
|
||||
<linkId value="NICE-FHIR-Pilot"/>
|
||||
|
||||
<!-- 1 -->
|
||||
<group>
|
||||
<linkId value="opname identificatie"/>
|
||||
<question>
|
||||
<linkId value="hospno"/>
|
||||
<answer>
|
||||
<valueInteger value="88"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="icno"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="admno"/>
|
||||
<answer>
|
||||
<valueInteger value="1239827"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 2 -->
|
||||
<group>
|
||||
<linkId value="patientinformation" />
|
||||
<question>
|
||||
<linkId value="patno"/>
|
||||
<answer>
|
||||
<valueString value="KSJDHFSDFMNCVXJK"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="partialBSN"/>
|
||||
<answer>
|
||||
<valueInteger value="1232456"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="date_of_birth"/>
|
||||
<answer>
|
||||
<valueDate value="1964-03-09"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 3 -->
|
||||
<group>
|
||||
<linkId value="opnamegegevens"/>
|
||||
<question>
|
||||
<linkId value="adm_hosp"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-21T14:04:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_icu"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-21T14:04:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_source"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="cardio_vas_insuf"/>
|
||||
<answer>
|
||||
<valueBoolean value="true"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
<!-- 4 -->
|
||||
<group>
|
||||
<linkId value="1ste 24uur na opname"/>
|
||||
<question>
|
||||
<linkId value="ap4diag1"/>
|
||||
<answer>
|
||||
<valueInteger value="129"/> <!-- Guillian-Barre syndrome -->
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="ap4diag2"/>
|
||||
<answer>
|
||||
<valueInteger value="246"/> <!-- CABG with other operation -->
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="meanbl_max"/>
|
||||
<answer>
|
||||
<valueQuantity>
|
||||
<value value="240" />
|
||||
<units value="mmHg" />
|
||||
<system value="http://unitsofmeasure.org" />
|
||||
<code value="mm[Hg]" />
|
||||
</valueQuantity>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="meanbl_min"/>
|
||||
<answer>
|
||||
<valueQuantity>
|
||||
<value value="11" />
|
||||
<units value="mmHg" />
|
||||
<system value="http://unitsofmeasure.org" />
|
||||
<code value="mm[Hg]" />
|
||||
</valueQuantity>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="creat_max"/>
|
||||
<answer>
|
||||
<valueDecimal value="287"/>
|
||||
</answer>
|
||||
<!-- should be in umol/l -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="creat_min"/>
|
||||
<answer>
|
||||
<valueDecimal value="99"/>
|
||||
</answer>
|
||||
<!-- should be in umol/l -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="eye_24"/>
|
||||
<type value="choice"/>
|
||||
<answer>
|
||||
<valueInteger value="2" />
|
||||
</answer>
|
||||
|
||||
<!-- could or should i use loinc?
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"/>
|
||||
<code value="9267-6"/>
|
||||
<display value="Glasgow coma score eye opening"/>
|
||||
</coding>
|
||||
<text value="Eyes"/>
|
||||
</code>
|
||||
-->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="motor_24"/>
|
||||
<answer>
|
||||
<ValueInteger value="3"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="verbal_24"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
<!-- could or should i use loinc?
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"/>
|
||||
<code value="9270-0"/>
|
||||
<display value="Glasgow coma score verbal"/>
|
||||
</coding>
|
||||
<text value="Verbal"/>
|
||||
</code> -->
|
||||
</question>
|
||||
</group>
|
||||
</group>
|
||||
</QuestionnaireAnswers>
|
|
@ -0,0 +1,198 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<QuestionnaireAnswers xmlns="http://hl7.org/fhir">
|
||||
<text>
|
||||
At the end of an ICU admission, we want the discharge information.
|
||||
</text>
|
||||
<questionnaire>
|
||||
<reference value="Questionnaire/nice-pilot-questionnaire" /> <!-- Should reference the nice-pilot-questionnaire.xml -->
|
||||
</questionnaire>
|
||||
<status value="completed "/>
|
||||
|
||||
<group>
|
||||
<linkId value="NICE-FHIR-Pilot"/>
|
||||
|
||||
<!-- 1 -->
|
||||
<group>
|
||||
<linkId value="opname identificatie"/>
|
||||
<question>
|
||||
<linkId value="hospno"/>
|
||||
<answer>
|
||||
<valueInteger value="88"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="icno"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="admno"/>
|
||||
<answer>
|
||||
<valueInteger value="1239827"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 2 -->
|
||||
<group>
|
||||
<linkId value="patientinformation" />
|
||||
<question>
|
||||
<linkId value="patno"/>
|
||||
<answer>
|
||||
<valueString value="KSJDHFSDFMNCVXJK"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="partialBSN"/>
|
||||
<answer>
|
||||
<valueInteger value="1232456"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="date_of_birth"/>
|
||||
<answer>
|
||||
<valueDate value="1964-03-09"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 3 -->
|
||||
<group>
|
||||
<linkId value="opnamegegevens"/>
|
||||
<question>
|
||||
<linkId value="adm_hosp"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-21T14:04:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_icu"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-21T14:04:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_source"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="cardio_vas_insuf"/>
|
||||
<answer>
|
||||
<valueBoolean value="true"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
<!-- 4 -->
|
||||
<group>
|
||||
<linkId value="1ste 24uur na opname"/>
|
||||
<question>
|
||||
<linkId value="ap4diag1"/>
|
||||
<answer>
|
||||
<valueInteger value="129"/> <!-- Guillian-Barre syndrome -->
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="ap4diag2"/>
|
||||
<answer>
|
||||
<valueInteger value="246"/> <!-- CABG with other operation -->
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="meanbl_max"/>
|
||||
<answer>
|
||||
<valueQuantity>
|
||||
<value value="240" />
|
||||
<units value="mmHg" />
|
||||
<system value="http://unitsofmeasure.org" />
|
||||
<code value="mm[Hg]" />
|
||||
</valueQuantity>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="meanbl_min"/>
|
||||
<answer>
|
||||
<valueQuantity>
|
||||
<value value="11" />
|
||||
<units value="mmHg" />
|
||||
<system value="http://unitsofmeasure.org" />
|
||||
<code value="mm[Hg]" />
|
||||
</valueQuantity>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="creat_max"/>
|
||||
<answer>
|
||||
<valueDecimal value="287"/>
|
||||
</answer>
|
||||
<!-- should be in umol/l -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="creat_min"/>
|
||||
<answer>
|
||||
<valueDecimal value="99"/>
|
||||
</answer>
|
||||
<!-- should be in umol/l -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="eye_24"/>
|
||||
<type value="choice"/>
|
||||
<answer>
|
||||
<valueInteger value="2" />
|
||||
</answer>
|
||||
|
||||
<!-- could or should i use loinc?
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"/>
|
||||
<code value="9267-6"/>
|
||||
<display value="Glasgow coma score eye opening"/>
|
||||
</coding>
|
||||
<text value="Eyes"/>
|
||||
</code>
|
||||
-->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="motor_24"/>
|
||||
<answer>
|
||||
<ValueInteger value="3"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="verbal_24"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
<!-- could or should i use loinc?
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"/>
|
||||
<code value="9270-0"/>
|
||||
<display value="Glasgow coma score verbal"/>
|
||||
</coding>
|
||||
<text value="Verbal"/>
|
||||
</code> -->
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 5 -->
|
||||
<group>
|
||||
<linkId value="IC ontslaggegevens"/>
|
||||
<question>
|
||||
<linkId value="dis_icu"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-23T08:44:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="discharged_to"/>
|
||||
<answer>
|
||||
<valueInteger value="7"/> <!-- mortuary -->
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
</QuestionnaireAnswers>
|
|
@ -0,0 +1,251 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Questionnaire xmlns="http://hl7.org/fhir">
|
||||
<text>
|
||||
The Dutch National Intensive Care Evaluation (NICE) foundation
|
||||
facilitates a registry to enable participating intensive care units to
|
||||
quantify and improve the quality of care they offer. The NICE
|
||||
foundation offers intensive care units feedback and benchmarking on
|
||||
patient outcomes, including mortality and allows them to compare their
|
||||
outcomes with those achieved nationally and in groups of similar
|
||||
hospitals. The foundation provides each participating intensive care
|
||||
unit with biannual quality reports and access to an online tool
|
||||
enabling each intensive care unit to perform additional analyses on
|
||||
their data at any time. It also publishes two magazines each year with
|
||||
features based on analyses of registry data and organizes a national
|
||||
conference to enable medical and nursing specialists to meet and
|
||||
discuss their own and national results. In addition, the foundation
|
||||
collects data to enable quality indicators developed by the
|
||||
Netherlands Society of Intensive Care to be calculated.
|
||||
|
||||
The data is collected since 1996 until today using Ms Access files which
|
||||
where send monthly. Now a pilot is setup to collect this data "realtime"
|
||||
with FHIR.
|
||||
|
||||
In this questionnaire is a representative selection of items from the NICE definitions.
|
||||
The language used in the texts, is dutch (sorry).
|
||||
|
||||
</text>
|
||||
<identifier>
|
||||
<use value="official"/>
|
||||
<system value="http://stichting-nice.nl/pilot/fhir"/>
|
||||
</identifier>
|
||||
<status value="draft"/>
|
||||
<group>
|
||||
<linkId value="NICE-FHIR-Pilot"/>
|
||||
<title value="NICE FHIR Pilot questionnaire"/>
|
||||
<required value="true"/>
|
||||
<repeats value="false"/>
|
||||
|
||||
<!-- 1 -->
|
||||
<group>
|
||||
<linkId value="opname identificatie"/>
|
||||
<required value="true"/>
|
||||
<repeats value="false"/>
|
||||
<title value="Wat is de identificatie van de opname volgens de regels van NICE?"/>
|
||||
<text value="Vrijwel alle gegevens die de NICE wil ontvangen, is gerelateerd aan een IC-opname. Deze wordt door de NICE
|
||||
geidentificeerd met behulp van de combinatie ziekenhuisnummer, ic-nummer en het opnamenummer.
|
||||
Dit onderdeel is dan ook verplicht voor elke opname gerelateerde questionnaire. De periodieke gegevens als
|
||||
de jaargegevens, kwartaalgegevens en de dagelijkse fteâs en bedbezetting hebben een aangepaste sleutel. "/>
|
||||
<required value="true"/>
|
||||
<repeats value="false"/>
|
||||
<question>
|
||||
<linkId value="hospno"/>
|
||||
<text value="Wat is het door NICE toegekende ziekenhuisnummer?"/>
|
||||
<type value="integer"/>
|
||||
<required value="true"/>
|
||||
<repeats value="false"/>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="icno"/>
|
||||
<text value="Wat is het door NICE toegekende IC nummer voor de afdeling?"/>
|
||||
<type value="integer"/>
|
||||
<required value="true"/>
|
||||
<repeats value="false"/>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="admno"/>
|
||||
<text value="Wat is het unieke nummer dat door de instelling is toegewezen aan deze opname?"/>
|
||||
<type value="integer"/>
|
||||
<required value="true"/>
|
||||
<repeats value="false"/>
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 2 -->
|
||||
<group>
|
||||
<!-- For now as questions, might want to use a reference to a patient resource -->
|
||||
<linkId value="patientinformation" />
|
||||
<text value="De gegevens die bekent zijn bij IC opname"/>
|
||||
<required value="false"/>
|
||||
<repeats value="false"/>
|
||||
<question>
|
||||
<linkId value="patno"/>
|
||||
<text value="Wat is het NICE geencrypteerde patientnummer?"/>
|
||||
<type value="string"/>
|
||||
<required value="true"/>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="partialBSN"/>
|
||||
<text value="Wat zijn de eerste 6 cijfers van het BSN?"/>
|
||||
<type value="string"/>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="date_of_birth"/>
|
||||
<text value="Wat is de geboortedatum van de patient?"/>
|
||||
<type value="date"/>
|
||||
<required value="true"/>
|
||||
</question>
|
||||
</group>
|
||||
<!-- 3 -->
|
||||
<group>
|
||||
<linkId value="opnamegegevens"/>
|
||||
<required value="false"/>
|
||||
<repeats value="false"/>
|
||||
<question>
|
||||
<linkId value="adm_hosp"/>
|
||||
<text value="Wat is de ziekenhuisopnamedatum ( optioneel: en -tijd)?"/>
|
||||
<type value="dateTime"/>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_icu"/>
|
||||
<text value="Wat is de IC opnamedatum en -tijd?"/>
|
||||
<type value="dateTime"/>
|
||||
<required value="true"/>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_source"/>
|
||||
<text value="Wat is de herkomst van de patient direct voor IC-opname"/>
|
||||
<type value="choice"/>
|
||||
<options>
|
||||
<reference value="https://stichting-nice.nl/pilot/fhir/ValueSet/AdmissionSource"/>
|
||||
</options>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="cardio_vas_insuf"/>
|
||||
<text value="Angina of symptomen in rust of bij minimale inspanning (aankleden en verzorging)? (New York Heart Association klasse IV)."/>
|
||||
<type value="boolean"/>
|
||||
</question>
|
||||
</group>
|
||||
<!-- 4 -->
|
||||
<group>
|
||||
<linkId value="1ste 24uur na opname"/>
|
||||
<required value="false"/>
|
||||
<repeats value="false"/>
|
||||
<text value="De gegevens over de 1ste 24uur van de IC opname"/>
|
||||
<question>
|
||||
<linkId value="ap4diag1"/>
|
||||
<text value="Welke APACHE IV diagnose hoort bij deze IC opname?"/>
|
||||
<type value="choice"/>
|
||||
<options>
|
||||
<!-- reference exists -->
|
||||
<reference value="https://stichting-nice.nl/pilot/fhir/ValueSet/ApacheIVDiagnose"/>
|
||||
</options>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="ap4diag2"/>
|
||||
<text value="Welke optionele 2de APACHE IV diagnose hoort bij deze IC opname?"/>
|
||||
<type value="choice"/>
|
||||
<options>
|
||||
<!-- reference exists -->
|
||||
<reference value="https://stichting-nice.nl/pilot/fhir/ValueSet/ApacheIVDiagnose"/>
|
||||
</options>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="meanbl_max"/>
|
||||
<text value="Wat was de hoogste gemiddelde bloeddruk in de 1ste 24uur van IC opname?"/>
|
||||
<type value="quantity"/>
|
||||
<!-- should be in mmHg -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="meanbl_min"/>
|
||||
<text value="Wat was de laagste gemiddelde bloeddruk in de 1ste 24uur van IC opname?"/>
|
||||
<type value="quantity"/>
|
||||
<!-- should be in mmHg -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="creat_max"/>
|
||||
<text value="Wat was de hoogste waarde serum creatinine in de 1ste 24uur van IC opname?"/>
|
||||
<type value="quantity"/>
|
||||
<!-- should be in umol/l -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="creat_min"/>
|
||||
<text value="Wat was de laagste waarde serum creatinine in de 1ste 24uur van IC opname?"/>
|
||||
<type value="quantity"/>
|
||||
<!-- should be in umol/l -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="eye_24"/>
|
||||
<text value="Wat is de oogreactie 24uur na IC opname?"/>
|
||||
<type value="choice"/>
|
||||
<options>
|
||||
<reference value="https://stichting-nice.nl/pilot/fhir/ValueSet/104"/>
|
||||
</options>
|
||||
|
||||
<!-- could or should i use loinc?
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"/>
|
||||
<code value="9267-6"/>
|
||||
<display value="Glasgow coma score eye opening"/>
|
||||
</coding>
|
||||
<text value="Eyes"/>
|
||||
</code>
|
||||
-->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="motor_24"/>
|
||||
<concept>
|
||||
<coding>
|
||||
<system value="http://loinc.org"/>
|
||||
<code value="9268-4"/>
|
||||
<display value="Glasgow coma score motor"/>
|
||||
</coding>
|
||||
</concept>
|
||||
<text value="Wat is de motorische reactie 24uur na IC opname?"/>
|
||||
<type value="choice"/>
|
||||
<options>
|
||||
<reference value="https://stichting-nice.nl/pilot/fhir/ValueSet/198"/>
|
||||
</options>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="verbal_24"/>
|
||||
<text value="Wat is de verbale reactie 24uur na IC opname?"/>
|
||||
<type value="choice"/>
|
||||
<options>
|
||||
<reference value="https://stichting-nice.nl/pilot/fhir/ValueSet/435"/>
|
||||
</options>
|
||||
|
||||
<!-- could or should i use loinc?
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"/>
|
||||
<code value="9270-0"/>
|
||||
<display value="Glasgow coma score verbal"/>
|
||||
</coding>
|
||||
<text value="Verbal"/>
|
||||
</code> -->
|
||||
</question>
|
||||
</group>
|
||||
<!-- 5 -->
|
||||
<group>
|
||||
<linkId value="IC ontslaggegevens"/>
|
||||
<required value="false"/>
|
||||
<repeats value="false"/>
|
||||
<text value="De gegevens die bekend zijn na IC ontslag"/>
|
||||
<question>
|
||||
<linkId value="dis_icu"/>
|
||||
<text value="Wat is de IC ontslagdatum en âtijd?"/>
|
||||
<type value="dateTime"/>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="discharged_to"/>
|
||||
<text value="Wat is de ontslagbestemming?"/>
|
||||
<type value="choice"/>
|
||||
<options>
|
||||
<reference value="https://stichting-nice.nl/pilot/fhir/ValueSet/Discharged_to"/>
|
||||
</options>
|
||||
</question>
|
||||
</group>
|
||||
</group>
|
||||
</Questionnaire>
|
|
@ -0,0 +1,195 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<QuestionnaireAnswers xmlns="http://hl7.org/fhir">
|
||||
<questionnaire>
|
||||
<reference value="Questionnaire/nice-pilot-questionnaire" /> <!-- Should reference the nice-pilot-questionnaire.xml -->
|
||||
</questionnaire>
|
||||
<status value="in-progress"/>
|
||||
|
||||
<group>
|
||||
<linkId value="NICE-FHIR-Pilot"/>
|
||||
|
||||
<!-- 1 -->
|
||||
<group>
|
||||
<linkId value="opname identificatie"/>
|
||||
<question>
|
||||
<linkId value="hospno"/>
|
||||
<answer>
|
||||
<valueInteger value="88"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="icno"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="admno"/>
|
||||
<answer>
|
||||
<valueInteger value="1239827"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 2 -->
|
||||
<group>
|
||||
<linkId value="patientinformation" />
|
||||
<question>
|
||||
<linkId value="patno"/>
|
||||
<answer>
|
||||
<valueString value="KSJDHFSDFMNCVXJK"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="partialBSN"/>
|
||||
<answer>
|
||||
<valueInteger value="1232456"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="date_of_birth"/>
|
||||
<answer>
|
||||
<valueDate value="1964-03-09"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 3 -->
|
||||
<group>
|
||||
<linkId value="opnamegegevens"/>
|
||||
<question>
|
||||
<linkId value="adm_hosp"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-21T14:04:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_icu"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-21T14:04:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="adm_source"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="cardio_vas_insuf"/>
|
||||
<answer>
|
||||
<valueBoolean value="true"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
<!-- 4 -->
|
||||
<group>
|
||||
<linkId value="1ste 24uur na opname"/>
|
||||
<question>
|
||||
<linkId value="ap4diag1"/>
|
||||
<answer>
|
||||
<valueInteger value="129"/> <!-- Guillian-Barre syndrome -->
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="ap4diag2"/>
|
||||
<answer>
|
||||
<valueInteger value="246"/> <!-- CABG with other operation -->
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="meanbl_max"/>
|
||||
<answer>
|
||||
<valueQuantity>
|
||||
<value value="240" />
|
||||
<units value="mmHg" />
|
||||
<system value="http://unitsofmeasure.org" />
|
||||
<code value="mm[Hg]" />
|
||||
</valueQuantity>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="meanbl_min"/>
|
||||
<answer>
|
||||
<valueQuantity>
|
||||
<value value="11" />
|
||||
<units value="mmHg" />
|
||||
<system value="http://unitsofmeasure.org" />
|
||||
<code value="mm[Hg]" />
|
||||
</valueQuantity>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="creat_max"/>
|
||||
<answer>
|
||||
<valueDecimal value="287"/>
|
||||
</answer>
|
||||
<!-- should be in umol/l -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="creat_min"/>
|
||||
<answer>
|
||||
<valueDecimal value="99"/>
|
||||
</answer>
|
||||
<!-- should be in umol/l -->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="eye_24"/>
|
||||
<type value="choice"/>
|
||||
<answer>
|
||||
<valueInteger value="2" />
|
||||
</answer>
|
||||
|
||||
<!-- could or should i use loinc?
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"/>
|
||||
<code value="9267-6"/>
|
||||
<display value="Glasgow coma score eye opening"/>
|
||||
</coding>
|
||||
<text value="Eyes"/>
|
||||
</code>
|
||||
-->
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="motor_24"/>
|
||||
<answer>
|
||||
<ValueInteger value="3"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="verbal_24"/>
|
||||
<answer>
|
||||
<valueInteger value="1"/>
|
||||
</answer>
|
||||
<!-- could or should i use loinc?
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://loinc.org"/>
|
||||
<code value="9270-0"/>
|
||||
<display value="Glasgow coma score verbal"/>
|
||||
</coding>
|
||||
<text value="Verbal"/>
|
||||
</code> -->
|
||||
</question>
|
||||
</group>
|
||||
|
||||
<!-- 5 -->
|
||||
<group>
|
||||
<linkId value="IC ontslaggegevens"/>
|
||||
<question>
|
||||
<linkId value="dis_icu"/>
|
||||
<answer>
|
||||
<valueDateTime value="2015-07-23T08:44:00+01:00"/>
|
||||
</answer>
|
||||
</question>
|
||||
<question>
|
||||
<linkId value="discharged_to"/>
|
||||
<answer>
|
||||
<valueInteger value="7"/>
|
||||
</answer>
|
||||
</question>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
</QuestionnaireAnswers>
|
Loading…
Reference in New Issue