use of org.hl7.fhir.r4b.model.Questionnaire.QuestionnaireItemComponent in project org.hl7.fhir.core by hapifhir.
the class QuestionnaireValidator method checkDateOption.
private void checkDateOption(List<ValidationMessage> errors, Element answer, NodeStack stack, QuestionnaireWithContext qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
Element v = answer.getNamedChild("valueDate");
NodeStack ns = stack.push(v, -1, null, null);
if (qItem.getAnswerOption().size() > 0) {
List<DateType> list = new ArrayList<DateType>();
for (QuestionnaireItemAnswerOptionComponent components : qItem.getAnswerOption()) {
try {
list.add(components.getValueDateType());
} catch (FHIRException e) {
// If it's the wrong type, just keep going
}
}
if (list.isEmpty() && !openChoice) {
rule(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_NOOPTIONSDATE);
} else {
boolean found = false;
for (DateType item : list) {
if (item.getValue().equals(v.primitiveValue())) {
found = true;
break;
}
}
if (!found) {
rule(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), found, I18nConstants.QUESTIONNAIRE_QR_ITEM_NODATE, v.primitiveValue());
}
}
} else
hint(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_DATENOOPTIONS);
}
use of org.hl7.fhir.r4b.model.Questionnaire.QuestionnaireItemComponent in project org.hl7.fhir.core by hapifhir.
the class QuestionnaireValidator method validateQuestionnaireResponseItem.
private void validateQuestionnaireResponseItem(ValidatorHostContext hostContext, QuestionnaireWithContext qsrc, QuestionnaireItemComponent qItem, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
String text = element.getNamedChildValue("text");
rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), Utilities.noString(text) || text.equals(qItem.getText()), I18nConstants.QUESTIONNAIRE_QR_ITEM_TEXT, qItem.getLinkId());
List<Element> answers = new ArrayList<Element>();
element.getNamedChildren("answer", answers);
if (inProgress)
warning(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), isAnswerRequirementFulfilled(qItem, answers), I18nConstants.QUESTIONNAIRE_QR_ITEM_MISSING, qItem.getLinkId());
else if (myEnableWhenEvaluator.isQuestionEnabled(hostContext, qItem, qstack, fpe)) {
rule(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), isAnswerRequirementFulfilled(qItem, answers), I18nConstants.QUESTIONNAIRE_QR_ITEM_MISSING, qItem.getLinkId());
} else if (!answers.isEmpty()) {
// items without answers should be allowed, but not items with answers to questions that are disabled
// it appears that this is always a duplicate error - it will always already have been reported, so no need to report it again?
// GDG 2019-07-13
// rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), !isAnswerRequirementFulfilled(qItem, answers), I18nConstants.QUESTIONNAIRE_QR_ITEM_NOTENABLED, qItem.getLinkId());
}
if (answers.size() > 1)
rule(errors, IssueType.INVALID, answers.get(1).line(), answers.get(1).col(), stack.getLiteralPath(), qItem.getRepeats(), I18nConstants.QUESTIONNAIRE_QR_ITEM_ONLYONEA);
int i = 0;
for (Element answer : answers) {
NodeStack ns = stack.push(answer, i, null, null);
if (qItem.getType() != null) {
switch(qItem.getType()) {
case GROUP:
rule(errors, IssueType.STRUCTURE, answer.line(), answer.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_GROUP);
break;
case // nothing
DISPLAY:
break;
case BOOLEAN:
validateQuestionnaireResponseItemType(errors, answer, ns, "boolean");
break;
case DECIMAL:
validateQuestionnaireResponseItemType(errors, answer, ns, "decimal");
break;
case INTEGER:
validateQuestionnaireResponseItemType(errors, answer, ns, "integer");
break;
case DATE:
validateQuestionnaireResponseItemType(errors, answer, ns, "date");
break;
case DATETIME:
validateQuestionnaireResponseItemType(errors, answer, ns, "dateTime");
break;
case TIME:
validateQuestionnaireResponseItemType(errors, answer, ns, "time");
break;
case STRING:
validateQuestionnaireResponseItemType(errors, answer, ns, "string");
break;
case TEXT:
validateQuestionnaireResponseItemType(errors, answer, ns, "text");
break;
case URL:
validateQuestionnaireResponseItemType(errors, answer, ns, "uri");
break;
case ATTACHMENT:
validateQuestionnaireResponseItemType(errors, answer, ns, "Attachment");
break;
case REFERENCE:
validateQuestionnaireResponseItemType(errors, answer, ns, "Reference");
break;
case QUANTITY:
if ("Quantity".equals(validateQuestionnaireResponseItemType(errors, answer, ns, "Quantity")))
if (qItem.hasExtension("???"))
validateQuestionnaireResponseItemQuantity(errors, answer, ns);
break;
case CODING:
String itemType = validateQuestionnaireResponseItemType(errors, answer, ns, "Coding", "date", "time", "integer", "string");
if (itemType != null) {
if (itemType.equals("Coding"))
validateAnswerCode(errors, answer, ns, qsrc, qItem, false);
else if (itemType.equals("date"))
checkOption(errors, answer, ns, qsrc, qItem, "date");
else if (itemType.equals("time"))
checkOption(errors, answer, ns, qsrc, qItem, "time");
else if (itemType.equals("integer"))
checkOption(errors, answer, ns, qsrc, qItem, "integer");
else if (itemType.equals("string"))
checkOption(errors, answer, ns, qsrc, qItem, "string");
}
break;
// case QUESTION:
case NULL:
// no validation
break;
case QUESTION:
throw new Error("Shouldn't get here?");
}
}
if (qItem.getType() != QuestionnaireItemType.GROUP) {
// if it's a group, we already have an error before getting here, so no need to hammer away on that
validateQuestionannaireResponseItems(hostContext, qsrc, qItem.getItem(), errors, answer, stack, inProgress, questionnaireResponseRoot, qstack);
}
i++;
}
if (qItem.getType() == null) {
fail(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_NOTYPE, qItem.getLinkId());
} else if (qItem.getType() == QuestionnaireItemType.DISPLAY) {
List<Element> items = new ArrayList<Element>();
element.getNamedChildren("item", items);
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), items.isEmpty(), I18nConstants.QUESTIONNAIRE_QR_ITEM_DISPLAY, qItem.getLinkId());
} else if (qItem.getType() != QuestionnaireItemType.GROUP) {
List<Element> items = new ArrayList<Element>();
element.getNamedChildren("item", items);
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), items.isEmpty(), I18nConstants.QUESTIONNAIRE_QR_ITEM_GROUP_ANSWER, qItem.getLinkId());
} else {
validateQuestionannaireResponseItems(hostContext, qsrc, qItem.getItem(), errors, element, stack, inProgress, questionnaireResponseRoot, qstack);
}
}
use of org.hl7.fhir.r4b.model.Questionnaire.QuestionnaireItemComponent in project org.hl7.fhir.core by hapifhir.
the class QuestionnaireBuilder method processExisting.
private void processExisting(String path, List<QuestionnaireResponse.QuestionnaireResponseItemComponent> answerGroups, QuestionnaireItemComponent item, List<QuestionnaireResponse.QuestionnaireResponseItemComponent> nResponse) throws FHIRException {
// processing existing data
for (QuestionnaireResponse.QuestionnaireResponseItemComponent ag : answerGroups) {
List<Base> children = ((Element) ag.getUserData("object")).listChildrenByName(tail(path));
for (Base child : children) {
if (child != null) {
QuestionnaireResponse.QuestionnaireResponseItemComponent ans = ag.addItem();
ag.setLinkId(item.getLinkId());
ans.setUserData("object", child);
nResponse.add(ans);
}
}
}
}
use of org.hl7.fhir.r4b.model.Questionnaire.QuestionnaireItemComponent in project org.hl7.fhir.core by hapifhir.
the class QuestionnaireBuilder method addReferenceQuestions.
// Special Types ---------------------------------------------------------------
private void addReferenceQuestions(QuestionnaireItemComponent group, ElementDefinition element, String path, List<CanonicalType> profileURL, List<QuestionnaireResponse.QuestionnaireResponseItemComponent> answerGroups) throws FHIRException {
// var
// rn : String;
// i : integer;
// q : TFhirQuestionnaireGroupQuestion;
ToolingExtensions.addFhirType(group, "Reference");
QuestionnaireItemComponent q = addQuestion(group, QuestionnaireItemType.REFERENCE, path, "value", group.getText(), answerGroups);
group.setText(null);
CommaSeparatedStringBuilder rn = new CommaSeparatedStringBuilder();
for (UriType u : profileURL) if (u.getValue().startsWith("http://hl7.org/fhir/StructureDefinition/"))
rn.append(u.getValue().substring(40));
if (rn.length() == 0)
ToolingExtensions.addReferenceFilter(q, "subject=$subj&patient=$subj&encounter=$encounter");
else {
ToolingExtensions.addAllowedResource(q, rn.toString());
ToolingExtensions.addReferenceFilter(q, "subject=$subj&patient=$subj&encounter=$encounter");
}
for (QuestionnaireResponse.QuestionnaireResponseItemComponent ag : answerGroups) ag.setText(null);
}
use of org.hl7.fhir.r4b.model.Questionnaire.QuestionnaireItemComponent in project org.hl7.fhir.core by hapifhir.
the class QuestionnaireBuilder method buildQuestion.
private void buildQuestion(QuestionnaireItemComponent group, StructureDefinition profile, ElementDefinition element, String path, List<QuestionnaireResponse.QuestionnaireResponseItemComponent> answerGroups, List<ElementDefinition> parents) throws FHIRException {
group.setLinkId(path);
// in this context, we don't have any concepts to mark...
// prefix with name?
group.setText(element.getShort());
group.setRequired(element.getMin() > 0);
if (element.getMin() > 0)
ToolingExtensions.addMin(group, element.getMin());
group.setRepeats(!element.getMax().equals('1'));
if (!element.getMax().equals("*"))
ToolingExtensions.addMax(group, Integer.parseInt(element.getMax()));
for (QuestionnaireResponse.QuestionnaireResponseItemComponent ag : answerGroups) {
ag.setLinkId(group.getLinkId());
ag.setText(group.getText());
}
if (!Utilities.noString(element.getComment()))
ToolingExtensions.addFlyOver(group, element.getDefinition() + " " + element.getComment(), group.getLinkId() + "-flyover");
else
ToolingExtensions.addFlyOver(group, element.getDefinition(), group.getLinkId() + "-flyover");
if (element.getType().size() > 1 || element.getType().get(0).getWorkingCode().equals("*")) {
List<TypeRefComponent> types = expandTypeList(element.getType());
Questionnaire.QuestionnaireItemComponent q = addQuestion(group, QuestionnaireItemType.CHOICE, element.getPath(), "_type", "type", null, makeTypeList(profile, types, element.getPath()));
for (TypeRefComponent t : types) {
Questionnaire.QuestionnaireItemComponent sub = q.addItem();
sub.setType(QuestionnaireItemType.GROUP);
sub.setLinkId(element.getPath() + "._" + t.getUserData("text"));
sub.setText((String) t.getUserData("text"));
// always optional, never repeats
List<QuestionnaireResponse.QuestionnaireResponseItemComponent> selected = new ArrayList<QuestionnaireResponse.QuestionnaireResponseItemComponent>();
selectTypes(profile, sub, t, answerGroups, selected);
processDataType(profile, sub, element, element.getPath() + "._" + t.getUserData("text"), t, selected, parents);
}
} else
// now we have to build the question panel for each different data type
processDataType(profile, group, element, element.getPath(), element.getType().get(0), answerGroups, parents);
}
Aggregations