diff --git a/src/main/java/com/medblocks/openfhir/tofhir/IntermediateCacheProcessing.java b/src/main/java/com/medblocks/openfhir/tofhir/IntermediateCacheProcessing.java index 80445eb3..83c22b18 100644 --- a/src/main/java/com/medblocks/openfhir/tofhir/IntermediateCacheProcessing.java +++ b/src/main/java/com/medblocks/openfhir/tofhir/IntermediateCacheProcessing.java @@ -222,23 +222,23 @@ private void handlePopulationNoParent(final FhirInstanceCreator.InstantiateAndSe final String fullOpenEhrPath, final String followedByParentOpenEhr, final boolean lastOpenEhrIsDigit) { + final String fhirPath = path + (StringUtils.isEmpty(hardcodedReturn.getPath()) ? "" : ("." + hardcodedReturn.getPath())); if (hardcodedReturn.isList()) { final String openEhrPath = lastOpenEhrIsDigit ? fullOpenEhrPath.substring(0, fullOpenEhrPath.lastIndexOf(":")) : fullOpenEhrPath; // puts in the list - instantiatedIntermediateElements.put(createKeyForIntermediateElements(objectRef, path + "." + hardcodedReturn.getPath(), openEhrPath), + instantiatedIntermediateElements.put(createKeyForIntermediateElements(objectRef, fhirPath, openEhrPath), hardcodedReturn.getReturning()); - final Integer lastIndex = openFhirStringUtils.getLastIndex(fullOpenEhrPath); final List returningList = (List) hardcodedReturn.getReturning(); if (lastOpenEhrIsDigit) { final Object toAddToCache = returningList.get(returningList.size() - 1); // todo: always takes the last one, is this ok? - instantiatedIntermediateElements.put(createKeyForIntermediateElements(objectRef, path + "." + hardcodedReturn.getPath(), - fullOpenEhrPath), + instantiatedIntermediateElements.put(createKeyForIntermediateElements(objectRef, fhirPath, + fullOpenEhrPath), toAddToCache); } } else { - instantiatedIntermediateElements.put(createKeyForIntermediateElements(objectRef, path + "." + hardcodedReturn.getPath(), fullOpenEhrPath), + instantiatedIntermediateElements.put(createKeyForIntermediateElements(objectRef, fhirPath, fullOpenEhrPath), hardcodedReturn.getReturning()); } @@ -247,7 +247,7 @@ private void handlePopulationNoParent(final FhirInstanceCreator.InstantiateAndSe populateIntermediateCache(hardcodedReturn.getInner(), objectRef, instantiatedIntermediateElements, - path + "." + hardcodedReturn.getPath(), + fhirPath, fullOpenEhrPath, null, followedByParentOpenEhr); diff --git a/src/main/java/com/medblocks/openfhir/tofhir/OpenEhrToFhir.java b/src/main/java/com/medblocks/openfhir/tofhir/OpenEhrToFhir.java index 7aa06e74..17c3e504 100644 --- a/src/main/java/com/medblocks/openfhir/tofhir/OpenEhrToFhir.java +++ b/src/main/java/com/medblocks/openfhir/tofhir/OpenEhrToFhir.java @@ -1053,11 +1053,16 @@ void prepareOpenEhrToFhirHelpers(final OpenFhirFhirConnectModelMapper theMapper, } String fixedOpenEhr = definedMappingWithOpenEhr - .replace(FhirConnectConst.REFERENCE, "") .replace(FhirConnectConst.REFERENCE + "/", "") + .replace(FhirConnectConst.REFERENCE, "") .replace(OPENEHR_ARCHETYPE_FC, firstFlatPath) .replace(OPENEHR_COMPOSITION_FC, webTemplate.getTree().getId()); - String openehrAqlPath = mappingRootElement && !definedMappingWithOpenEhr.startsWith(OPENEHR_COMPOSITION_FC) ? firstFlatPath : getOpenEhrKey(fixedOpenEhr, parentFollowedByOpenEhr, firstFlatPath); + if (mapping.getReference() != null) { + mapping.getWith().setType(OPENEHR_TYPE_NONE); + } + String openehrAqlPath = + mappingRootElement && !definedMappingWithOpenEhr.startsWith(OPENEHR_COMPOSITION_FC) ? firstFlatPath + : getOpenEhrKey(fixedOpenEhr, parentFollowedByOpenEhr, firstFlatPath); String openehr = getPathFromAqlPath(openehrAqlPath, webTemplate, mapping.getWith().getType()); String parentFollowedByOpenEhrWithOutAqlPath = null; if (parentFollowedByOpenEhr != null) { @@ -1170,8 +1175,10 @@ private void prepareOpenEhrCondition(final Condition openEhrCondition, final String newAttribute = formattedOpenEhrConditionAttribute + openFhirMapperUtils.replaceAqlSuffixWithFlatSuffix( openEhrConditionTargetAttributeWithAqlPath); - if (newAttribute.startsWith(openEhrCondition.getTargetRoot())) { + if (newAttribute.startsWith(openEhrCondition.getTargetRoot() + "/")) { newAttributes.add(newAttribute.replace(openEhrCondition.getTargetRoot() + "/", "")); + } else if (newAttribute.startsWith(openEhrCondition.getTargetRoot())) { + newAttributes.add(newAttribute.replace(openEhrCondition.getTargetRoot(), "")); } else { newAttributes.add(newAttribute); } @@ -1356,6 +1363,19 @@ private void handleReferenceMapping(final Mapping mapping, final String resource final String wConditions = openFhirStringUtils.getFhirPathWithConditions(mapping.getWith().getFhir(), mapping.getFhirCondition(), resourceType, parentFollowedByFhir); + + // if it's a referenced mapping, we need to add this so it adds reference to the intermediateCache under the right cache key + final Mapping staticMapping = new Mapping(); + staticMapping.setName("staticMapping"); + final With with = new With(); + with.setFhir("$fhirRoot"); + with.setOpenehr(referencedMapping.get(0).getWith().getOpenehr()); + with.setValue("openFhirDontPopulate"); + staticMapping.setWith(with); + staticMapping.setFhirCondition(mapping.getFhirCondition()); + referencedMapping.add(0, staticMapping); + + openFhirMapperUtils.prepareReferencedMappings(wConditions, openehr, referencedMapping, firstFlatPath); // now conditions @@ -1450,36 +1470,8 @@ private List extractValues(final Mapping mapp List values = new ArrayList<>(); if (!OPENEHR_TYPE_NONE.equals(mapping.getWith().getType())) { if (StringUtils.isNotEmpty(hardcodedValue) && !joinedEntries.isEmpty()) { - values = new ArrayList<>(); - final Condition openehrCondition = mapping.getOpenehrCondition(); - final String fullOpenEhrPath; - if (openehrCondition == null) { - fullOpenEhrPath = OPENEHR_ARCHETYPE_FC; - } else { - final List targetAttributes = mapping.getOpenehrCondition().getTargetAttributes(); - final String targetRoot = mapping.getOpenehrCondition().getTargetRoot(); -// final String rootWithAttrs = targetRoot + ((targetAttributes != null && !targetAttributes.isEmpty()) ? "" : ("/" + targetAttributes.get(0))); - final String piped = openFhirStringUtils.addRegexPatternToSimplifiedFlatFormat(targetRoot); - final List allEntriesThatMatch = openFhirStringUtils.getAllEntriesThatMatch(piped, - flatJsonObject); - fullOpenEhrPath = allEntriesThatMatch.get(0); - } - int index = getHardcodedIndex(mapping, flatJsonObject); - if (index == -1) { - // get outer most index of all indexes in flatJsonObject that is the same for all entries, because - // while -1 means it has to be for all entries, it more than that means it has to be for all entries - // on the currently evaluated items! - index = openFhirStringUtils.getLastMostCommonIndex(new ArrayList<>(flatJsonObject.keySet())); - } - values.add(new OpenEhrToFhirHelper.DataWithIndex(new StringType(hardcodedValue), index, - fullOpenEhrPath)); - } - // TO DO : Program mapping from openEHR to FHIR - // else if(mapping.getMappingCode()!=null){ - - // } - - else { + handleHardcodedMappings(values, mapping, flatJsonObject, joinedEntries, hardcodedValue); + } else { values = joinedEntries.values().stream() .map(strings -> valueToDataPoint(strings, rmType, flatJsonObject, true)) .filter(Objects::nonNull) @@ -1500,6 +1492,44 @@ private List extractValues(final Mapping mapp return values; } + private void handleHardcodedMappings(final List values, + final Mapping mapping, final JsonObject flatJsonObject, + final Map> joinedEntries, + final String hardcodedValue) { + + final Condition openehrCondition = mapping.getOpenehrCondition(); + final String fullOpenEhrPath; + if (openehrCondition == null) { + fullOpenEhrPath = OPENEHR_ARCHETYPE_FC; + } else { + final String targetRoot = mapping.getOpenehrCondition().getTargetRoot(); + final String piped = openFhirStringUtils.addRegexPatternToSimplifiedFlatFormat(targetRoot); + final List allEntriesThatMatch = openFhirStringUtils.getAllEntriesThatMatch(piped, + flatJsonObject); + fullOpenEhrPath = allEntriesThatMatch.get(0); + } + int index = getHardcodedIndex(mapping, flatJsonObject); + + if (index == -1) { + // get outer most index of all indexes in flatJsonObject that is the same for all entries, because + // while -1 means it has to be for all entries, it more than that means it has to be for all entries + // on the currently evaluated items! + index = openFhirStringUtils.getLastMostCommonIndex(new ArrayList<>(flatJsonObject.keySet())); + } + + if (openehrCondition == null) { + joinedEntries.keySet().forEach(key -> { + final Integer lastIndex = openFhirStringUtils.getLastIndex(key); + values.add(new OpenEhrToFhirHelper.DataWithIndex(new StringType(hardcodedValue), + lastIndex, + key)); + }); + } else { + values.add(new OpenEhrToFhirHelper.DataWithIndex(new StringType(hardcodedValue), index, + fullOpenEhrPath)); + } + } + private int getHardcodedIndex(final Mapping mapping, final JsonObject flatJsonObject) { if (mapping.getOpenehrCondition() == null) { return -1; // goes for all anyway diff --git a/src/main/java/com/medblocks/openfhir/util/FhirInstancePopulator.java b/src/main/java/com/medblocks/openfhir/util/FhirInstancePopulator.java index 8ecb494a..e463dca9 100644 --- a/src/main/java/com/medblocks/openfhir/util/FhirInstancePopulator.java +++ b/src/main/java/com/medblocks/openfhir/util/FhirInstancePopulator.java @@ -77,11 +77,17 @@ private void populateListElement(List toPopulate, Base data) { if (lastElement.toString() == null || objectIsEmpty(lastElement)) { populateElement(lastElement, data); // Populate last element if empty } else { + if (data instanceof StringType && "openFhirDontPopulate".equals(((StringType) data).getValueAsString())) { + return; + } ((List) toPopulate).add(data); // Otherwise, add new entry } } private void handleSpecificTypePopulation(final Object toPopulate, final Base data) { + if (data instanceof StringType && "openFhirDontPopulate".equals(((StringType) data).getValueAsString())) { + return; + } if (data instanceof Quantity) { populateQuantity(toPopulate, (Quantity) data); } else if (data instanceof IntegerType) { diff --git a/src/main/java/com/medblocks/openfhir/util/OpenEhrConditionEvaluator.java b/src/main/java/com/medblocks/openfhir/util/OpenEhrConditionEvaluator.java index 2dd10e99..443b61ac 100644 --- a/src/main/java/com/medblocks/openfhir/util/OpenEhrConditionEvaluator.java +++ b/src/main/java/com/medblocks/openfhir/util/OpenEhrConditionEvaluator.java @@ -10,6 +10,7 @@ import java.util.Set; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -73,14 +74,17 @@ private JsonObject handleOneOfOperatorSplit(final Condition openEhrCondition, final JsonObject modifiedJsonObject = new JsonObject(); final Set notAddingForThisCondition = new HashSet<>(); for (final String extractedValueKey : extractedValueKeys) { - final String preparedTargetAttribute = openFhirStringUtils.prepareOpenEhrSyntax( - targetAttribute, - ""); - final String openEhrKey = preparedTargetAttribute == null ? extractedValueKey : String.format("%s/%s", extractedValueKey, preparedTargetAttribute); - final JsonPrimitive extractedValueJson = fullFlatPath.getAsJsonPrimitive(openEhrKey); + + final boolean subPath = targetAttribute.startsWith("|"); + if(subPath && !extractedValueKey.endsWith(targetAttribute)){ + // wrong subpath to check for + continue; + } + final String keyToCheckFor = subPath ? extractedValueKey : extractedValueKey + "/" + targetAttribute; + final JsonPrimitive extractedValueJson = fullFlatPath.getAsJsonPrimitive(keyToCheckFor); final String extractedValue = extractedValueJson == null ? "" : extractedValueJson.getAsString(); - if (openEhrCondition.getCriteria().contains(extractedValue)) { + if (StringUtils.isNotEmpty(extractedValue) && openEhrCondition.getCriteria().contains(extractedValue)) { fullFlatPath.entrySet().forEach((entry) -> { if (entry.getKey().startsWith(extractedValueKey)) { modifiedJsonObject.add(entry.getKey(), entry.getValue()); @@ -91,7 +95,7 @@ private JsonObject handleOneOfOperatorSplit(final Condition openEhrCondition, log.info( "Flat path {} evaluated to {}, condition.criteria requires it to be {}, therefore excluding all {} from mapping.", - openEhrKey, extractedValue, openEhrCondition.getCriteria(), extractedValueKey); + extractedValueKey, extractedValue, openEhrCondition.getCriteria(), extractedValueKey); notAddingForThisCondition.add(extractedValueKey); fullFlatPath.entrySet().forEach((entry) -> { diff --git a/src/main/java/com/medblocks/openfhir/util/OpenFhirMapperUtils.java b/src/main/java/com/medblocks/openfhir/util/OpenFhirMapperUtils.java index 9995a886..b40ff752 100644 --- a/src/main/java/com/medblocks/openfhir/util/OpenFhirMapperUtils.java +++ b/src/main/java/com/medblocks/openfhir/util/OpenFhirMapperUtils.java @@ -318,7 +318,7 @@ public void prepareFollowedByMappings(final List followedByMappings, .replace(FhirConnectConst.OPENEHR_ARCHETYPE_FC + ".", "") .replace(FhirConnectConst.OPENEHR_ARCHETYPE_FC, "")); } else if (conditionRoot.equals(FhirConnectConst.OPENEHR_ARCHETYPE_FC)) { - openehrCondition.setTargetRoot(openehr); + openehrCondition.setTargetRoot(slotContext); } else { openehrCondition.setTargetRoot( new OpenFhirStringUtils().prepareOpenEhrSyntax(conditionRoot, diff --git a/src/test/java/com/medblocks/openfhir/kds/DiagnoseTest.java b/src/test/java/com/medblocks/openfhir/kds/DiagnoseTest.java index 7f32e83c..8584cdfd 100644 --- a/src/test/java/com/medblocks/openfhir/kds/DiagnoseTest.java +++ b/src/test/java/com/medblocks/openfhir/kds/DiagnoseTest.java @@ -136,9 +136,17 @@ private void assertCondition(final Condition condition, final boolean second) { // - name: "mehrfachcodierung" final CodeableConcept mehrfachcodierung = (CodeableConcept) icd10code.getExtensionByUrl( "http://fhir.de/StructureDefinition/icd-10-gm-mehrfachcodierungs-kennzeichen").getValue(); - Assert.assertEquals("!", mehrfachcodierung.getCodingFirstRep().getCode()); + + if(second) { + Assert.assertEquals("*", mehrfachcodierung.getCodingFirstRep().getCode()); + Assert.assertEquals("*", mehrfachcodierung.getCodingFirstRep().getDisplay()); + } else { + Assert.assertEquals("†", mehrfachcodierung.getCodingFirstRep().getCode()); // because openEhr condition says if it's 'at0002' it needs to be † and flatpath of diagnose/diagnose:0/mehrfachkodierungskennzeichen_icd-10-gm/mehrfachkodierungkennzeichen|code is at0002 + Assert.assertEquals("†", mehrfachcodierung.getCodingFirstRep().getDisplay()); + } + Assert.assertEquals("http://fhir.de/ValueSet/icd-10-gm-mehrfachcodierungs-kennzeichen", mehrfachcodierung.getCodingFirstRep().getSystem()); - Assert.assertEquals("!", mehrfachcodierung.getCodingFirstRep().getDisplay()); + // - name: "seitenlokalisation" final CodeableConcept seitenlokalisation = (CodeableConcept) icd10code.getExtensionByUrl( @@ -165,16 +173,7 @@ public void toFhir() { final Condition conditionSecond = (Condition) allConditions.get(1).getResource(); // second condition assertCondition(condition, false); -// assertCondition(conditionSecond, true); - - final Type referencedExtensionCondition = condition.getExtensionByUrl( - "http://hl7.org/fhir/StructureDefinition/condition-related") - .getValue(); - Assert.assertNotNull(referencedExtensionCondition); - Assert.assertTrue(conditionSecond.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/condition-related") - .getValue().isEmpty()); - - assertCondition((Condition) ((Reference) referencedExtensionCondition).getResource(), true); + assertCondition(conditionSecond, true); } diff --git a/src/test/java/com/medblocks/openfhir/kds/StudienteilnahmeTest.java b/src/test/java/com/medblocks/openfhir/kds/StudienteilnahmeTest.java index 3d45a17a..1940d136 100644 --- a/src/test/java/com/medblocks/openfhir/kds/StudienteilnahmeTest.java +++ b/src/test/java/com/medblocks/openfhir/kds/StudienteilnahmeTest.java @@ -47,7 +47,7 @@ public void toFhir() { final Consent consent = (Consent) allConsents.get(0).getResource(); - Assert.assertEquals("entered-in-error", consent.getStatusElement().getValueAsString()); + Assert.assertEquals("stopped", consent.getStatusElement().getValueAsString()); // - name: "period" final DateTimeType periodStart = consent.getProvision().getPeriod().getStartElement(); diff --git a/src/test/resources/kds/diagnose/KDS_Diagnose_multiple_Composition.flat.json b/src/test/resources/kds/diagnose/KDS_Diagnose_multiple_Composition.flat.json index e72bd7e2..126e0bdd 100644 --- a/src/test/resources/kds/diagnose/KDS_Diagnose_multiple_Composition.flat.json +++ b/src/test/resources/kds/diagnose/KDS_Diagnose_multiple_Composition.flat.json @@ -84,9 +84,9 @@ "diagnose/diagnose:1/lebensphase/ende|code": "referenced_44", "diagnose/diagnose:1/lebensphase/ende|value": "referenced_No example for termínology '//fhir.hl7.org//ValueSet/$expand?url=http://fhir.de/ValueSet/lebensphase-de' available", "diagnose/diagnose:1/lebensphase/ende|terminology": "referenced_//fhir.hl7.org//ValueSet/$expand?url=http://fhir.de/ValueSet/lebensphase-de", - "diagnose/diagnose:1/mehrfachkodierungskennzeichen_icd-10-gm/mehrfachkodierungkennzeichen|value": "referenced_†", - "diagnose/diagnose:1/mehrfachkodierungskennzeichen_icd-10-gm/mehrfachkodierungkennzeichen|code": "referenced_at0002", - "diagnose/diagnose:1/mehrfachkodierungskennzeichen_icd-10-gm/mehrfachkodierungkennzeichen|terminology": "referenced_local", + "diagnose/diagnose:1/mehrfachkodierungskennzeichen_icd-10-gm/mehrfachkodierungkennzeichen|value": "*", + "diagnose/diagnose:1/mehrfachkodierungskennzeichen_icd-10-gm/mehrfachkodierungkennzeichen|code": "at0003", + "diagnose/diagnose:1/mehrfachkodierungskennzeichen_icd-10-gm/mehrfachkodierungkennzeichen|terminology": "local", "diagnose/diagnose:1/klinisch_relevanter_zeitraum_zeitpunkt_der_genesung": "3022-02-03T04:05:06", "diagnose/diagnose:1/klinischer_status/diagnosestatus|code": "at0088", "diagnose/diagnose:1/klinischer_status/diagnosestatus|terminology": "local", diff --git a/src/test/resources/kds_new/model/action/org.openehr/informed_consent.v0.yml b/src/test/resources/kds_new/model/action/org.openehr/informed_consent.v0.yml index efe91bd0..4c64e3b8 100644 --- a/src/test/resources/kds_new/model/action/org.openehr/informed_consent.v0.yml +++ b/src/test/resources/kds_new/model/action/org.openehr/informed_consent.v0.yml @@ -166,7 +166,27 @@ mappings: operator: "one of" criteria: "528" - + - name: "aborted" + fhir: + - path: "status" + value: "stopped" + openehrCondition: + targetRoot: "$openehrRoot" + targetAttribute: "defining_code/code_string" + operator: "one of" + criteria: "531" + openehr: + - path: "defining_code/terminology_id" + value: "openehr" + - path: "value" + value: "Aborted" + - path: "defining_code/code_string" + value: "531" + fhirCondition: + targetRoot: "$fhirRoot" + targetAttribute: "status" + operator: "one of" + criteria: "stopped" - name: "study" with: