diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/fhirpath/FHIRPathEngine.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/fhirpath/FHIRPathEngine.java index 17ab4ac3a..956ee8cad 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/fhirpath/FHIRPathEngine.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/fhirpath/FHIRPathEngine.java @@ -2735,7 +2735,7 @@ public class FHIRPathEngine { if (right.size() > 1) { throw makeExceptionPlural(right.size(), expr, I18nConstants.FHIRPATH_RIGHT_VALUE, "+"); } - if (!right.get(0).isPrimitive() && !((left.get(0).isDateTime() || "0".equals(left.get(0).primitiveValue()) || left.get(0).hasType("Quantity")) && right.get(0).hasType("Quantity"))) { + if (!right.get(0).isPrimitive() && !((left.get(0).isDateTime() || left.get(0).hasType("Date") || "0".equals(left.get(0).primitiveValue()) || left.get(0).hasType("Quantity")) && right.get(0).hasType("Quantity"))) { throw makeException(expr, I18nConstants.FHIRPATH_RIGHT_VALUE_WRONG_TYPE, "+", right.get(0).fhirType()); } @@ -2748,8 +2748,9 @@ public class FHIRPathEngine { result.add(new IntegerType(Integer.parseInt(l.primitiveValue()) + Integer.parseInt(r.primitiveValue()))); } else if (l.hasType("decimal", "integer") && r.hasType("decimal", "integer")) { result.add(new DecimalType(new BigDecimal(l.primitiveValue()).add(new BigDecimal(r.primitiveValue())))); - } else if (l.isDateTime() && r.hasType("Quantity")) { - result.add(dateAdd((BaseDateTimeType) l, (Quantity) r, false, expr)); + } else if ((l.isDateTime() || l.hasType("Date")) && r.hasType("Quantity")) { + DateTimeType dl = l instanceof DateTimeType ? (DateTimeType) l : new DateTimeType(l.primitiveValue()); + result.add(dateAdd(dl, (Quantity) r, false, expr)); } else { throw makeException(expr, I18nConstants.FHIRPATH_OP_INCOMPATIBLE, "+", left.get(0).fhirType(), right.get(0).fhirType()); } @@ -2994,7 +2995,7 @@ public class FHIRPathEngine { if (right.size() > 1) { throw makeExceptionPlural(right.size(), expr, I18nConstants.FHIRPATH_RIGHT_VALUE, "-"); } - if (!right.get(0).isPrimitive() && !((left.get(0).isDateTime() || "0".equals(left.get(0).primitiveValue()) || left.get(0).hasType("Quantity")) && right.get(0).hasType("Quantity"))) { + if (!right.get(0).isPrimitive() && !((left.get(0).isDateTime() || left.get(0).hasType("Date") || "0".equals(left.get(0).primitiveValue()) || left.get(0).hasType("Quantity")) && right.get(0).hasType("Quantity"))) { throw makeException(expr, I18nConstants.FHIRPATH_RIGHT_VALUE_WRONG_TYPE, "-", right.get(0).fhirType()); } @@ -3012,8 +3013,9 @@ public class FHIRPathEngine { Quantity qty = (Quantity) r; result.add(qty.copy().setValue(qty.getValue().abs())); } - } else if (l.isDateTime() && r.hasType("Quantity")) { - result.add(dateAdd((BaseDateTimeType) l, (Quantity) r, true, expr)); + } else if ((l.isDateTime() || l.hasType("Date")) && r.hasType("Quantity")) { + DateTimeType dl = l instanceof DateTimeType ? (DateTimeType) l : new DateTimeType(l.primitiveValue()); + result.add(dateAdd(dl, (Quantity) r, true, expr)); } else { throw makeException(expr, I18nConstants.FHIRPATH_OP_INCOMPATIBLE, "-", left.get(0).fhirType(), right.get(0).fhirType()); } diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/StructureMapUtilitiesTest.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/StructureMapUtilitiesTest.java index bec404a62..a5e1c1279 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/StructureMapUtilitiesTest.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/StructureMapUtilitiesTest.java @@ -1,5 +1,7 @@ package org.hl7.fhir.r5.test; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.io.IOException; import java.util.List; @@ -56,6 +58,19 @@ public class StructureMapUtilitiesTest implements ITransformerServices { Assertions.assertEquals("2147483647",fp.evaluateToString(target, "extension[2].value")); Assertions.assertEquals("2147483647",fp.evaluateToString(target, "extension[3].value")); } + + @Test + public void testDateOpVariables() throws IOException, FHIRException { + StructureMapUtilities scu = new StructureMapUtilities(context, this); + String fileMap = TestingUtilities.loadTestResource("r5", "structure-mapping", "qr2patfordates.map"); + Element source = Manager.parseSingle(context, TestingUtilities.loadTestResourceStream("r5", "structure-mapping", "qrext.json"), FhirFormat.JSON); + StructureMap structureMap = scu.parse(fileMap, "qr2patfordates"); + Element target = Manager.build(context, scu.getTargetType(structureMap)); + scu.transform(null, source, structureMap, target); + FHIRPathEngine fp = new FHIRPathEngine(context); + assertEquals("2023-10-26", fp.evaluateToString(target, "birthDate")); + assertEquals("2023-09-20T13:19:13.502Z", fp.evaluateToString(target, "deceased")); + } private void assertSerializeDeserialize(StructureMap structureMap) { Assertions.assertEquals("syntax", structureMap.getName());