Skip to content

Commit e83ae2f

Browse files
committed
Update randomCode fn to take output type as an optional second param
1 parent 2cc0a62 commit e83ae2f

File tree

5 files changed

+114
-10
lines changed

5 files changed

+114
-10
lines changed

src/main/java/org/mitre/synthea/export/FhirR4.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -3385,7 +3385,7 @@ private static Type convertFhirDateTime(long datetime, boolean time) {
33853385
* @param system The system identifier, such as a URI. Optional; may be null.
33863386
* @return The converted CodeableConcept
33873387
*/
3388-
private static CodeableConcept mapCodeToCodeableConcept(Code from, String system) {
3388+
public static CodeableConcept mapCodeToCodeableConcept(Code from, String system) {
33893389
CodeableConcept to = new CodeableConcept();
33903390
system = system == null ? null : ExportHelper.getSystemURI(system);
33913391
from.system = ExportHelper.getSystemURI(from.system);

src/main/java/org/mitre/synthea/export/flexporter/Actions.java

+17-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.hl7.fhir.r4.model.Bundle.BundleEntryRequestComponent;
2727
import org.hl7.fhir.r4.model.Bundle.BundleType;
2828
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
29+
import org.hl7.fhir.r4.model.Coding;
2930
import org.hl7.fhir.r4.model.DateTimeType;
3031
import org.hl7.fhir.r4.model.Encounter;
3132
import org.hl7.fhir.r4.model.Meta;
@@ -822,7 +823,7 @@ private static Object getValue(Bundle bundle, String valueDef, Resource currentR
822823
} else if (flag.equals("getAttribute")) {
823824
return getAttribute(person, flagValues);
824825
} else if (flag.equals("randomCode")) {
825-
return randomCode(flagValues[0]);
826+
return randomCode(flagValues);
826827
}
827828

828829
return null;
@@ -900,13 +901,22 @@ private static Base findValue(Bundle bundle, String... args) {
900901
return fieldValues.get(0);
901902
}
902903

903-
private static Map<String, String> randomCode(String valueSetUrl) {
904+
private static Object randomCode(String... args) {
905+
String valueSetUrl = args[0];
906+
String outputType = (args.length > 1) ? args[1] : "Coding";
904907
Code code = RandomCodeGenerator.getCode(valueSetUrl,
905908
(int) (Math.random() * Integer.MAX_VALUE));
906-
Map<String, String> codeAsMap = Map.of(
907-
"system", code.system,
908-
"code", code.code,
909-
"display", code.display == null ? "" : code.display);
910-
return codeAsMap;
909+
910+
if (outputType.equalsIgnoreCase("code")) {
911+
return code.code;
912+
} else if (outputType.equalsIgnoreCase("Coding")) {
913+
return new Coding(code.system, code.code, code.display);
914+
} else if (outputType.equalsIgnoreCase("CodeableConcept")) {
915+
return FhirR4.mapCodeToCodeableConcept(code, null);
916+
} else {
917+
throw new IllegalArgumentException("Unexpected output type for randomCode: " + outputType
918+
+ ". Valid values are: code, Coding, CodeableConcept");
919+
}
920+
911921
}
912922
}

src/main/java/org/mitre/synthea/helpers/RandomCodeGenerator.java

+21-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import okhttp3.ResponseBody;
1919
import org.apache.commons.lang3.StringUtils;
2020
import org.apache.commons.validator.routines.UrlValidator;
21+
import org.hl7.fhir.r4.model.OperationOutcome;
22+
import org.hl7.fhir.r4.model.Resource;
2123
import org.hl7.fhir.r4.model.ValueSet;
2224
import org.hl7.fhir.r4.model.ValueSet.ConceptReferenceComponent;
2325
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
@@ -117,8 +119,25 @@ private static synchronized void expandValueSet(String valueSetUri) {
117119
ResponseBody body = response.body();
118120
if (body != null) {
119121
IParser parser = FhirR4.getContext().newJsonParser();
120-
ValueSet valueSet = (ValueSet) parser.parseResource(body.charStream());
121-
loadValueSet(valueSetUri, valueSet);
122+
Resource resource = (Resource) parser.parseResource(body.charStream());
123+
if (resource instanceof ValueSet) {
124+
loadValueSet(valueSetUri, (ValueSet)resource);
125+
} else if (resource instanceof OperationOutcome) {
126+
OperationOutcome oo = (OperationOutcome)resource;
127+
parser.setPrettyPrint(true);
128+
System.err.println(parser.encodeResourceToString(oo));
129+
String details = oo.getIssueFirstRep().getDetails().getText();
130+
131+
throw new RuntimeException(
132+
"Received OperationOutcome in ValueSet expand response. Detail: "
133+
+ details + ". See log for full resource");
134+
} else {
135+
parser.setPrettyPrint(true);
136+
System.err.println(parser.encodeResourceToString(resource));
137+
throw new RuntimeException(
138+
"Unexpected resourceType received in expand ValueSet response: "
139+
+ resource.getResourceType() + ". See log for full resource");
140+
}
122141
} else {
123142
throw new RuntimeException("Value Set Expansion contained no body");
124143
}

src/test/java/org/mitre/synthea/export/flexporter/ActionsTest.java

+64
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,15 @@
5454
import org.hl7.fhir.r4.model.ServiceRequest;
5555
import org.hl7.fhir.r4.model.TimeType;
5656
import org.hl7.fhir.r4.model.Type;
57+
import org.hl7.fhir.r4.model.ValueSet;
58+
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
5759
import org.junit.AfterClass;
5860
import org.junit.BeforeClass;
5961
import org.junit.Test;
6062
import org.mitre.synthea.engine.Module;
6163
import org.mitre.synthea.engine.State;
6264
import org.mitre.synthea.export.FhirR4;
65+
import org.mitre.synthea.helpers.RandomCodeGenerator;
6366
import org.mitre.synthea.world.agents.Person;
6467

6568
public class ActionsTest {
@@ -817,4 +820,65 @@ public void testGetAttribute() throws Exception {
817820
assertEquals("Robert Rainbow", name.getText());
818821
}
819822

823+
@Test
824+
public void testRandomCode() {
825+
Bundle b = new Bundle();
826+
b.setType(BundleType.COLLECTION);
827+
828+
ValueSet statusVs = constructValueSet(
829+
"http://hl7.org/fhir/encounter-status",
830+
"planned", "finished", "cancelled");
831+
RandomCodeGenerator.loadValueSet("http://example.org/encounterStatus", statusVs);
832+
833+
ValueSet classVs = constructValueSet(
834+
"http://terminology.hl7.org/CodeSystem/v3-ActCode",
835+
"AMB", "EMER", "ACUTE");
836+
RandomCodeGenerator.loadValueSet("http://example.org/encounterClass", classVs);
837+
838+
ValueSet typeVs = constructValueSet(
839+
"http://terminology.hl7.org/CodeSystem/encounter-type",
840+
"ADMS", "OKI");
841+
RandomCodeGenerator.loadValueSet("http://example.org/encounterType", typeVs);
842+
843+
Map<String, Object> action = getActionByName("testRandomCode");
844+
Actions.applyAction(b, action, null, null);
845+
846+
Encounter e = (Encounter) b.getEntryFirstRep().getResource();
847+
848+
Encounter.EncounterStatus status = e.getStatus();
849+
assertNotNull(status);
850+
assertTrue(status == Encounter.EncounterStatus.PLANNED
851+
|| status == Encounter.EncounterStatus.FINISHED
852+
|| status == Encounter.EncounterStatus.CANCELLED);
853+
854+
Coding encClass = e.getClass_();
855+
assertNotNull(encClass);
856+
assertEquals("http://terminology.hl7.org/CodeSystem/v3-ActCode", encClass.getSystem());
857+
String code = encClass.getCode();
858+
assertTrue(code.equals("AMB") || code.equals("EMER") || code.equals("ACUTE"));
859+
860+
CodeableConcept type = e.getTypeFirstRep();
861+
assertNotNull(type);
862+
Coding typeCoding = type.getCodingFirstRep();
863+
assertNotNull(typeCoding);
864+
assertEquals("http://terminology.hl7.org/CodeSystem/encounter-type", typeCoding.getSystem());
865+
code = typeCoding.getCode();
866+
assertTrue(code.equals("ADMS") || code.equals("OKI"));
867+
}
868+
869+
private ValueSet constructValueSet(String system, String... codes) {
870+
ValueSet vs = new ValueSet();
871+
872+
// populates the codes so that they can be read in RandomCodeGenerator.loadValueSet
873+
ConceptSetComponent csc = new ConceptSetComponent();
874+
csc.setSystem(system);
875+
for (String code : codes) {
876+
csc.addConcept().setCode(code).setDisplay(code);
877+
}
878+
879+
vs.getCompose().getInclude().add(csc);
880+
881+
return vs;
882+
}
883+
820884
}

src/test/resources/flexporter/test_mapping.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,17 @@ actions:
280280
location: ServiceRequest.authoredOn
281281
value: $getField([Procedure.performed]) # datetime choice type
282282

283+
- name: testRandomCode
284+
create_resource:
285+
- resourceType: Encounter
286+
fields:
287+
- location: Encounter.status
288+
value: $randomCode([http://example.org/encounterStatus,code])
289+
- location: Encounter.class
290+
value: $randomCode([http://example.org/encounterClass])
291+
- location: Encounter.type
292+
value: $randomCode([http://example.org/encounterType,CodeableConcept])
293+
283294

284295
- name: testExecuteScript
285296
execute_script:

0 commit comments

Comments
 (0)