diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/R3TEchnicalCorrectionProcessor.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/R3TEchnicalCorrectionProcessor.java new file mode 100644 index 000000000..1d704dad5 --- /dev/null +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/R3TEchnicalCorrectionProcessor.java @@ -0,0 +1,162 @@ +package org.hl7.fhir.dstu3.utils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.io.FileUtils; +import org.hl7.fhir.dstu3.formats.IParser.OutputStyle; +import org.hl7.fhir.dstu3.formats.JsonParser; +import org.hl7.fhir.dstu3.formats.XmlParser; +import org.hl7.fhir.dstu3.model.Bundle; +import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; +import org.hl7.fhir.dstu3.model.DomainResource; +import org.hl7.fhir.dstu3.model.Resource; +import org.hl7.fhir.exceptions.FHIRFormatError; +import org.hl7.fhir.utilities.Utilities; + +public class R3TEchnicalCorrectionProcessor { + + public static void main(String[] args) throws FileNotFoundException, IOException { + new R3TEchnicalCorrectionProcessor().execute(args[0], args[1]); + + } + + private void execute(String src, String packageRoot) throws FileNotFoundException, IOException { + System.out.println("Loading resources from "+src); + List resources = new ArrayList<>(); + Map definitions = new HashMap<>(); + for (File f : new File(src).listFiles()) { + if (f.getName().endsWith(".xml") && !(f.getName().endsWith("warnings.xml") || f.getName().endsWith(".diff.xml"))) { + try { + Resource r = new XmlParser().parse(new FileInputStream(f)); + if (f.getName().contains("canonical")) { + resources.add(r); + } + if (Utilities.existsInList(f.getName(), "conceptmaps.xml", "dataelements.xml", "extension-definitions.xml", "profiles-others.xml", "profiles-resources.xml", + "profiles-types.xml", "search-parameters.xml", "v2-tables.xml", "v3-codesystems.xml", "valuesets.xml")) { + definitions.put(f.getName(), r); + } + r.setUserData("path", f.getName().substring(0, f.getName().indexOf("."))); +// FileUtils.copyFile(f, new File(f.getAbsolutePath()+"1")); +// FileUtils.copyFile(f, new File(f.getAbsolutePath()+"2")); + } catch (Exception e) { + System.out.println("Unable to load "+f.getName()+": "+e.getMessage()); + } + } + if (f.getName().endsWith(".json") && !(f.getName().endsWith("schema.json") || f.getName().endsWith(".diff.json"))) { + try { +// new JsonParser().parse(new FileInputStream(f)); +// FileUtils.copyFile(f, new File(f.getAbsolutePath()+"1")); +// FileUtils.copyFile(f, new File(f.getAbsolutePath()+"2")); + } catch (Exception e) { + System.out.println("Unable to load "+f.getName()+": "+e.getMessage()); + } + } + } + System.out.println(Integer.toString(resources.size())+" resources"); + System.out.println(Integer.toString(definitions.size())+" resources"); + produceExamplesXml(resources, src); + produceDefinitionsXml(definitions, src); + produceExamplesJson(resources, src); + produceDefinitionsJson(definitions, src); + for (Resource r : definitions.values()) { + if (r instanceof Bundle) { + Bundle bnd = (Bundle) r; + for (BundleEntryComponent be : bnd.getEntry()) { + resources.add(be.getResource()); + } + } + } + extractToPackageMaster(resources, packageRoot); + System.out.println("Done"); + } + + private void produceDefinitionsXml(Map definitions, String dest) throws IOException { + for (String n : definitions.keySet()) { + File f = new File(Utilities.path(dest, "definitions.xml", n)); + new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f), definitions.get(n)); + } + } + + private void produceDefinitionsJson(Map definitions, String dest) throws IOException { + for (String n : definitions.keySet()) { + File f = new File(Utilities.path(dest, "definitions.json", Utilities.changeFileExt(n, ".json"))); + new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f), definitions.get(n)); + } + } + + private void produceExamplesJson(List resources, String dest) throws FileNotFoundException, IOException { + for (Resource r : resources) { + String n = r.fhirType().toLowerCase()+"-"+r.getUserString("path"); + if (!r.getId().equals(r.getUserString("path"))) { + n = n+"("+r.getId()+")"; + } + File f = new File(Utilities.path(dest, "examples-json", n+".json")); + new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f), r); + } + + } + + private void produceExamplesXml(List resources, String dest) throws FileNotFoundException, IOException { + for (Resource r : resources) { + String n = r.fhirType().toLowerCase()+"-"+r.getUserString("path"); + if (!r.getId().equals(r.getUserString("path"))) { + n = n+"("+r.getId()+")"; + } + File f = new File(Utilities.path(dest, "examples", n+".xml")); + new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f), r); + } + } + + private void extractToPackageMaster(List list, String root) throws IOException, FHIRFormatError { + System.out.println("Updating Packages Master"); + String corePath = Utilities.path(root, "hl7.fhir.r3.core", "package"); + String examplesPath = Utilities.path(root, "hl7.fhir.r3.examples", "package"); + String elementsPath = Utilities.path(root, "hl7.fhir.r3.elements", "package"); + int coreTotal = new File(corePath).list().length-1; + int examplesTotal = new File(examplesPath).list().length-1; + int elementsTotal = new File(elementsPath).list().length-1; + + int coreCount = 0; + int examplesCount = 0; + int elementsCount = 0; + for (Resource r : list) { + String n = r.fhirType()+"-"+r.getId()+".json"; + FileOutputStream dst = null; + if (n.startsWith("DataElement-")) { + elementsCount++; + dst = new FileOutputStream(Utilities.path(elementsPath, n)); + new JsonParser().setOutputStyle(OutputStyle.NORMAL).compose(dst, r); + } else { + dst = new FileOutputStream(Utilities.path(examplesPath, n)); + new JsonParser().setOutputStyle(OutputStyle.NORMAL).compose(dst, r); + if (isCoreResource(r.fhirType())) { + coreCount++; + DomainResource dr = (DomainResource) r; + dr.setText(null); + new JsonParser().setOutputStyle(OutputStyle.NORMAL).compose(new FileOutputStream(Utilities.path(corePath, n)), r); + } + } + } + System.out.println(" Core @ "+corePath+": Replaced "+coreCount+" of "+coreTotal); + System.out.println(" Examples @ "+examplesPath+": Replaced "+examplesCount+" of "+examplesTotal); + System.out.println(" Elements @ "+elementsPath+": Replaced "+elementsCount+" of "+elementsTotal); + } + + private boolean isCoreResource(String rt) { + return Utilities.existsInList(rt, "CapabilityStatement", "CodeSystem", "CompartmentDefinition", "ConceptMap", "NamingSystem", "OperationDefinition", "SearchParameter", "StructureDefinition", "StructureMap", "ValueSet"); + } + +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java index c73b65901..c56812cc3 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java @@ -91,7 +91,7 @@ public abstract class ParserBase { protected StructureDefinition getDefinition(int line, int col, String ns, String name) throws FHIRFormatError { if (ns == null) { - logError(line, col, name, IssueType.STRUCTURE, "This cannot be parsed as a FHIR object (no namespace)", IssueSeverity.FATAL); + logError(line, col, name, IssueType.STRUCTURE, "This '"+name+"' cannot be parsed as a FHIR object (no namespace)", IssueSeverity.FATAL); return null; } if (name == null) { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java index 3d98973ec..868a3fa95 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java @@ -2306,6 +2306,8 @@ public class ElementDefinition extends BackboneType implements ICompositeType { return "integer"; if ("xsd:decimal OR xsd:double".equals(s)) return "decimal"; + if ("xsd:decimal".equals(s)) + return "decimal"; if ("xsd:base64Binary".equals(s)) return "base64Binary"; if ("xsd:positiveInteger".equals(s)) diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/TurtleTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/TurtleTests.java index 92a4d2f84..640b20ab7 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/TurtleTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/TurtleTests.java @@ -1001,7 +1001,7 @@ public class TurtleTests { } @Test public void test_turtle_syntax_bad_number_dot_in_anon() throws Exception { - doTest(TestingUtilities.resourceNameToFile("turtle", "turtle-syntax-bad-number-dot-in-anon.ttl"), true); + doTest(TestingUtilities.resourceNameToFile("turtle", "turtle-syntax-bad-number-dot-in-anon.ttl"), false); } @Test public void test_turtle_syntax_bad_pname_01() throws Exception { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/EnableWhenEvaluator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/EnableWhenEvaluator.java index ac72bc588..17fbf0767 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/EnableWhenEvaluator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/EnableWhenEvaluator.java @@ -131,6 +131,9 @@ public class EnableWhenEvaluator { * @return */ public boolean isQuestionEnabled(QuestionnaireItemComponent qitem, QStack qstack) { + if (hasExpressionExtension(qitem)) { + throw new Error("Not Done Yet"); + } if (!qitem.hasEnableWhen()) { return true; } @@ -142,6 +145,12 @@ public class EnableWhenEvaluator { } + private boolean hasExpressionExtension(QuestionnaireItemComponent qitem) { + return qitem.hasExtension("http://phr.kanta.fi/StructureDefinition/fiphr-ext-questionnaire-enablewhen") || // finnish extension + qitem.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression"); // sdc extension + } + + public boolean checkConditionResults(List evaluationResults, QuestionnaireItemComponent questionnaireItem) { if ((questionnaireItem.hasEnableBehavior() && questionnaireItem.getEnableBehavior() == EnableWhenBehavior.ANY) || evaluationResults.size() == 1){ return evaluationResults.stream().anyMatch(EnableWhenResult::isEnabled); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java index 796e09222..1acfca927 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java @@ -3905,7 +3905,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L if (ref != null && !Utilities.noString(reference)) { Element target = resolveInBundle(entries, reference, fullUrl, type, id); - rule(errors, IssueType.INVALID, ref.line(), ref.col(), stack.addToLiteralPath("reference"), target != null, "Unable to resolve the target of the reference in the bundle (" + name + ")"); + rule(errors, IssueType.INVALID, ref.line(), ref.col(), stack.addToLiteralPath("reference"), target != null, "Can't find '"+reference+"' in the bundle (" + name + ")"); } } @@ -3925,13 +3925,47 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L // first entry must be a composition if (rule(errors, IssueType.INVALID, composition.line(), composition.col(), stack.getLiteralPath(), composition.getType().equals("Composition"), "The first entry in a document must be a composition")) { - // the composition subject and section references must resolve in the bundle - Element elem = composition.getNamedChild("subject"); - if (rule(errors, IssueType.INVALID, composition.line(), composition.col(), stack.getLiteralPath(), elem != null, "A document composition must have a subject")) - validateBundleReference(errors, entries, elem, "Composition Subject", stack.push(elem, -1, null, null), fullUrl, "Composition", id); + + // the composition subject etc references must resolve in the bundle + validateDocumentReference(errors, entries, composition, stack, fullUrl, id, false, "subject", "Composition"); + validateDocumentReference(errors, entries, composition, stack, fullUrl, id, true, "author", "Composition"); + validateDocumentReference(errors, entries, composition, stack, fullUrl, id, false, "encounter", "Composition"); + validateDocumentReference(errors, entries, composition, stack, fullUrl, id, false, "custodian", "Composition"); + validateDocumentSubReference(errors, entries, composition, stack, fullUrl, id, "Composition", "attester", false, "party"); + validateDocumentSubReference(errors, entries, composition, stack, fullUrl, id, "Composition", "event", true, "detail"); + validateSections(errors, entries, composition, stack, fullUrl, id); } } + + public void validateDocumentSubReference(List errors, List entries, Element composition, NodeStack stack, String fullUrl, String id, String title, String parent, boolean repeats, String propName) { + List list = new ArrayList<>(); + composition.getNamedChildren(parent, list); + int i = 1; + for (Element elem : list) { + validateDocumentReference(errors, entries, elem, stack.push(elem, i, null, null), fullUrl, id, repeats, propName, title+"."+parent); + i++; + } + } + + public void validateDocumentReference(List errors, List entries, Element composition, NodeStack stack, String fullUrl, String id, boolean repeats, String propName, String title) { + if (repeats) { + List list = new ArrayList<>(); + composition.getNamedChildren(propName, list); + int i = 1; + for (Element elem : list) { + validateBundleReference(errors, entries, elem, title+"."+propName, stack.push(elem, i, null, null), fullUrl, "Composition", id); + i++; + } + + } else { + Element elem = composition.getNamedChild(propName); + if (elem != null) { + validateBundleReference(errors, entries, elem, title+"."+propName, stack.push(elem, -1, null, null), fullUrl, "Composition", id); + } + } + } + // rule(errors, IssueType.INVALID, bundle.line(), bundle.col(), "Bundle", !"urn:guid:".equals(base), "The base 'urn:guid:' is not valid (use urn:uuid:)"); // rule(errors, IssueType.INVALID, entry.line(), entry.col(), localStack.getLiteralPath(), !"urn:guid:".equals(ebase), "The base 'urn:guid:' is not valid"); // rule(errors, IssueType.INVALID, entry.line(), entry.col(), localStack.getLiteralPath(), !Utilities.noString(base) || !Utilities.noString(ebase), "entry @@ -4590,11 +4624,23 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L private void validateSections(List errors, List entries, Element focus, NodeStack stack, String fullUrl, String id) { List sections = new ArrayList(); - focus.getNamedChildren("entry", sections); - int i = 0; + focus.getNamedChildren("section", sections); + int i = 1; for (Element section : sections) { - NodeStack localStack = stack.push(section, 1, null, null); - validateBundleReference(errors, entries, section.getNamedChild("content"), "Section Content", localStack, fullUrl, "Composition", id); + NodeStack localStack = stack.push(section, i, null, null); + + // technically R4+, but there won't be matches from before that + validateDocumentReference(errors, entries, section, stack, fullUrl, id, false, "author", "Section"); + validateDocumentReference(errors, entries, section, stack, fullUrl, id, false, "focus", "Section"); + + List sectionEntries = new ArrayList(); + section.getNamedChildren("entry", sectionEntries); + int j = 1; + for (Element sectionEntry : sectionEntries) { + NodeStack localStack2 = localStack.push(sectionEntry, j, null, null); + validateBundleReference(errors, entries, sectionEntry, "Section Entry", localStack2, fullUrl, "Composition", id); + j++; + } validateSections(errors, entries, section, localStack, fullUrl, id); i++; } diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/Bundle.document.json b/org.hl7.fhir.validation/src/test/resources/validation-examples/Bundle.document.json new file mode 100644 index 000000000..a4e8ee841 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/Bundle.document.json @@ -0,0 +1,641 @@ + + { + "resourceType" : "Bundle", + "id" : "9e11848b-0e37-4bc6-92cf-153b0917cd22", + "identifier" : { + "value" : "889977665544", + "system" : "http://spms.min-saude.pt/SClinico/code" + }, + "type" : "document", + "entry" : [ + { + "fullUrl" : "http://spms.min-saude.pt/fhir/Composition/27eab09d-74bc-4ad3-95b1-d890b7db4c2b", + "resource" : { + "resourceType" : "Composition", + "id" : "27eab09d-74bc-4ad3-95b1-d890b7db4c2b", + "identifier" : { + "system" : "http://spms.min-saude.pt/SClinico/code", + "value" : "889977665544" + }, + "status" : "final", + "type" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "18842-5", + "display" : "Discharge Summary" + } + ] + }, + "subject" : { + "reference" : "Patient/94615767-9ba1-482c-8930-fdda1a0baea8" + }, + "encounter" : { + "reference" : "Encounter/17bcea80-37a6-43ec-a40c-427ab904edd8" + }, + "date" : "2019-10-02T16:48:19.000+00:00", + "author" : [ + { + "reference" : "Practitioner/88b07e2d-73dc-4b87-b1cf-c0d0eddd0e5c" + }, + { + "reference" : "Practitioner/09b68ca1-4088-48bd-9768-1c8bf6118607" + }, + { + "reference" : "Practitioner/ca85c061-8c81-4ff8-8188-cae8d231d872" + }, + { + "reference" : "Practitioner/46d2e8af-e3fb-408d-a042-43c3561291e3" + } + ], + "attester" : [ + { + "mode" : ["personal"], + "party" : { + "reference" : "Practitioner/46d2e8af-e3fb-408d-a042-43c3561291e3" + } + } + ], + "title" : "Nota de alta de internamento", + "custodian" : { + "reference" : "Organization/08748631-6f66-46fd-a8c5-528b574dc33d" + }, + "event" : [ + { + "detail" : [ + { + "reference" : "Encounter/17bcea80-37a6-43ec-a40c-427ab904edd8" + } + ] + } + ], + "section" : [ + { + "title" : "Allergies", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "48765-2", + "display" : "Allergies" + } + ] + }, + "entry" : [ + { + "reference" : "AllergyIntolerance/4f9ad961-d5f1-4888-aa6c-05d003fce450" + } + ] + }, + { + "title" : "Hospital course Narrative", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "8648-8", + "display" : "Hospital course Narrative" + } + ] + }, + "entry" : [ + { + "reference" : "Observation/5da5de2d-93c8-40db-90b6-7d1763fed7f5" + } + ] + }, + { + "title" : "Discharge diagnosis Narrative", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "78375-3", + "display" : "Discharge diagnosis Narrative" + } + ] + }, + "entry" : [ + { + "reference" : "Encounter/17bcea80-37a6-43ec-a40c-427ab904edd8" + } + ] + }, + { + "title" : "Discharge medications Narrative", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "75311-1", + "display" : "Discharge medications Narrative" + } + ] + }, + "entry" : [ + { + "reference" : "MedicationRequest/b684690b-bb71-45b3-9779-88fd89f1d0b5" + } + ] + }, + { + "title" : "Admission diagnosis (narrative)", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "42347-5", + "display" : "Admission diagnosis (narrative)" + } + ] + }, + "entry" : [ + { + "reference" : "Encounter/17bcea80-37a6-43ec-a40c-427ab904edd8" + } + ] + }, + { + "title" : "Medications on admission (narrative)", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "42346-7", + "display" : "Medications on admission (narrative)" + } + ] + }, + "entry" : [ + { + "reference" : "MedicationAdministration/199a4838-e1ba-4408-8ca2-da6a826373da" + }, + { + "reference" : "MedicationAdministration/d6c8c9b2-da4e-4aac-9200-b79b05480402" + }, + { + "reference" : "MedicationAdministration/4db8b223-8c95-4554-9e7f-86906a6c80da" + }, + { + "reference" : "MedicationAdministration/d8adcea3-f539-4dcb-baef-f049bb5eae33" + } + ] + }, + { + "title" : "Discharge diet (narrative)", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "42344-2", + "display" : "Discharge diet (narrative)" + } + ] + }, + "entry" : [ + { + "reference" : "Observation/20b06357-2287-4246-b637-0c0c510ac2d5" + } + ] + }, + { + "title" : "History of Present illness Narrative", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "10164-2", + "display" : "History of Present illness Narrative" + } + ] + }, + "entry" : [ + { + "reference" : "Observation/aaa443d5-222d-4e4b-8291-155750ba9bf6" + } + ] + }, + { + "title" : "Plan of Care", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "18776-5", + "display" : "Plan of care" + } + ] + }, + "section" : [ + { + "title" : "Proposta de monitorização e tratamento", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "PMT", + "display" : "Proposta de monitorização e tratamento" + } + ] + }, + "entry" : [ + { + "reference" : "Observation/cfddbb48-045d-4853-b4f4-e18a2d72701f" + } + ] + }, + { + "title" : "Orientação/agendamentos", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "ORI", + "display" : "Orientação/agendamentos" + } + ] + }, + "entry" : [ + { + "reference" : "Appointment/ac28d16e-0631-4e9b-9bbf-873339010e29" + }, + { + "reference" : "Appointment/b54abdba-8f77-4900-9c79-bda7e0348eed" + }, + { + "reference" : "Appointment/e1574ddd-7a92-42cd-8a6f-733180dd1291" + }, + { + "reference" : "Appointment/5c5af0ca-ccc6-4821-91eb-ef32b7d483e6" + }, + { + "reference" : "Appointment/42e5f192-32aa-4eb2-a90e-7e3ff2f8d701" + }, + { + "reference" : "Appointment/c960cc20-15fb-4ef9-867d-d13c96750ea8" + }, + { + "reference" : "Appointment/f1d8748c-057e-437b-a8b2-5f7642250e5e" + } + ] + }, + { + "title" : "Meios complementares de diagnóstico marcados", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "MCDTM", + "display" : "Meios complementares de diagnóstico marcados" + } + ] + }, + "emptyReason" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list-empty-reason", + "code" : "not-found", + "display" : "Not Found" + } + ], + "text" : "Não foram encontrados registos para este utente" + } + } + ] + }, + { + "title" : "Functional status assessment note", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "47420-5", + "display" : "Functional status assessment note" + } + ] + }, + "section" : [ + { + "title" : "Focos de diagnóstico de enfermagem", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "FDE", + "display" : "Focos de diagnóstio de enfermagem" + } + ] + }, + "entry" : [ + { + "reference" : "Condition/3d4dcb01-5e84-4de3-bfd1-2c7a873acd74" + } + ] + }, + { + "title" : "Atitudes Terapêuticas", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "ATI", + "display" : "Atitudes terapêuticas" + } + ] + }, + "entry" : [ + { + "reference" : "Procedure/1cdba079-e745-4ff3-bfd6-6fae81238be8" + }, + { + "reference" : "Procedure/42077cf6-64c0-4309-ab0d-bb1859da03ae" + }, + { + "reference" : "Procedure/85b5f07c-f1cf-4038-be23-5ad2b9d89e92" + }, + { + "reference" : "Procedure/2afedeb5-0c0f-4e0a-a506-93f03c8bd382" + } + ] + } + ] + }, + { + "title" : "History of Procedures Document", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "47519-4", + "display" : "History of Procedures Document" + } + ] + }, + "section" : [ + { + "title" : "Dispositivos implantáveis", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "DIS", + "display" : "Dispositivos implantáveis" + } + ] + }, + "entry" : [ + { + "reference" : "Device/5b237d94-0ae3-49a2-9a8a-ef39607cc68d" + } + ] + }, + { + "title" : "Intervenções Cirúrgicas", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "INT", + "display" : "Intervenções cirúrgicas" + } + ] + }, + "entry" : [ + { + "reference" : "Procedure/59b211c5-32aa-4c28-91df-d81de43b1bd1" + } + ] + }, + { + "title" : "Ventilação Mecânica", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "VEN", + "display" : "Ventilação mecânica" + } + ] + }, + "entry" : [ + { + "reference" : "Procedure/ce38198b-f2e1-4625-85d7-5c58a9eb8c94" + }, + { + "reference" : "Procedure/4a42b0a8-d198-42fc-9658-d24a2214fc8d" + }, + { + "reference" : "Procedure/0ee5087f-d047-453a-afdc-d6eccba2d2df" + } + ] + }, + { + "title" : "Infeção nosocomial", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "INF", + "display" : "Infeção nosocomial" + } + ] + }, + "entry" : [ + { + "reference" : "Procedure/a96a4c64-976a-42e5-938a-f54b844e07b0" + }, + { + "reference" : "Procedure/b18f9160-91eb-4d19-b7d2-25dc4e66cc2c" + } + ] + }, + { + "title" : "Meios complementares de diagnósticos efetuados", + "code" : { + "coding" : [ + { + "system" : "http://spms.min-saude.pt/valueset-list", + "code" : "MCDTE", + "display" : "Meios complementares de diagnósticos efetuados" + } + ] + }, + "entry" : [ + { + "reference" : "ProcedureRequest/47d0cf17-65aa-4f65-abb0-1f4e4cf53f35" + }, + { + "reference" : "ProcedureRequest/e8814151-03c6-4f85-9caf-a8ea606acb5c" + }, + { + "reference" : "ProcedureRequest/1b1ae576-fae6-425c-a85b-78e222b269f7" + }, + { + "reference" : "ProcedureRequest/7ed52dda-afde-4b4a-bb60-0b5600d598bd" + }, + { + "reference" : "ProcedureRequest/8a426c75-119e-441e-bfea-55fdc50118ba" + }, + { + "reference" : "ProcedureRequest/82a006cd-939b-4dde-8982-5f875ed862cc" + }, + { + "reference" : "ProcedureRequest/cc8b9f10-cd3b-4240-8352-b8346cf48205" + }, + { + "reference" : "ProcedureRequest/8b7fbb19-5ca1-4f47-8b0b-6fedcc543b5f" + }, + { + "reference" : "ProcedureRequest/c8e08048-0c43-42b9-a611-6c92705a910d" + }, + { + "reference" : "ProcedureRequest/26587c9f-5041-4313-ac03-ab8feda7951a" + }, + { + "reference" : "ProcedureRequest/d65a5ce6-97fe-4959-9660-6c096d70b3a1" + }, + { + "reference" : "ProcedureRequest/018aea83-70f9-44db-908b-bd8a0f475cd3" + }, + { + "reference" : "ProcedureRequest/3346f637-c83f-4a3f-a82d-fbfce6286f3d" + }, + { + "reference" : "ProcedureRequest/38ca8f90-71b2-44d9-a6cb-97aaf2df8781" + }, + { + "reference" : "ProcedureRequest/c9320c07-569c-413f-8ffa-ef0fdaacac23" + }, + { + "reference" : "ProcedureRequest/b4c2ec41-e1fe-43be-9ea4-97f34deca878" + }, + { + "reference" : "ProcedureRequest/921f8560-5eb5-46fa-8dcd-0972756f5880" + }, + { + "reference" : "ProcedureRequest/7de5bf65-09a5-4be8-8edb-9e909296e8e0" + }, + { + "reference" : "ProcedureRequest/ff40f491-2a57-44ee-be62-19c63a5e5481" + }, + { + "reference" : "ProcedureRequest/a2c80ea2-9b8d-46ce-a846-1b5b6a98d2a6" + }, + { + "reference" : "ProcedureRequest/c9daa080-ef42-4b67-b252-566c4a334f81" + }, + { + "reference" : "ProcedureRequest/206615ca-448a-418f-a287-96cb9e4ba4c4" + }, + { + "reference" : "ProcedureRequest/307bc183-46fc-44f5-930d-af9602573204" + }, + { + "reference" : "ProcedureRequest/a8ae7ec5-e2e4-402b-b578-4f52de17865f" + }, + { + "reference" : "ProcedureRequest/43dd4257-cd53-4cba-a851-beec3730c98f" + } + ] + } + ] + }, + { + "title" : "Review of systems Narrative - Reporte", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "10187-3", + "display" : "Review of systems Narrative Reporte" + } + ] + }, + "entry" : [ + { + "reference" : "Observation/74f5c1f7-e6d9-4cac-bff8-5f22bbbdd501" + }, + { + "reference" : "Observation/5957c0e2-ad3c-43e0-b45e-c002d2b45f05" + } + ] + }, + { + "title" : "Administrative information", + "code" : { + "coding" : [ + { + "system" : "http://loinc.org", + "code" : "87504-7", + "display" : "Administrative information" + } + ] + }, + "entry" : [ + { + "reference" : "Patient/94615767-9ba1-482c-8930-fdda1a0baea8" + }, + { + "reference" : "Encounter/17bcea80-37a6-43ec-a40c-427ab904edd8" + }, + { + "reference" : "List/0f1eedb7-9d71-456b-b228-e910a9723dd6" + } + ] + } + ] + } + }, + { + "fullUrl" : "http://spms.min-saude.pt/fhir/Patient/94615767-9ba1-482c-8930-fdda1a0baea8", + "resource" : { + "resourceType" : "Patient", + "id" : "94615767-9ba1-482c-8930-fdda1a0baea8", + "identifier" : [ + { + "type" : { + "coding" : [ + { + "system" : "http://hl7.org/fhir/v2/0203", + "code" : "HC", + "display" : "Health Card Number" + } + ], + "text" : "NNU" + }, + "system" : "http://spms.min-saude.pt/rnu/identifiers/patient-id", + "value" : "383816471" + }, + { + "type" : { + "coding" : [ + { + "system" : "http://hl7.org/fhir/v2/0203", + "code" : "MR", + "display" : "Medical Record Number" + } + ], + "text" : "Número do Processo" + }, + "system" : "https://www.sns.gov.pt/hospitalfacilities/1137006/identifiers/patient-id", + "value" : "99149257" + } + ], + "name" : [ + { + "text" : "MARTIM RICARDO FERREIRA", + "given" : [ + "RICARDO", + "FERREIRA" + ], + "family" : "MARTIM" + } + ], + "gender" : "male", + "birthDate" : "1943-11-24" + + + } + } + ] + } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json b/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json index 2eafd7a77..88c940216 100644 --- a/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json @@ -200,6 +200,11 @@ }, "fhirpath-null.json": { "errorCount": 1 + }, + "Bundle.document.json": { + "version" : "3.0", + "errorCount": 68, + "errors-for-debugging" : ["68 errors to do with things not found in the bundle"], }, "qr-ex.json": { "questionnaire": "q-ex.json", @@ -653,6 +658,18 @@ "questionnaire": "questionnaire-enableWhen-test.xml", "errorCount": 0 }, + "questionnaireResponse-enableWhen-test-fail.xml": { + "questionnaire": "questionnaire-enableWhen-test.xml", + "errorCount": 1 + }, + "questionnaireResponse-enableWhenEx-test.xml": { + "questionnaire": "questionnaire-enableWhenEx-test.xml", + "errorCount": 0 + }, + "questionnaireResponse-enableWhenEx-test-fail.xml": { + "questionnaire": "questionnaire-enableWhenEx-test.xml", + "errorCount": 1 + }, "questionnaireResponse-enableWhen-test-nested.xml": { "questionnaire": "questionnaire-enableWhen-test-nested.xml", "errorCount": 2 diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaire-enableWhenEx-test.xml b/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaire-enableWhenEx-test.xml new file mode 100644 index 000000000..5e14b4c2b --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaire-enableWhenEx-test.xml @@ -0,0 +1,30 @@ + + + + + + +
+

enableWhen test

+
+
+ + + + + + + + + + + + + + + + + + + +
diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaireResponse-enableWhen-test-fail.xml b/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaireResponse-enableWhen-test-fail.xml new file mode 100644 index 000000000..cc59de5b8 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaireResponse-enableWhen-test-fail.xml @@ -0,0 +1,26 @@ + + + + + +
+

enableWhen test response

+
+
+ + + + + + + + + + + + + + + + +
diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaireResponse-enableWhenEx-test-fail.xml b/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaireResponse-enableWhenEx-test-fail.xml new file mode 100644 index 000000000..896b5f990 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaireResponse-enableWhenEx-test-fail.xml @@ -0,0 +1,26 @@ + + + + + +
+

enableWhen test response

+
+
+ + + + + + + + + + + + + + + + +
diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaireResponse-enableWhenEx-test.xml b/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaireResponse-enableWhenEx-test.xml new file mode 100644 index 000000000..7435cabbf --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/questionnaireResponse-enableWhenEx-test.xml @@ -0,0 +1,26 @@ + + + + + +
+

enableWhen test response

+
+
+ + + + + + + + + + + + + + + + +