• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.healthconnect.cts.phr.utils;
18 
19 import org.json.JSONArray;
20 import org.json.JSONException;
21 import org.json.JSONObject;
22 
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 
27 /**
28  * Test helper class for making medication related FHIR data, including <a
29  * href="https://www.hl7.org/fhir/medication.html">Medication</a>, <a
30  * href="https://www.hl7.org/fhir/medicationrequest.html">MedicationRequest</a> and <a
31  * href="https://www.hl7.org/fhir/medicationstatement.html">MedicationStatement</a>.
32  */
33 public final class MedicationsBuilder {
34 
35     /**
36      * Builder class for creating FHIR <a
37      * href="https://www.hl7.org/fhir/medication.html">Medications</a>
38      */
39     public static class MedicationBuilder extends FhirResourceBuilder<MedicationBuilder> {
40 
41         private static final String DEFAULT_MEDICATION_JSON =
42                 "{"
43                         + "  \"resourceType\": \"Medication\","
44                         + "  \"id\": \"med0311\","
45                         + "  \"code\": {"
46                         + "    \"coding\": ["
47                         + "      {"
48                         + "        \"system\": \"http://snomed.info/sct\","
49                         + "        \"code\": \"373994007\","
50                         + "        \"display\": \"Prednisone 5mg tablet (Product)\""
51                         + "      }"
52                         + "    ]"
53                         + "  },"
54                         + "  \"form\": {"
55                         + "    \"coding\": ["
56                         + "      {"
57                         + "        \"system\": \"http://snomed.info/sct\","
58                         + "        \"code\": \"385055001\","
59                         + "        \"display\": \"Tablet dose form (qualifier value)\""
60                         + "      }"
61                         + "    ]"
62                         + "  },"
63                         + "  \"ingredient\": ["
64                         + "    {"
65                         + "      \"itemReference\": {"
66                         + "        \"reference\": \"#sub03\""
67                         + "      },"
68                         + "      \"strength\": {"
69                         + "        \"numerator\": {"
70                         + "          \"value\": 5,"
71                         + "          \"system\": \"http://unitsofmeasure.org\","
72                         + "          \"code\": \"mg\""
73                         + "        },"
74                         + "        \"denominator\": {"
75                         + "          \"value\": 1,"
76                         + "          \"system\":"
77                         + "\"http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm\","
78                         + "          \"code\": \"TAB\""
79                         + "        }"
80                         + "      }"
81                         + "    }"
82                         + "  ]"
83                         + "}";
84 
85         private static final String TYLENOL =
86                 "{"
87                         + "  \"resourceType\": \"Medication\","
88                         + "  \"id\": \"med0309\","
89                         + "  \"code\": {"
90                         + "    \"coding\": ["
91                         + "      {"
92                         + "        \"system\": \"http://hl7.org/fhir/sid/ndc\","
93                         + "        \"code\": \"50580-506-02\","
94                         + "        \"display\": \"Tylenol PM\""
95                         + "      }"
96                         + "    ]"
97                         + "  },"
98                         + "  \"manufacturer\": {"
99                         + "    \"reference\": \"#org2\""
100                         + "  },"
101                         + "  \"form\": {"
102                         + "    \"coding\": ["
103                         + "      {"
104                         + "        \"system\": \"http://snomed.info/sct\","
105                         + "        \"code\": \"385057009\","
106                         + "        \"display\": \"Film-coated tablet (qualifier value)\""
107                         + "      }"
108                         + "    ]"
109                         + "  },"
110                         + "  \"ingredient\": ["
111                         + "    {"
112                         + "      \"itemCodeableConcept\": {"
113                         + "        \"coding\": ["
114                         + "          {"
115                         + "            \"system\": \"http://www.nlm.nih.gov/research/umls/rxnorm\","
116                         + "            \"code\": \"315266\","
117                         + "            \"display\": \"Acetaminophen 500 MG\""
118                         + "          }"
119                         + "        ]"
120                         + "      },"
121                         + "      \"strength\": {"
122                         + "        \"numerator\": {"
123                         + "          \"value\": 500,"
124                         + "          \"system\": \"http://unitsofmeasure.org\","
125                         + "          \"code\": \"mg\""
126                         + "        },"
127                         + "        \"denominator\": {"
128                         + "          \"value\": 1,"
129                         + "          \"system\":"
130                         + "\"http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm\","
131                         + "          \"code\": \"Tab\""
132                         + "        }"
133                         + "      }"
134                         + "    },"
135                         + "    {"
136                         + "      \"itemCodeableConcept\": {"
137                         + "        \"coding\": ["
138                         + "          {"
139                         + "            \"system\": \"http://www.nlm.nih.gov/research/umls/rxnorm\","
140                         + "            \"code\": \"901813\","
141                         + "            \"display\": \"Diphenhydramine Hydrochloride 25 mg\""
142                         + "          }"
143                         + "        ]"
144                         + "      },"
145                         + "      \"strength\": {"
146                         + "        \"numerator\": {"
147                         + "          \"value\": 25,"
148                         + "          \"system\": \"http://unitsofmeasure.org\","
149                         + "          \"code\": \"mg\""
150                         + "        },"
151                         + "        \"denominator\": {"
152                         + "          \"value\": 1,"
153                         + "          \"system\":"
154                         + "\"http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm\","
155                         + "          \"code\": \"Tab\""
156                         + "        }"
157                         + "      }"
158                         + "    }"
159                         + "  ],"
160                         + "  \"batch\": {"
161                         + "    \"lotNumber\": \"9494788\","
162                         + "    \"expirationDate\": \"2017-05-22\""
163                         + "  }"
164                         + "}";
165 
MedicationBuilder()166         public MedicationBuilder() {
167             super(DEFAULT_MEDICATION_JSON);
168         }
169 
170         /**
171          * Set this medication to be Tylenol.
172          *
173          * @return this builder
174          */
setTylenol()175         public MedicationBuilder setTylenol() {
176             try {
177                 JSONObject tylenol = new JSONObject(TYLENOL);
178                 Iterator<String> keys = tylenol.keys();
179                 while (keys.hasNext()) {
180                     String key = keys.next();
181                     set(key, tylenol.get(key));
182                 }
183             } catch (JSONException e) {
184                 throw new IllegalStateException(e);
185             }
186             return this;
187         }
188 
189         @Override
returnThis()190         protected MedicationBuilder returnThis() {
191             return this;
192         }
193     }
194 
195     /**
196      * Builder class for creating FHIR <a
197      * href="https://www.hl7.org/fhir/medicationstatement.html">MedicationStatements</a>
198      */
199     public static class MedicationStatementR4Builder
200             extends FhirResourceBuilder<MedicationStatementR4Builder> {
201         private static final String DEFAULT_MEDICATION_STATEMENT_JSON =
202                 "{"
203                         + "  \"resourceType\": \"MedicationStatement\","
204                         + "  \"id\": \"example001\","
205                         + "  \"identifier\": ["
206                         + "    {"
207                         + "      \"use\": \"official\","
208                         + "      \"system\": \"http://www.bmc.nl/portal/medstatements\","
209                         + "      \"value\": \"12345689\""
210                         + "    }"
211                         + "  ],"
212                         + "  \"status\": \"active\","
213                         + "  \"category\": {"
214                         + "    \"coding\": ["
215                         + "      {"
216                         + "        \"system\": "
217                         + "\"http://terminology.hl7.org/CodeSystem/medication-statement-category\","
218                         + "        \"code\": \"inpatient\","
219                         + "        \"display\": \"Inpatient\""
220                         + "      }"
221                         + "    ]"
222                         + "  },"
223                         + "  \"medicationReference\": {"
224                         + "    \"reference\": \"#med0309\""
225                         + "  },"
226                         + "  \"subject\": {"
227                         + "    \"reference\": \"Patient/pat1\","
228                         + "    \"display\": \"Donald Duck\""
229                         + "  },"
230                         + "  \"effectiveDateTime\": \"2015-01-23\","
231                         + "  \"dateAsserted\": \"2015-02-22\","
232                         + "  \"informationSource\": {"
233                         + "    \"reference\": \"Patient/pat1\","
234                         + "    \"display\": \"Donald Duck\""
235                         + "  },"
236                         + "  \"derivedFrom\": ["
237                         + "    {"
238                         + "      \"reference\": \"MedicationRequest/medrx002\""
239                         + "    }"
240                         + "  ],"
241                         + "  \"reasonCode\": ["
242                         + "    {"
243                         + "      \"coding\": ["
244                         + "        {"
245                         + "          \"system\": \"http://snomed.info/sct\","
246                         + "          \"code\": \"32914008\","
247                         + "          \"display\": \"Restless Legs\""
248                         + "        }"
249                         + "      ]"
250                         + "    }"
251                         + "  ],"
252                         + "  \"note\": ["
253                         + "    {"
254                         + "      \"text\": \"Patient indicates they miss the occasional dose\""
255                         + "    }"
256                         + "  ],"
257                         + "  \"dosage\": ["
258                         + "    {"
259                         + "      \"sequence\": 1,"
260                         + "      \"text\": \"1-2 tablets once daily at bedtime as needed\","
261                         + "      \"additionalInstruction\": ["
262                         + "        {"
263                         + "          \"text\": \"Taking at bedtime\""
264                         + "        }"
265                         + "      ],"
266                         + "      \"timing\": {"
267                         + "        \"repeat\": {"
268                         + "          \"frequency\": 1,"
269                         + "          \"period\": 1,"
270                         + "          \"periodUnit\": \"d\""
271                         + "        }"
272                         + "      },"
273                         + "      \"asNeededCodeableConcept\": {"
274                         + "        \"coding\": ["
275                         + "          {"
276                         + "            \"system\": \"http://snomed.info/sct\","
277                         + "            \"code\": \"32914008\","
278                         + "            \"display\": \"Restless Legs\""
279                         + "          }"
280                         + "        ]"
281                         + "      },"
282                         + "      \"route\": {"
283                         + "        \"coding\": ["
284                         + "          {"
285                         + "            \"system\": \"http://snomed.info/sct\","
286                         + "            \"code\": \"26643006\","
287                         + "            \"display\": \"Oral Route\""
288                         + "          }"
289                         + "        ]"
290                         + "      },"
291                         + "      \"doseAndRate\": ["
292                         + "        {"
293                         + "          \"type\": {"
294                         + "            \"coding\": ["
295                         + "              {"
296                         + "                \"system\": "
297                         + "\"http://terminology.hl7.org/CodeSystem/dose-rate-type\","
298                         + "                \"code\": \"ordered\","
299                         + "                \"display\": \"Ordered\""
300                         + "              }"
301                         + "            ]"
302                         + "          },"
303                         + "          \"doseRange\": {"
304                         + "            \"low\": {"
305                         + "              \"value\": 1,"
306                         + "              \"unit\": \"TAB\","
307                         + "              \"system\": "
308                         + "\"http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm\","
309                         + "              \"code\": \"TAB\""
310                         + "            },"
311                         + "            \"high\": {"
312                         + "              \"value\": 2,"
313                         + "              \"unit\": \"TAB\","
314                         + "              \"system\": "
315                         + "\"http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm\","
316                         + "              \"code\": \"TAB\""
317                         + "            }"
318                         + "          }"
319                         + "        }"
320                         + "      ]"
321                         + "    }"
322                         + "  ]"
323                         + "}";
324 
MedicationStatementR4Builder()325         public MedicationStatementR4Builder() {
326             super(DEFAULT_MEDICATION_STATEMENT_JSON);
327         }
328 
329         /**
330          * Set this medication statement to contain the given medication.
331          *
332          * @param medication the medication to be contained (may be modified).
333          * @return this builder
334          */
setContainedMedication(MedicationBuilder medication)335         public MedicationStatementR4Builder setContainedMedication(MedicationBuilder medication) {
336             String containedId = "med123";
337             try {
338                 set(
339                         "contained",
340                         new JSONArray(
341                                 List.of(new JSONObject(medication.setId(containedId).toJson()))));
342                 set("medicationReference", new JSONObject(Map.of("reference", "#" + containedId)));
343             } catch (JSONException e) {
344                 throw new IllegalArgumentException(e);
345             }
346             return this;
347         }
348 
349         @Override
returnThis()350         protected MedicationStatementR4Builder returnThis() {
351             return this;
352         }
353     }
354 
355     public static class MedicationRequestBuilder
356             extends FhirResourceBuilder<MedicationRequestBuilder> {
357 
358         private static final String DEFAULT_REQUEST_JSON =
359                 "{"
360                         + "  \"resourceType\": \"MedicationRequest\","
361                         + "  \"id\": \"medrx0331\","
362                         + "  \"identifier\": ["
363                         + "    {"
364                         + "      \"use\": \"official\","
365                         + "      \"system\": \"http://www.bmc.nl/portal/prescriptions\","
366                         + "      \"value\": \"12345689\""
367                         + "    }"
368                         + "  ],"
369                         + "  \"status\": \"active\","
370                         + "  \"intent\": \"order\","
371                         + "  \"medicationReference\": {"
372                         + "    \"reference\": \"#med0350\""
373                         + "  },"
374                         + "  \"subject\": {"
375                         + "    \"reference\": \"Patient/pat1\","
376                         + "    \"display\": \"Donald Duck\""
377                         + "  },"
378                         + "  \"authoredOn\": \"2015-01-15\","
379                         + "  \"requester\": {"
380                         + "    \"reference\": \"Practitioner/f007\","
381                         + "    \"display\": \"Patrick Pump\""
382                         + "  },"
383                         + "  \"dosageInstruction\": ["
384                         + "    {"
385                         + "      \"sequence\": 1,"
386                         + "      \"text\": \"7mg once daily\","
387                         + "      \"timing\": {"
388                         + "        \"repeat\": {"
389                         + "          \"frequency\": 1,"
390                         + "          \"period\": 1,"
391                         + "          \"periodUnit\": \"d\""
392                         + "        }"
393                         + "      },"
394                         + "      \"doseAndRate\": ["
395                         + "        {"
396                         + "          \"type\": {"
397                         + "            \"coding\": ["
398                         + "              {"
399                         + "                \"system\":"
400                         + "\"http://terminology.hl7.org/CodeSystem/dose-rate-type\","
401                         + "                \"code\": \"ordered\","
402                         + "                \"display\": \"Ordered\""
403                         + "              }"
404                         + "            ]"
405                         + "          },"
406                         + "          \"doseQuantity\": {"
407                         + "            \"value\": 7,"
408                         + "            \"unit\": \"mg\","
409                         + "            \"system\": \"http://unitsofmeasure.org\","
410                         + "            \"code\": \"mg\""
411                         + "          }"
412                         + "        }"
413                         + "      ]"
414                         + "    }"
415                         + "  ],"
416                         + "  \"dispenseRequest\": {"
417                         + "    \"validityPeriod\": {"
418                         + "      \"start\": \"2015-01-15\","
419                         + "      \"end\": \"2016-01-15\""
420                         + "    },"
421                         + "    \"numberOfRepeatsAllowed\": 3,"
422                         + "    \"quantity\": {"
423                         + "      \"value\": 30,"
424                         + "      \"unit\": \"TAB\","
425                         + "      \"system\":"
426                         + "\"http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm\","
427                         + "      \"code\": \"TAB\""
428                         + "    },"
429                         + "    \"expectedSupplyDuration\": {"
430                         + "      \"value\": 30,"
431                         + "      \"unit\": \"days\","
432                         + "      \"system\": \"http://unitsofmeasure.org\","
433                         + "      \"code\": \"d\""
434                         + "    }"
435                         + "  },"
436                         + "  \"substitution\": {"
437                         + "    \"allowedBoolean\": true,"
438                         + "    \"reason\": {"
439                         + "      \"coding\": ["
440                         + "        {"
441                         + "          \"system\":"
442                         + "\"http://terminology.hl7.org/CodeSystem/v3-ActReason\","
443                         + "          \"code\": \"FP\","
444                         + "          \"display\": \"formulary policy\""
445                         + "        }"
446                         + "      ]"
447                         + "    }"
448                         + "  }"
449                         + "}";
450 
MedicationRequestBuilder()451         public MedicationRequestBuilder() {
452             super(DEFAULT_REQUEST_JSON);
453         }
454 
455         @Override
returnThis()456         protected MedicationRequestBuilder returnThis() {
457             return this;
458         }
459     }
460 
461     /**
462      * Returns a builder class that will help build <a
463      * href="https://www.hl7.org/fhir/medication.html">Medication</a> FHIR JSON.
464      */
medication()465     public static MedicationBuilder medication() {
466         return new MedicationBuilder();
467     }
468 
469     /**
470      * Returns a builder class that will help build <a
471      * href="https://www.hl7.org/fhir/medication.html">Medication</a> FHIR JSON, in FHIR version R4
472      * format.
473      */
statementR4()474     public static MedicationStatementR4Builder statementR4() {
475         return new MedicationStatementR4Builder();
476     }
477 
478     /**
479      * Returns a builder class that will help build <a
480      * href="https://www.hl7.org/fhir/medicationrequest.html">MedicationRequest</a> FHIR JSON.
481      */
request()482     public static MedicationRequestBuilder request() {
483         return new MedicationRequestBuilder();
484     }
485 }
486