Repository: FHIR/sushi (ts)

Issue:
Quantity with units: Zero (0) value is omitted in instances
Hi,

sushi v2.1.1 does not write a valueQuantity.value 0 to an instance when using the "short syntax":

Consider the following 2 examples:
```
Alias: $loinc = http://loinc.org
Alias: $ucum = http://unitsofmeasure.org

Instance: MyObservationValid
InstanceOf: Observation
* status = #final
* code = $loinc#8867-4 "Alcoholic drinks per day"
* valueQuantity
  * system = $ucum
  * value = 0
  * code = #/d
  * unit = "PerDay"

Instance: MyObservationInvalid
InstanceOf: Observation
* status = #final
* code = $loinc#74013-4 "Alcoholic drinks per day"
* valueQuantity = 0 '/d' "PerDay"
```
Both instances should be the same (as of my understanding), but the first instance (MyObservationValid) is translated by sushi to (excerpt):
``` json
  "valueQuantity": {
    "system": "http://unitsofmeasure.org",
    "value": 0,
    "code": "/d",
    "unit": "PerDay"
  }
```

Whereas the second instance (MyObservationInvalid) is translated to:
``` json
  "valueQuantity": {
    "code": "/d",
    "system": "http://unitsofmeasure.org",
    "unit": "PerDay"
  }
```
i.e. omitting the value (this happens only with value of 0).


Pull request:
Fix Quantity Assignments w/ Value: 0
This PR provides a fix for exporting quantities whose value is `0`.  Previously, if the value was 0, the value was omitted from the exported FHIR quantity. Now it works as expected.

To test this, you can checkout just commit a98ccff and confirm the tests fail.  Then checkout the rest of the PR and the tests pass.  It's also easy to test manually by assigning any quantity type to 0.  For example:

```
Alias: $loinc = http://loinc.org

Profile: DrinksPerDayProfile
Parent: Observation
* code = $loinc#74013-4 "Alcoholic drinks per day"
* value[x] only Quantity
* value[x] = 0 '/d'
```
If you look at the FHIR exported from the above, the `value[x]` element's `patternQuantity` is missing the value when run on master.  When run on this PR, the value is present (as `0`).

```
Alias: $loinc = http://loinc.org

Instance: DrinksPerDayInstance
InstanceOf: Observation
* status = #final
* code = $loinc#74013-4 "Alcoholic drinks per day"
* valueQuantity = 0 '/d' "PerDay"
```
If you look at the FHIR exported from the above, the `valueQuantity` is missing the value when run on master.  When run on this PR, the value is present (as `0`).

Fixes #947 

Patch:
diff --git a/src/fshtypes/FshQuantity.ts b/src/fshtypes/FshQuantity.ts
index 2202e37..62c40aa 100644
--- a/src/fshtypes/FshQuantity.ts
+++ b/src/fshtypes/FshQuantity.ts
@@ -25,7 +25,7 @@ export class FshQuantity extends FshEntity {
 
   toFHIRQuantity(): Quantity {
     const quantity: Quantity = {};
-    if (this.value) {
+    if (this.value != null) {
       quantity.value = this.value;
     }
     if (this.unit?.code) {


Test patch:
diff --git a/test/export/InstanceExporter.test.ts b/test/export/InstanceExporter.test.ts
index bf81681..f56de09 100644
--- a/test/export/InstanceExporter.test.ts
+++ b/test/export/InstanceExporter.test.ts
@@ -2426,6 +2426,26 @@ describe('InstanceExporter', () => {
       ]);
     });
 
+    // Assigning Quantities with value 0 (e.g., Age)
+    it('should assign a Quantity with value 0 (and not drop the 0)', () => {
+      const observationInstance = new Instance('ZeroValueObservation');
+      observationInstance.instanceOf = 'Observation';
+      const assignedValueQuantityRule = new AssignmentRule('valueQuantity');
+      assignedValueQuantityRule.value = new FshQuantity(
+        0,
+        new FshCode('mm', 'http://unitsofmeasure.org', 'mm')
+      );
+      observationInstance.rules.push(assignedValueQuantityRule);
+      doc.instances.set(observationInstance.name, observationInstance);
+      const exported = exportInstance(observationInstance);
+      expect(exported.valueQuantity).toEqual({
+        value: 0,
+        code: 'mm',
+        system: 'http://unitsofmeasure.org',
+        unit: 'mm'
+      });
+    });
+
     // Assigning Quantities to Quantity specializations (e.g., Age)
     it('should assign a Quantity to a Quantity specialization', () => {
       const conditionInstance = new Instance('SomeCondition');
diff --git a/test/export/StructureDefinitionExporter.test.ts b/test/export/StructureDefinitionExporter.test.ts
index 4d3d554..994abdb 100644
--- a/test/export/StructureDefinitionExporter.test.ts
+++ b/test/export/StructureDefinitionExporter.test.ts
@@ -3524,6 +3524,27 @@ describe('StructureDefinitionExporter R4', () => {
       });
     });
 
+    it('should apply a correct AssignmentRule for Quantity w/ value 0', () => {
+      const profile = new Profile('Foo');
+      profile.parent = 'Observation';
+
+      const rule = new AssignmentRule('valueQuantity');
+      rule.value = new FshQuantity(0, new FshCode('mm', 'http://unitsofmeasure.org', 'mm'));
+      profile.rules.push(rule);
+
+      exporter.exportStructDef(profile);
+      const sd = pkg.profiles[0];
+
+      const assignedValue = sd.findElement('Observation.value[x]:valueQuantity');
+
+      expect(assignedValue.patternQuantity).toEqual({
+        value: 0,
+        code: 'mm',
+        system: 'http://unitsofmeasure.org',
+        unit: 'mm'
+      });
+    });
+
     it('should apply a Reference AssignmentRule and replace the Reference', () => {
       const profile = new Profile('Foo');
       profile.parent = 'Observation';