From c6a7e6530d00386e88e1ec47f689cd2141e83757 Mon Sep 17 00:00:00 2001 From: Dheeraj Pundir <1236dheeraj.ds@gmail.com> Date: Fri, 12 Feb 2021 16:27:54 +0530 Subject: [PATCH] Dheeraj | Add Immunization and Immunization Recommendation --- .../in/projecteka/utils/data/FHIRUtils.java | 42 ++++++++++++++++++- .../utils/data/ImmunizationGenerator.java | 42 +++++++++++++++++-- .../utils/data/OPConsultationGenerator.java | 28 ++++++++++++- .../utils/data/model/TargetDisease.java | 17 ++++++++ .../immunization-diseases.properties | 9 ++++ ...rties => immunization-vaccines.properties} | 0 src/main/resources/patients.properties | 3 +- 7 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 src/main/java/in/projecteka/utils/data/model/TargetDisease.java create mode 100644 src/main/resources/immunization-diseases.properties rename src/main/resources/{immunization.properties => immunization-vaccines.properties} (100%) diff --git a/src/main/java/in/projecteka/utils/data/FHIRUtils.java b/src/main/java/in/projecteka/utils/data/FHIRUtils.java index ae82c79..fb257db 100644 --- a/src/main/java/in/projecteka/utils/data/FHIRUtils.java +++ b/src/main/java/in/projecteka/utils/data/FHIRUtils.java @@ -1,6 +1,7 @@ package in.projecteka.utils.data; import in.projecteka.utils.data.model.Doctor; +import in.projecteka.utils.data.model.TargetDisease; import in.projecteka.utils.data.model.Vaccine; import in.projecteka.utils.data.model.Medicine; import in.projecteka.utils.data.model.SimpleCondition; @@ -15,12 +16,14 @@ import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Condition; import org.hl7.fhir.r4.model.DateTimeType; +import org.hl7.fhir.r4.model.DiagnosticReport; import org.hl7.fhir.r4.model.DocumentReference; import org.hl7.fhir.r4.model.Encounter; import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.HumanName; import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.r4.model.Immunization; +import org.hl7.fhir.r4.model.ImmunizationRecommendation; import org.hl7.fhir.r4.model.Medication; import org.hl7.fhir.r4.model.MedicationRequest; import org.hl7.fhir.r4.model.Meta; @@ -32,12 +35,14 @@ import org.hl7.fhir.r4.model.Resource; import org.hl7.fhir.r4.model.ResourceType; import org.hl7.fhir.r4.model.StringType; +import org.hl7.fhir.utilities.DateTimeUtil; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.List; import java.util.Properties; import java.util.UUID; import java.util.stream.Collectors; @@ -189,6 +194,7 @@ static CodeableConcept getChiefComplaintSectionType() { coding.setDisplay("Chief Complaint Section"); return type; } + static CodeableConcept getAllergySectionType() { CodeableConcept type = new CodeableConcept(); Coding coding = type.addCoding(); @@ -198,7 +204,14 @@ static CodeableConcept getAllergySectionType() { return type; } - + static CodeableConcept getImmunizationRecommendationSectionType() { + CodeableConcept type = new CodeableConcept(); + Coding coding = type.addCoding(); + coding.setSystem(Constants.EKA_SCT_SYSTEM); + coding.setCode("41000179103"); + coding.setDisplay("Immunization Recommendation"); + return type; + } static void addToBundleEntry(Bundle bundle, Resource resource, boolean useIdPart) { String resourceType = resource.getResourceType().toString(); @@ -322,6 +335,33 @@ static Immunization getImmunization(Vaccine vaccine, Date date, String orgPrefix return immunization; } + static ImmunizationRecommendation getImmunizationRecommendation(Vaccine vaccine, TargetDisease targetDisease, Date date){ + ImmunizationRecommendation immunizationRecommendation = new ImmunizationRecommendation(); + immunizationRecommendation.setId(UUID.randomUUID().toString()); + immunizationRecommendation.setDate(date); + var immunizationRecommendationComponent = immunizationRecommendation.addRecommendation(); + immunizationRecommendationComponent.addVaccineCode(getCodeableConcept(vaccine.getCode(), vaccine.getName(), null)); + immunizationRecommendationComponent.setTargetDisease(getCodeableConcept(targetDisease.getCode(), targetDisease.getName(), null)); + + var dateCriterion = immunizationRecommendationComponent.addDateCriterion(); + dateCriterion.setCode(getCodeableConcept("30980-7", "Date vaccine due", null)); + dateCriterion.setValue(date); + + return immunizationRecommendation; + } + + static DiagnosticReport getDiagnosticReport(Date date) { + DiagnosticReport diagnosticReport = new DiagnosticReport(); + diagnosticReport.setId(UUID.randomUUID().toString()); + + DateTimeType dateTimeType = new DateTimeType(); + dateTimeType.setValue(Utils.getFutureTime(date, 60)); + diagnosticReport.setStatus(DiagnosticReport.DiagnosticReportStatus.FINAL); + diagnosticReport.setCode(FHIRUtils.getDiagnosticTestCode(SimpleDiagnosticTest.getRandomTest())); + diagnosticReport.setConclusion("Refer to Doctor. To be correlated with further study."); + return diagnosticReport; + } + static MedicationRequest createMedicationRequest(Practitioner author, Date date, Medicine med, diff --git a/src/main/java/in/projecteka/utils/data/ImmunizationGenerator.java b/src/main/java/in/projecteka/utils/data/ImmunizationGenerator.java index 4d4b1bb..0b59dd5 100644 --- a/src/main/java/in/projecteka/utils/data/ImmunizationGenerator.java +++ b/src/main/java/in/projecteka/utils/data/ImmunizationGenerator.java @@ -1,8 +1,11 @@ package in.projecteka.utils.data; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.parser.IParser; import in.projecteka.utils.DocRequest; import in.projecteka.utils.data.model.Doctor; +import in.projecteka.utils.data.model.Obs; +import in.projecteka.utils.data.model.SimpleCondition; import in.projecteka.utils.data.model.Vaccine; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.CodeableConcept; @@ -10,10 +13,12 @@ import org.hl7.fhir.r4.model.DocumentReference; import org.hl7.fhir.r4.model.Encounter; import org.hl7.fhir.r4.model.Immunization; +import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.Resource; import org.hl7.fhir.r4.model.ResourceType; import java.nio.file.Path; @@ -32,7 +37,7 @@ public class ImmunizationGenerator implements DocumentGenerator { private Properties patients; public void init() throws Exception { - immunizationProps = Utils.loadFromFile("/immunization.properties"); + immunizationProps = Utils.loadFromFile("/immunization-vaccines.properties"); doctors = Utils.loadFromFile("/practitioners.properties"); patients = Utils.loadFromFile("/patients.properties"); } @@ -42,7 +47,7 @@ public void execute(DocRequest request) throws Exception { LocalDateTime dateTime = request.getFromDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); for (int i = 0; i < request.getNumber(); i++) { Date date = Utils.getNextDate(dateTime, i); - Bundle bundle = createImmunizationBundle(date, request.getPatientName(), request.getHipPrefix(), request.getPatientId()); + Bundle bundle = createImmunizationBundle(date, request.getPatientName(), request.getHipPrefix(), request.getPatientId(), fhirContext.newJsonParser()); String encodedString = fhirContext.newJsonParser().encodeResourceToString(bundle); List patientEntries = bundle.getEntry().stream() @@ -60,7 +65,7 @@ public void execute(DocRequest request) throws Exception { } } - private Bundle createImmunizationBundle(Date date, String patientName, String hipPrefix, String patientId) throws Exception { + private Bundle createImmunizationBundle(Date date, String patientName, String hipPrefix, String patientId, IParser parser) throws Exception { Bundle bundle = FHIRUtils.createBundle(date, hipPrefix); Patient patientResource = FHIRUtils.getPatientResource(patientName, patientId, patients); Reference patientRef = createPatientReference(patientResource); @@ -106,6 +111,31 @@ private Bundle createImmunizationBundle(Date date, String patientName, String hi FHIRUtils.addToBundleEntry(bundle, organization, true); immunization.setManufacturer(FHIRUtils.getReferenceToResource(organization)); + //Reason reference + if(Utils.randomBool()) { + int randomReasonRefNumber = Utils.randomInt(1,2); + Resource reasonResource = FHIRUtils.createCondition(SimpleCondition.getRandomCondition(), date); + + if(randomReasonRefNumber == 1){ + reasonResource = getObservation(parser); + } + + if(randomReasonRefNumber == 2){ + var diagnosticReport = FHIRUtils.getDiagnosticReport(date); + diagnosticReport.addResultsInterpreter(FHIRUtils.getReferenceToResource(author)); + reasonResource = diagnosticReport; + } + + FHIRUtils.addToBundleEntry(bundle, reasonResource, false); + immunization.addReasonReference(FHIRUtils.getReferenceToResource(reasonResource)); + } + + if(Utils.randomBool()){ + Observation observation = getObservation(parser); + FHIRUtils.addToBundleEntry(bundle, observation, false); + immunization.addReaction().setDetail(FHIRUtils.getReferenceToResource(observation)); + } + immunization.setPatient(patientRef); FHIRUtils.addToBundleEntry(bundle, immunization, false); section.getEntry().add(FHIRUtils.getReferenceToResource(immunization)); @@ -125,4 +155,10 @@ private Reference createPatientReference(Patient patientResource) { return patientRef; } + private Observation getObservation(IParser parser) { + Observation observation = parser.parseResource(Observation.class, Obs.getObservationResString()); + observation.setId(UUID.randomUUID().toString()); + return observation; + } + } diff --git a/src/main/java/in/projecteka/utils/data/OPConsultationGenerator.java b/src/main/java/in/projecteka/utils/data/OPConsultationGenerator.java index ba78691..49d8d0c 100644 --- a/src/main/java/in/projecteka/utils/data/OPConsultationGenerator.java +++ b/src/main/java/in/projecteka/utils/data/OPConsultationGenerator.java @@ -9,7 +9,10 @@ import in.projecteka.utils.data.model.SimpleAllergy; import in.projecteka.utils.data.model.SimpleCondition; import in.projecteka.utils.data.model.SimpleDiagnosticTest; +import in.projecteka.utils.data.model.TargetDisease; +import in.projecteka.utils.data.model.Vaccine; import lombok.SneakyThrows; +import org.apache.commons.lang3.RandomUtils; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.r4.model.AllergyIntolerance; import org.hl7.fhir.r4.model.Annotation; @@ -23,6 +26,7 @@ import org.hl7.fhir.r4.model.DiagnosticReport; import org.hl7.fhir.r4.model.DocumentReference; import org.hl7.fhir.r4.model.Encounter; +import org.hl7.fhir.r4.model.ImmunizationRecommendation; import org.hl7.fhir.r4.model.Medication; import org.hl7.fhir.r4.model.MedicationRequest; import org.hl7.fhir.r4.model.Observation; @@ -58,12 +62,16 @@ public class OPConsultationGenerator implements DocumentGenerator { private Properties doctors; private Properties patients; private Properties medicationProps; + private Properties immunizationVaccineProps; + private Properties immunizationDiseaseProps; @Override public void init() throws Exception { doctors = Utils.loadFromFile("/practitioners.properties"); patients = Utils.loadFromFile("/patients.properties"); medicationProps = Utils.loadFromFile("/medications.properties"); + immunizationDiseaseProps = Utils.loadFromFile("/immunization-diseases.properties"); + immunizationVaccineProps = Utils.loadFromFile("/immunization-vaccines.properties"); } @Override @@ -137,7 +145,7 @@ private Bundle createOPConsultationBundle(Date date, String patientName, String Reference referenceToResource = FHIRUtils.getReferenceToResource(encounter); opDoc.setEncounter(referenceToResource); - generateSections(hipPrefix, jsonParser, bundle, opDoc, patientResource); + generateSections(hipPrefix, jsonParser, bundle, opDoc, patientResource, date); return bundle; } @@ -145,7 +153,7 @@ protected String getCompositionDocumentTitle() { return "OP Consultation Document"; } - protected void generateSections(String hipPrefix, IParser jsonParser, Bundle bundle, Composition opDoc, Patient patientResource) { + protected void generateSections(String hipPrefix, IParser jsonParser, Bundle bundle, Composition opDoc, Patient patientResource, Date date) { createChiefComplaintsSection(bundle, opDoc, patientResource); createAllergiesSection(bundle, opDoc, patientResource, jsonParser); createMedicalHistorySection(bundle, opDoc, patientResource); //TODO @@ -153,6 +161,7 @@ protected void generateSections(String hipPrefix, IParser jsonParser, Bundle bun createObservationSection(bundle, opDoc, patientResource, jsonParser); createInvestigationSection(bundle, opDoc, patientResource); //TODO createPrescriptionSection(bundle, opDoc, patientResource); + createImmunizationRecordSection(bundle, opDoc, patientResource, date); createDocumentsSection(bundle, opDoc, patientResource, hipPrefix); createProcedureSection(bundle, opDoc, patientResource, hipPrefix); createDiagnosticReportSection(bundle, opDoc, patientResource, jsonParser, hipPrefix); @@ -461,6 +470,21 @@ protected void createAllergiesSection(Bundle bundle, Composition composition, Pa section.getEntry().add(FHIRUtils.getReferenceToResource(medicationAllergy)); } + @SneakyThrows + protected void createImmunizationRecordSection(Bundle bundle, Composition composition, Patient patient, Date date) { + Composition.SectionComponent section = composition.addSection(); + section.setTitle("Immunization Recommendation"); + section.setCode(FHIRUtils.getImmunizationRecommendationSectionType()); + var vaccineIndex = RandomUtils.nextInt(1, 11); + var diseaseIndex = RandomUtils.nextInt(1, 10); + Vaccine vaccine = Vaccine.parse((String) immunizationVaccineProps.get(String.valueOf(vaccineIndex))); + TargetDisease targetDisease = TargetDisease.parse((String) immunizationDiseaseProps.get(String.valueOf(diseaseIndex))); + ImmunizationRecommendation immunizationRecommendation = FHIRUtils.getImmunizationRecommendation(vaccine, targetDisease, date); + immunizationRecommendation.setPatient(FHIRUtils.getReferenceToPatient(patient)); + FHIRUtils.addToBundleEntry(bundle, immunizationRecommendation, true); + section.getEntry().add(FHIRUtils.getReferenceToResource(immunizationRecommendation)); + } + @SneakyThrows protected void createMedicalHistorySection(Bundle bundle, Composition composition, Patient patient) { return; diff --git a/src/main/java/in/projecteka/utils/data/model/TargetDisease.java b/src/main/java/in/projecteka/utils/data/model/TargetDisease.java new file mode 100644 index 0000000..e8dc831 --- /dev/null +++ b/src/main/java/in/projecteka/utils/data/model/TargetDisease.java @@ -0,0 +1,17 @@ +package in.projecteka.utils.data.model; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class TargetDisease { + String code; + String name; + + public static TargetDisease parse(String details) { + String[] parts = details.split(","); + return new TargetDisease(parts[0].trim(), parts[1].trim()); + } + +} diff --git a/src/main/resources/immunization-diseases.properties b/src/main/resources/immunization-diseases.properties new file mode 100644 index 0000000..94e5191 --- /dev/null +++ b/src/main/resources/immunization-diseases.properties @@ -0,0 +1,9 @@ +1=1857005, Gestational rubella syndrome +2=397430003, Diphtheria due to Corynebacterium diphtheriae +3=14189004, Measles +4=36989005, Mumps +5=36653000, Rubella +6=76902006, Tetanus +7=709410003, Haemophilus influenzae type b infection +8=27836007, Pertussis +9=398102009, Acute poliomyelitis diff --git a/src/main/resources/immunization.properties b/src/main/resources/immunization-vaccines.properties similarity index 100% rename from src/main/resources/immunization.properties rename to src/main/resources/immunization-vaccines.properties diff --git a/src/main/resources/patients.properties b/src/main/resources/patients.properties index d00aba2..942cf7d 100644 --- a/src/main/resources/patients.properties +++ b/src/main/resources/patients.properties @@ -6,4 +6,5 @@ singhal=Navajot Singhal, female, NCC1702, navjSinghal85, navajotSinghal.1985 mane=Sadio Mane, male, LIVNO10, sadiomane92, sadiomane.1992 salah=Mohamed Salah, male, LIVNO11, mohamedsalah92, mohamedsalah.1992 firmino=Roberto Firmino, male, LIVNO09, robertofirmino91, robertofirmino.1991 -david=David James, male, LIVNO14, davidjames93, davidjames.1993 \ No newline at end of file +david=David James, male, LIVNO14, davidjames93, davidjames.1993 +kabir=Kabir Singh, male, RVH1012, kabirsingh99, kabirsingh.1992