From d55b0b2c9ef6ece977af50fa708224f0b5a37530 Mon Sep 17 00:00:00 2001 From: Terry O'Neill Date: Fri, 3 Dec 2021 10:36:19 +1100 Subject: [PATCH 01/11] Added ADT_A60 support and partial IAM segment support --- .../hl7/data/SimpleDataTypeMapper.java | 1 + .../hl7/data/SimpleDataValueResolver.java | 6 +++ src/main/resources/config.properties | 2 +- .../hl7/codesystem/v2ToFhirMapping.yml | 3 ++ src/main/resources/hl7/message/ADT_A60.yml | 37 ++++++++++++++++ .../hl7/resource/AllergyIntolerance.yml | 43 +++++++++++++++++-- 6 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/hl7/message/ADT_A60.yml diff --git a/src/main/java/io/github/linuxforhealth/hl7/data/SimpleDataTypeMapper.java b/src/main/java/io/github/linuxforhealth/hl7/data/SimpleDataTypeMapper.java index 9238d7c8..27736051 100644 --- a/src/main/java/io/github/linuxforhealth/hl7/data/SimpleDataTypeMapper.java +++ b/src/main/java/io/github/linuxforhealth/hl7/data/SimpleDataTypeMapper.java @@ -44,6 +44,7 @@ public enum SimpleDataTypeMapper { ALLERGY_INTOLERANCE_CATEGORY(SimpleDataValueResolver.ALLERGY_INTOLERANCE_CATEGORY_CODE_FHIR), ALLERGY_INTOLERANCE_CRITICALITY( SimpleDataValueResolver.ALLERGY_INTOLERANCE_CRITICALITY_CODE_FHIR), + ALLERGY_INTOLERANCE_TYPE(SimpleDataValueResolver.ALLERGY_INTOLERANCE_TYPE_CODE_FHIR), ADMINISTRATIVE_GENDER(SimpleDataValueResolver.ADMINISTRATIVE_GENDER_CODE_FHIR), CONDITION_CATEGORY_CODES(SimpleDataValueResolver.CONDITION_CATEGORY_CODES), DIAGNOSTIC_REPORT_STATUS(SimpleDataValueResolver.DIAGNOSTIC_REPORT_STATUS_CODES), diff --git a/src/main/java/io/github/linuxforhealth/hl7/data/SimpleDataValueResolver.java b/src/main/java/io/github/linuxforhealth/hl7/data/SimpleDataValueResolver.java index eed27cf1..87e20d49 100644 --- a/src/main/java/io/github/linuxforhealth/hl7/data/SimpleDataValueResolver.java +++ b/src/main/java/io/github/linuxforhealth/hl7/data/SimpleDataValueResolver.java @@ -32,6 +32,7 @@ import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r4.model.AllergyIntolerance.AllergyIntoleranceCategory; import org.hl7.fhir.r4.model.AllergyIntolerance.AllergyIntoleranceCriticality; +import org.hl7.fhir.r4.model.AllergyIntolerance.AllergyIntoleranceType; import org.hl7.fhir.r4.model.DiagnosticReport.DiagnosticReportStatus; import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender; import org.hl7.fhir.r4.model.Immunization.ImmunizationStatus; @@ -577,6 +578,11 @@ private static final SimpleCode commonCodingSystemV2 (String table, String code, String val = Hl7DataHandlerUtil.getStringValue(value); return getFHIRCode(val, AllergyIntoleranceCategory.class); }; + + public static final ValueExtractor ALLERGY_INTOLERANCE_TYPE_CODE_FHIR = (Object value) -> { + String val = Hl7DataHandlerUtil.getStringValue(value); + return getFHIRCode(val, AllergyIntoleranceType.class); + }; public static final ValueExtractor DOSE_SYSTEM = (Object value) -> { String val = Hl7DataHandlerUtil.getStringValue(value); diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties index 151b2e73..efa7f6a2 100644 --- a/src/main/resources/config.properties +++ b/src/main/resources/config.properties @@ -1,4 +1,4 @@ base.path.resource= -supported.hl7.messages=ADT_A01, ADT_A08, ADT_A34, ADT_A40, MDM_T02, MDM_T06, ORM_O01, OMP_O09, ORU_R01, PPR_PC1, RDE_O11, RDE_O25, VXU_V04 +supported.hl7.messages=ADT_A01, ADT_A08, ADT_A34, ADT_A40, ADT_A60, MDM_T02, MDM_T06, ORM_O01, OMP_O09, ORU_R01, PPR_PC1, RDE_O11, RDE_O25, VXU_V04 default.zoneid=+08:00 additional.conceptmap.file= \ No newline at end of file diff --git a/src/main/resources/hl7/codesystem/v2ToFhirMapping.yml b/src/main/resources/hl7/codesystem/v2ToFhirMapping.yml index 96e2c6d8..a9a99873 100644 --- a/src/main/resources/hl7/codesystem/v2ToFhirMapping.yml +++ b/src/main/resources/hl7/codesystem/v2ToFhirMapping.yml @@ -15,6 +15,9 @@ AllergyIntoleranceCriticality: MI: low SV: high U: unable-to-assess +AllergyIntoleranceType: + AL: allergy + IN: intolerance ObservationStatus: C: corrected D: cancelled diff --git a/src/main/resources/hl7/message/ADT_A60.yml b/src/main/resources/hl7/message/ADT_A60.yml new file mode 100644 index 00000000..bae96d47 --- /dev/null +++ b/src/main/resources/hl7/message/ADT_A60.yml @@ -0,0 +1,37 @@ +# FHIR Resources to extract from ADT_A60 message +--- +resources: + - resourceName: MessageHeader + segment: MSH + resourcePath: resource/MessageHeader + repeats: false + isReferenced: false + additionalSegments: + - EVN + + - resourceName: Patient + segment: PID + resourcePath: resource/Patient + repeats: false + isReferenced: true + additionalSegments: + - MSH + + + - resourceName: Encounter + segment: PV1 + resourcePath: resource/Encounter + repeats: false + isReferenced: true + additionalSegments: + - PV2 + - EVN + - MSH + + - resourceName: AllergyIntolerance + segment: IAM + resourcePath: resource/AllergyIntolerance + repeats: true + additionalSegments: + - MSH + - PID \ No newline at end of file diff --git a/src/main/resources/hl7/resource/AllergyIntolerance.yml b/src/main/resources/hl7/resource/AllergyIntolerance.yml index 3f0b1b5e..4f6e88da 100644 --- a/src/main/resources/hl7/resource/AllergyIntolerance.yml +++ b/src/main/resources/hl7/resource/AllergyIntolerance.yml @@ -10,7 +10,7 @@ id: valueOf: 'UUID.randomUUID()' expressionType: JEXL -identifier: +identifier_1: valueOf: datatype/Identifier generateList: true expressionType: resource @@ -20,6 +20,16 @@ identifier: constants: sys: "urn:id:extID" +identifier_2: + valueOf: datatype/Identifier + generateList: true + expressionType: resource + vars: + system: SYSTEM_URL, $sys + value: IAM.7 + constants: + sys: "urn:id:extID" + clinicalStatus: valueOf: datatype/CodeableConcept_var generateList: true @@ -38,10 +48,15 @@ verificationStatus: code: 'confirmed' display: 'Confirmed' +type: + type: ALLERGY_INTOLERANCE_TYPE + valueOf: IAM.9 + expressionType: HL7Spec + category: type: ALLERGY_INTOLERANCE_CATEGORY generateList: true - valueOf: AL1.2 + valueOf: AL1.2 | IAM.2 expressionType: HL7Spec criticality: @@ -53,13 +68,35 @@ code: valueOf: datatype/CodeableConcept generateList: true expressionType: resource - specs: AL1.3 + specs: AL1.3 | IAM.3 onsetDateTime: type: DATE_TIME valueOf: AL1.6 expressionType: HL7Spec +recordedDate: + type: DATE_TIME + valueOf: IAM.13 + expressionType: HL7Spec + +asserter_1: + condition: $iam18 NOT_NULL + valueOf: resource/Practitioner + expressionType: reference + specs: IAM.18 + vars: + iam18: IAM.18 + +asserter_2: + condition: $iam18 NULL && $iam14 NOT_NULL + valueOf: resource/Patient + expressionType: reference + specs: IAM.14 + vars: + iam14: IAM.14 + iam18: IAM.18 + patient: valueOf: datatype/Reference expressionType: resource From b2125d80a435b7632733505e24483fc125ac070e Mon Sep 17 00:00:00 2001 From: Terry O'Neill Date: Fri, 3 Dec 2021 10:37:17 +1100 Subject: [PATCH 02/11] Added mapping for allergy categories used by cbord --- src/main/resources/hl7/codesystem/v2ToFhirMapping.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/hl7/codesystem/v2ToFhirMapping.yml b/src/main/resources/hl7/codesystem/v2ToFhirMapping.yml index a9a99873..f7f071f1 100644 --- a/src/main/resources/hl7/codesystem/v2ToFhirMapping.yml +++ b/src/main/resources/hl7/codesystem/v2ToFhirMapping.yml @@ -7,8 +7,10 @@ AllergyIntoleranceCategory: AA: environment DA: medication + DRUG: medication EA: environment FA: food + FOOD: food LA: environment PA: environment AllergyIntoleranceCriticality: From 9821af11c4650f550f0655e2538a36f1e6581c88 Mon Sep 17 00:00:00 2001 From: Terry O'Neill Date: Fri, 3 Dec 2021 10:38:48 +1100 Subject: [PATCH 03/11] Enabled support for ADT_A04, ADT_A05 and ADT_A31 (minor changes only) --- src/main/resources/config.properties | 4 +- src/main/resources/hl7/message/ADT_A05.yml | 52 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/hl7/message/ADT_A05.yml diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties index efa7f6a2..d4618360 100644 --- a/src/main/resources/config.properties +++ b/src/main/resources/config.properties @@ -1,4 +1,4 @@ base.path.resource= -supported.hl7.messages=ADT_A01, ADT_A08, ADT_A34, ADT_A40, ADT_A60, MDM_T02, MDM_T06, ORM_O01, OMP_O09, ORU_R01, PPR_PC1, RDE_O11, RDE_O25, VXU_V04 -default.zoneid=+08:00 +supported.hl7.messages=ADT_A01, ADT_A04, ADT_A05, ADT_A08, ADT_A31, ADT_A34, ADT_A40, ADT_A60, MDM_T02, MDM_T06, ORM_O01, OMP_O09, ORU_R01, PPR_PC1, RDE_O11, RDE_O25, VXU_V04 +default.zoneid=+11:00 additional.conceptmap.file= \ No newline at end of file diff --git a/src/main/resources/hl7/message/ADT_A05.yml b/src/main/resources/hl7/message/ADT_A05.yml new file mode 100644 index 00000000..d1d161a0 --- /dev/null +++ b/src/main/resources/hl7/message/ADT_A05.yml @@ -0,0 +1,52 @@ +# FHIR Resources to extract from ADT_A60 message +--- +resources: + - resourceName: MessageHeader + segment: MSH + resourcePath: resource/MessageHeader + repeats: false + isReferenced: false + additionalSegments: + - EVN + + - resourceName: Patient + segment: PID + resourcePath: resource/Patient + repeats: false + isReferenced: true + additionalSegments: + - PD1 + - MSH + + - resourceName: Encounter + segment: PV1 + resourcePath: resource/Encounter + repeats: false + isReferenced: true + additionalSegments: + - PV2 + - EVN + - MSH + - OBX + + - resourceName: Observation + segment: OBX + resourcePath: resource/Observation + repeats: true + isReferenced: true + additionalSegments: + - MSH + + - resourceName: AllergyIntolerance + segment: AL1 + resourcePath: resource/AllergyIntolerance + repeats: true + additionalSegments: + - MSH + + - resourceName: Condition + segment: DG1 + resourcePath: resource/Condition + repeats: true + additionalSegments: + - MSH \ No newline at end of file From 7e4f6530bd70c5efda247f7ef042c819ac3546d1 Mon Sep 17 00:00:00 2001 From: Terry O'Neill Date: Fri, 3 Dec 2021 10:39:38 +1100 Subject: [PATCH 04/11] configuration changes specific to pegacorn --- build.gradle | 3 ++- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ffbc45c6..8e03e0c4 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,8 @@ plugins { id 'signing' } -group = 'io.github.linuxforhealth' +// group = 'io.github.linuxforhealth' +group = 'net.fhirfactory.pegacorn' version = (findProperty('version') == 'unspecified') ? '1.0.1-SNAPSHOT' : version ext.isReleaseVersion = !version.endsWith("SNAPSHOT") diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 12d38de6..a5f05cc7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip +distributionUrl=https\://downloads.gradle-dn.com/distributions/gradle-6.6.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From e71b61a3cf5da87ec8b054a972288e187d6d3a6f Mon Sep 17 00:00:00 2001 From: Terry O'Neill Date: Mon, 6 Dec 2021 12:44:47 +1100 Subject: [PATCH 05/11] Added FHIR Location tree creation under Encounter from input PV1 segment --- src/main/resources/fhir/resourcemapping.yml | 1 + src/main/resources/hl7/resource/Encounter.yml | 6 + src/main/resources/hl7/resource/Location.yml | 215 ++++++++++++++++++ .../hl7/resource/Location_Building.yml | 62 +++++ .../hl7/resource/Location_Facility.yml | 26 +++ .../resources/hl7/resource/Location_Floor.yml | 94 ++++++++ .../hl7/resource/Location_PointOfCare.yml | 128 +++++++++++ .../resources/hl7/resource/Location_Room.yml | 166 ++++++++++++++ .../hl7/secondary/EncounterLocation.yml | 6 + 9 files changed, 704 insertions(+) create mode 100644 src/main/resources/hl7/resource/Location.yml create mode 100644 src/main/resources/hl7/resource/Location_Building.yml create mode 100644 src/main/resources/hl7/resource/Location_Facility.yml create mode 100644 src/main/resources/hl7/resource/Location_Floor.yml create mode 100644 src/main/resources/hl7/resource/Location_PointOfCare.yml create mode 100644 src/main/resources/hl7/resource/Location_Room.yml create mode 100644 src/main/resources/hl7/secondary/EncounterLocation.yml diff --git a/src/main/resources/fhir/resourcemapping.yml b/src/main/resources/fhir/resourcemapping.yml index 673b365e..fe9ec11c 100644 --- a/src/main/resources/fhir/resourcemapping.yml +++ b/src/main/resources/fhir/resourcemapping.yml @@ -12,6 +12,7 @@ Condition: org.hl7.fhir.r4.model.Condition Practitioner: org.hl7.fhir.r4.model.Practitioner DiagnosticReport: org.hl7.fhir.r4.model.DiagnosticReport Immunization: org.hl7.fhir.r4.model.Immunization +Location: org.hl7.fhir.r4.model.Location Organization: org.hl7.fhir.r4.model.Organization MessageHeader: org.hl7.fhir.r4.model.MessageHeader Medication: org.hl7.fhir.r4.model.Medication diff --git a/src/main/resources/hl7/resource/Encounter.yml b/src/main/resources/hl7/resource/Encounter.yml index 6542fd5e..825a3896 100644 --- a/src/main/resources/hl7/resource/Encounter.yml +++ b/src/main/resources/hl7/resource/Encounter.yml @@ -202,6 +202,12 @@ participant_4: codeableConceptCode: 'ADM' codeableConceptText: 'admitter' +location: + valueOf: secondary/EncounterLocation + generateList: true + expressionType: resource + specs: PV1.3 | PV1.6 | PV1.11 | PV1.42 | PV1.43 + extension_1: generateList: true expressionType: nested diff --git a/src/main/resources/hl7/resource/Location.yml b/src/main/resources/hl7/resource/Location.yml new file mode 100644 index 00000000..694dd585 --- /dev/null +++ b/src/main/resources/hl7/resource/Location.yml @@ -0,0 +1,215 @@ +# A location tree based on HL7 Person Location (PL) for bed or more general based on this order: +# Bed (PL.3) > Room (PL.2) > Point of Care (PL.1) > Floor (PL.8) > Building (PL.7) > Facility (PL.4) +--- +resourceType: Location +id: + type: STRING + valueOf: UUID.randomUUID() + expressionType: JEXL + +name_1: + condition: $bed NOT_NULL + type: STRING + valueOf: PL.3 + expressionType: HL7Spec + vars: + bed: PL.3 + +name_2: + condition: $bed NULL && $room NOT_NULL + type: STRING + valueOf: PL.2 + expressionType: HL7Spec + vars: + bed: PL.3 + room: PL.2 + +name_3: + condition: $bed NULL && $room NULL && $pointofcare NOT_NULL + type: STRING + valueOf: PL.1 + expressionType: HL7Spec + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + +name_4: + condition: $bed NULL && $room NULL && $pointofcare NULL && $floor NOT_NULL + type: STRING + valueOf: PL.8 + expressionType: HL7Spec + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + +name_5: + condition: $bed NULL && $room NULL && $pointofcare NULL && $floor NULL && $building NOT_NULL + type: STRING + valueOf: PL.7 + expressionType: HL7Spec + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + +name_6: + condition: $bed NULL && $room NULL && $pointofcare NULL && $floor NULL && $building NULL && $facility NOT_NULL + type: STRING + valueOf: PL.4 + expressionType: HL7Spec + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + facility: PL.4 + +partOf_1: + condition: $bed NOT_NULL + valueOf: resource/Location_Room + expressionType: reference + specs: PL + vars: + bed: PL.3 + +partOf_2: + condition: $bed NULL && $room NOT_NULL + valueOf: resource/Location_PointOfCare + expressionType: reference + specs: PL + vars: + bed: PL.3 + room: PL.2 + +partOf_3: + condition: $bed NULL && $room NULL && $pointofcare NOT_NULL + valueOf: resource/Location_Floor + expressionType: reference + specs: PL + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + +partOf_4: + condition: $bed NULL && $room NULL && $pointofcare NULL && $floor NOT_NULL + valueOf: resource/Location_Building + expressionType: reference + specs: PL + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + +partOf_5: + condition: $bed NULL && $room NULL && $pointofcare NULL && $floor NULL && $building NOT_NULL + valueOf: resource/Location_Facility + expressionType: reference + specs: PL + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + +physicalType_1: + condition: $bed NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'bd' + text: 'Bed' + vars: + bed: PL.3 + +physicalType_2: + condition: $bed NULL && $room NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'ro' + text: 'Room' + vars: + bed: PL.3 + room: PL.2 + +physicalType_3: + condition: $bed NULL && $room NULL && $pointofcare NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'wa' + text: 'Ward' + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + +physicalType_4: + condition: $bed NULL && $room NULL && $pointofcare NULL && $floor NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'lvl' + text: 'Level' + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + +physicalType_5: + condition: $bed NULL && $room NULL && $pointofcare NULL && $floor NULL && $building NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'bu' + text: 'Building' + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + +physicalType_6: + condition: $bed NULL && $room NULL && $pointofcare NULL && $floor NULL && $building NULL && $facility NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'si' + text: 'Site' + vars: + bed: PL.3 + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + facility: PL.4 + +mode: + type: STRING + value: 'instance' + +description: + type: STRING + valueOf: PL.9 + expressionType: HL7Spec + +# ToDo map PL.6 (Person Location Type) to type (just for this file; not in sub-locations) + +# ToDo check if PL.5 (Location Status) can be mapped to status \ No newline at end of file diff --git a/src/main/resources/hl7/resource/Location_Building.yml b/src/main/resources/hl7/resource/Location_Building.yml new file mode 100644 index 00000000..60fc1a2e --- /dev/null +++ b/src/main/resources/hl7/resource/Location_Building.yml @@ -0,0 +1,62 @@ +# Do not reference directly: use resource/Location +# A sub-location for under a floor. Much like resource/Location but ignoring +# the bed (PL.3), room (PL.2), point of care (PL.1) and floor (PL.8) for name +# and partOf +--- +resourceType: Location +id: + type: STRING + valueOf: UUID.randomUUID() + expressionType: JEXL + +name_1: + condition: $building NOT_NULL + type: STRING + valueOf: PL.7 + expressionType: HL7Spec + vars: + building: PL.7 + +name_2: + condition: $building NULL && $facility NOT_NULL + type: STRING + valueOf: PL.4 + expressionType: HL7Spec + vars: + building: PL.7 + facility: PL.4 + +partOf_1: + condition: $building NOT_NULL + valueOf: resource/Location_Facility + expressionType: reference + specs: PL + vars: + building: PL.7 + +physicalType_1: + condition: $building NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'bu' + text: 'Building' + vars: + building: PL.7 + +physicalType_2: + condition: $building NULL && $facility NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'si' + text: 'Site' + vars: + building: PL.7 + facility: PL.4 + +mode: + type: STRING + value: 'instance' \ No newline at end of file diff --git a/src/main/resources/hl7/resource/Location_Facility.yml b/src/main/resources/hl7/resource/Location_Facility.yml new file mode 100644 index 00000000..18facf88 --- /dev/null +++ b/src/main/resources/hl7/resource/Location_Facility.yml @@ -0,0 +1,26 @@ +# Do not reference directly: use resource/Location +# A sub-location for under a building. Much like resource/Location only using +# facility (PL.4) for name (as this is the top level location in PL) +--- +resourceType: Location +id: + type: STRING + valueOf: UUID.randomUUID() + expressionType: JEXL + +name: + type: STRING + valueOf: PL.4 + expressionType: HL7Spec + +physicalType: + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'si' + text: 'Site' + +mode: + type: STRING + value: 'instance' \ No newline at end of file diff --git a/src/main/resources/hl7/resource/Location_Floor.yml b/src/main/resources/hl7/resource/Location_Floor.yml new file mode 100644 index 00000000..7c47b8a5 --- /dev/null +++ b/src/main/resources/hl7/resource/Location_Floor.yml @@ -0,0 +1,94 @@ +# Do not reference directly: use resource/Location +# A sub-location for under a point of care. Much like resource/Location but +# ignoring the bed (PL.3), room (PL.2) and point of care (PL.1) for name and +# partOf +--- +resourceType: Location +id: + type: STRING + valueOf: UUID.randomUUID() + expressionType: JEXL + +name_1: + condition: $floor NOT_NULL + type: STRING + valueOf: PL.8 + expressionType: HL7Spec + vars: + floor: PL.8 + +name_2: + condition: $floor NULL && $building NOT_NULL + type: STRING + valueOf: PL.7 + expressionType: HL7Spec + vars: + floor: PL.8 + building: PL.7 + +name_3: + condition: $floor NULL && $building NULL && $facility NOT_NULL + type: STRING + valueOf: PL.4 + expressionType: HL7Spec + vars: + floor: PL.8 + building: PL.7 + facility: PL.4 + +partOf_1: + condition: $floor NOT_NULL + valueOf: resource/Location_Building + expressionType: reference + specs: PL + vars: + floor: PL.8 + +partOf_2: + condition: $floor NULL && $building NOT_NULL + valueOf: resource/Location_Facility + expressionType: reference + specs: PL + vars: + floor: PL.8 + building: PL.7 + +physicalType_1: + condition: $floor NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'lvl' + text: 'Level' + vars: + floor: PL.8 + +physicalType_2: + condition: $floor NULL && $building NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'bu' + text: 'Building' + vars: + floor: PL.8 + building: PL.7 + +physicalType_3: + condition: $floor NULL && $building NULL && $facility NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'si' + text: 'Site' + vars: + floor: PL.8 + building: PL.7 + facility: PL.4 + +mode: + type: STRING + value: 'instance' \ No newline at end of file diff --git a/src/main/resources/hl7/resource/Location_PointOfCare.yml b/src/main/resources/hl7/resource/Location_PointOfCare.yml new file mode 100644 index 00000000..4989e1a8 --- /dev/null +++ b/src/main/resources/hl7/resource/Location_PointOfCare.yml @@ -0,0 +1,128 @@ +# Do not reference directly: use resource/Location +# A sub-location for under a room. Much like resource/Location but ignoring the +# bed (PL.3) and room (PL.2) for name and partOf +--- +resourceType: Location +id: + type: STRING + valueOf: UUID.randomUUID() + expressionType: JEXL + +name_1: + condition: $pointofcare NOT_NULL + type: STRING + valueOf: PL.1 + expressionType: HL7Spec + vars: + pointofcare: PL.1 + +name_2: + condition: $pointofcare NULL && $floor NOT_NULL + type: STRING + valueOf: PL.8 + expressionType: HL7Spec + vars: + pointofcare: PL.1 + floor: PL.8 + +name_3: + condition: $pointofcare NULL && $floor NULL && $building NOT_NULL + type: STRING + valueOf: PL.7 + expressionType: HL7Spec + vars: + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + +name_4: + condition: $pointofcare NULL && $floor NULL && $building NULL && $facility NOT_NULL + type: STRING + valueOf: PL.4 + expressionType: HL7Spec + vars: + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + facility: PL.4 + +partOf_1: + condition: $pointofcare NOT_NULL + valueOf: resource/Location_Floor + expressionType: reference + specs: PL + vars: + pointofcare: PL.1 + +partOf_2: + condition: $pointofcare NULL && $floor NOT_NULL + valueOf: resource/Location_Building + expressionType: reference + specs: PL + vars: + pointofcare: PL.1 + floor: PL.8 + +partOf_3: + condition: $pointofcare NULL && $floor NULL && $building NOT_NULL + valueOf: resource/Location_Facility + expressionType: reference + specs: PL + vars: + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + +physicalType_1: + condition: $pointofcare NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'wa' + text: 'Ward' + vars: + pointofcare: PL.1 + +physicalType_2: + condition: $pointofcare NULL && $floor NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'lvl' + text: 'Level' + vars: + pointofcare: PL.1 + floor: PL.8 + +physicalType_3: + condition: $pointofcare NULL && $floor NULL && $building NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'bu' + text: 'Building' + vars: + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + +physicalType_4: + condition: $pointofcare NULL && $floor NULL && $building NULL && $facility NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'si' + text: 'Site' + vars: + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + facility: PL.4 + +mode: + type: STRING + value: 'instance' \ No newline at end of file diff --git a/src/main/resources/hl7/resource/Location_Room.yml b/src/main/resources/hl7/resource/Location_Room.yml new file mode 100644 index 00000000..47b59b10 --- /dev/null +++ b/src/main/resources/hl7/resource/Location_Room.yml @@ -0,0 +1,166 @@ +# Do not reference directly: use resource/Location +# A sub-location for under a bed. Much like resource/Location but ignoring the +# bed (PL.3) for name and partOf +--- +resourceType: Location +id: + type: STRING + valueOf: UUID.randomUUID() + expressionType: JEXL + +name_1: + condition: $room NOT_NULL + type: STRING + valueOf: PL.2 + expressionType: HL7Spec + vars: + room: PL.2 + +name_2: + condition: $room NULL && $pointofcare NOT_NULL + type: STRING + valueOf: PL.1 + expressionType: HL7Spec + vars: + room: PL.2 + pointofcare: PL.1 + +name_3: + condition: $room NULL && $pointofcare NULL && $floor NOT_NULL + type: STRING + valueOf: PL.8 + expressionType: HL7Spec + vars: + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + +name_4: + condition: $room NULL && $pointofcare NULL && $floor NULL && $building NOT_NULL + type: STRING + valueOf: PL.7 + expressionType: HL7Spec + vars: + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + +name_5: + condition: $room NULL && $pointofcare NULL && $floor NULL && $building NULL && $facility NOT_NULL + type: STRING + valueOf: PL.4 + expressionType: HL7Spec + vars: + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + facility: PL.4 + +partOf_1: + condition: $room NOT_NULL + valueOf: resource/Location_PointOfCare + expressionType: reference + specs: PL + vars: + room: PL.2 + +partOf_2: + condition: $room NULL && $pointofcare NOT_NULL + valueOf: resource/Location_Floor + expressionType: reference + specs: PL + vars: + room: PL.2 + pointofcare: PL.1 + +partOf_3: + condition: $room NULL && $pointofcare NULL && $floor NOT_NULL + valueOf: resource/Location_Building + expressionType: reference + specs: PL + vars: + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + +partOf_4: + condition: $room NULL && $pointofcare NULL && $floor NULL && $building NOT_NULL + valueOf: resource/Location_Facility + expressionType: reference + specs: PL + vars: + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + +physicalType_1: + condition: $room NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'ro' + text: 'Room' + vars: + room: PL.2 + +physicalType_2: + condition: $room NULL && $pointofcare NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'wa' + text: 'Ward' + vars: + room: PL.2 + pointofcare: PL.1 + +physicalType_3: + condition: $room NULL && $pointofcare NULL && $floor NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'lvl' + text: 'Level' + vars: + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + +physicalType_4: + condition: $room NULL && $pointofcare NULL && $floor NULL && $building NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'bu' + text: 'Building' + vars: + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + +physicalType_5: + condition: $room NULL && $pointofcare NULL && $floor NULL && $building NULL && $facility NOT_NULL + valueOf: datatype/CodeableConcept_var + expressionType: resource + constants: + system: 'http://hl7.org/fhir/ValueSet/location-physical-type' + code: 'si' + text: 'Site' + vars: + room: PL.2 + pointofcare: PL.1 + floor: PL.8 + building: PL.7 + facility: PL.4 + +mode: + type: STRING + value: 'instance' \ No newline at end of file diff --git a/src/main/resources/hl7/secondary/EncounterLocation.yml b/src/main/resources/hl7/secondary/EncounterLocation.yml new file mode 100644 index 00000000..9cda414f --- /dev/null +++ b/src/main/resources/hl7/secondary/EncounterLocation.yml @@ -0,0 +1,6 @@ +# A location under an encounter (references an actual Location type) +--- +location: + valueOf: resource/Location + expressionType: reference + specs: PL From de9e6d9437dccee0906f31c23e732bf304e893ec Mon Sep 17 00:00:00 2001 From: Terry O'Neill Date: Tue, 7 Dec 2021 14:43:11 +1100 Subject: [PATCH 06/11] Created pom.xml for ease of building in maven --- pom.xml | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 pom.xml diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..f79efe24 --- /dev/null +++ b/pom.xml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + 4.0.0 + + + + + + + + + net.fhirfactory.pegacorn + pegacorn + 1.0.0-SNAPSHOT + + + hl7v2-fhir-converter + jar + 1.0.1-SNAPSHOT + + Pegacorn :: HL7-FHIR-Converter + Converter of HL7 to FHIR JSON + + + + + + + + + + + + org.apache.commons + commons-lang3 + 3.9 + + + org.apache.commons + commons-math3 + 3.6.1 + + + com.fasterxml.jackson.core + jackson-databind + 2.10.1 + + + com.google.guava + guava + 23.0 + + + commons-io + commons-io + 2.6 + + + ca.uhn.hapi + hapi-base + 2.3 + + + ca.uhn.hapi + hapi-structures-v26 + 2.3 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.10.1 + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + 2.10.1 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.10.1 + + + org.apache.commons + commons-text + 1.8 + + + ca.uhn.hapi.fhir + hapi-fhir-structures-r4 + 5.1.0 + + + ca.uhn.hapi.fhir + hapi-fhir-structures-r5 + 5.1.0 + + + ca.uhn.hapi.fhir + hapi-fhir-validation + 5.1.0 + + + ca.uhn.hapi.fhir + hapi-fhir-validation-resources-r4 + 5.1.0 + + + org.apache.commons + commons-jexl3 + 3.1 + + + org.apache.commons + commons-configuration2 + 2.7 + + + org.apache.commons + commons-collections4 + 4.4 + + + com.ibm.fhir + fhir-registry + 4.9.0 + + + com.ibm.fhir + fhir-term + 4.9.0 + + + commons-beanutils + commons-beanutils + 1.9.4 + + + ch.qos.logback + logback-classic + 1.2.3 + test + + + org.assertj + assertj-core + 3.9.0 + test + + + jakarta.json + jakarta.json-api + 2.0.1 + test + + + org.junit.jupiter + junit-jupiter-api + 5.7.2 + test + + + org.junit.jupiter + junit-jupiter-params + 5.7.2 + test + + + + + + + + ch.qos.logback + logback-classic + ${version-ch.qos.logback-classic} + compile + + + + ch.qos.logback + logback-core + ${version-ch.qos.logback-classic} + compile + + + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${version-org.apache.maven-compiler-plugin} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${version-org.apache.maven-surefire-plugin} + + + org.apache.maven.plugins + maven-failsafe-plugin + ${version-org.apache.maven-failsafe-plugin} + + + + + + + + + + + + + + + default + + true + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${version-org.apache.maven-surefire-plugin} + + true + + + + + + + + From cd2e10eee6ed04bcc66d89fc8a4efcaab5749d52 Mon Sep 17 00:00:00 2001 From: Terry O'Neill Date: Wed, 8 Dec 2021 11:57:01 +1100 Subject: [PATCH 07/11] Added fallback processing for any Trigger Event type to try to handle PID and PV1 only --- .../hl7/HL7ToFHIRConverter.java | 11 ++++++- src/main/resources/config.properties | 2 +- .../resources/hl7/message/Fallback_Base.yml | 32 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/hl7/message/Fallback_Base.yml diff --git a/src/main/java/io/github/linuxforhealth/hl7/HL7ToFHIRConverter.java b/src/main/java/io/github/linuxforhealth/hl7/HL7ToFHIRConverter.java index 23f4c3c8..1d164c31 100644 --- a/src/main/java/io/github/linuxforhealth/hl7/HL7ToFHIRConverter.java +++ b/src/main/java/io/github/linuxforhealth/hl7/HL7ToFHIRConverter.java @@ -40,6 +40,7 @@ public class HL7ToFHIRConverter { private static HL7HapiParser hparser = new HL7HapiParser(); private static final Logger LOGGER = LoggerFactory.getLogger(HL7ToFHIRConverter.class); + private static final String FALLBACK_BASE = "Fallback_Base"; // fallback configuration file to use when Trigger Event does not match anything (only used if enabled in supported.hl7.messages) private Map messagetemplates = new HashMap<>(); /** @@ -130,7 +131,15 @@ public String convert(String hl7MessageData, ConverterOptions options) { if (hl7MessageTemplateModel != null) { return hl7MessageTemplateModel.convert(hl7message, engine); } else { - throw new UnsupportedOperationException("Message type not yet supported " + messageType); + // try to get the our fallback template + hl7MessageTemplateModel = messagetemplates.get(FALLBACK_BASE); + if (hl7MessageTemplateModel != null) { + // fallback template is enabled so use it just like a normal message template model + return hl7MessageTemplateModel.convert(hl7message, engine); + } else { + // it is not enabled by being in the supported.hl7.messages + throw new UnsupportedOperationException("Message type not yet supported " + messageType); + } } } else { throw new IllegalArgumentException("Parsed HL7 message was null."); diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties index d4618360..83000fe2 100644 --- a/src/main/resources/config.properties +++ b/src/main/resources/config.properties @@ -1,4 +1,4 @@ base.path.resource= -supported.hl7.messages=ADT_A01, ADT_A04, ADT_A05, ADT_A08, ADT_A31, ADT_A34, ADT_A40, ADT_A60, MDM_T02, MDM_T06, ORM_O01, OMP_O09, ORU_R01, PPR_PC1, RDE_O11, RDE_O25, VXU_V04 +supported.hl7.messages=Fallback_Base, ADT_A01, ADT_A04, ADT_A05, ADT_A08, ADT_A31, ADT_A34, ADT_A40, ADT_A60, MDM_T02, MDM_T06, ORM_O01, OMP_O09, ORU_R01, PPR_PC1, RDE_O11, RDE_O25, VXU_V04 default.zoneid=+11:00 additional.conceptmap.file= \ No newline at end of file diff --git a/src/main/resources/hl7/message/Fallback_Base.yml b/src/main/resources/hl7/message/Fallback_Base.yml new file mode 100644 index 00000000..15d2097e --- /dev/null +++ b/src/main/resources/hl7/message/Fallback_Base.yml @@ -0,0 +1,32 @@ +# FHIR Resources to extract from an unknown base as a fallback +# tries to get out patient and encounter data only +# to return to normal functionality without this fallback processing simply +# remove Fallback_Base from the supported.hl7.messages in config.properties +--- +resources: + - resourceName: MessageHeader + segment: MSH + resourcePath: resource/MessageHeader + repeats: false + isReferenced: false + additionalSegments: + - EVN + + - resourceName: Patient + segment: PID + resourcePath: resource/Patient + repeats: false + isReferenced: true + additionalSegments: + - MSH + + + - resourceName: Encounter + segment: PV1 + resourcePath: resource/Encounter + repeats: false + isReferenced: true + additionalSegments: + - PV2 + - EVN + - MSH From 41827ab7011ac632f82bb87c4ac1254a6c62009c Mon Sep 17 00:00:00 2001 From: Terry O'Neill Date: Tue, 4 Jan 2022 17:26:53 +1100 Subject: [PATCH 08/11] Updated artifact id to match changes to pegacorn-ponos --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f79efe24..af5b8d1d 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 1.0.0-SNAPSHOT - hl7v2-fhir-converter + pegacorn-hl7v2-fhir-converter jar 1.0.1-SNAPSHOT From 689b40c5cfe86b9c9bfbbb000212b057d8664b4c Mon Sep 17 00:00:00 2001 From: akinboj Date: Fri, 7 Jan 2022 17:08:33 +1100 Subject: [PATCH 09/11] Updated pom file --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index af5b8d1d..87f9623c 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ net.fhirfactory.pegacorn pegacorn - 1.0.0-SNAPSHOT + 1.5.0-SNAPSHOT pegacorn-hl7v2-fhir-converter From 12fe0a13ece3faf5d0d121024e798e46433354b3 Mon Sep 17 00:00:00 2001 From: Terry O'Neill Date: Mon, 10 Jan 2022 11:34:21 +1100 Subject: [PATCH 10/11] Altered pom to have parent of pegacorn-ponos and include relative path --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 87f9623c..1e271276 100644 --- a/pom.xml +++ b/pom.xml @@ -23,8 +23,9 @@ net.fhirfactory.pegacorn - pegacorn + pegacorn-ponos 1.5.0-SNAPSHOT + ../pegacorn-ponos pegacorn-hl7v2-fhir-converter From 07c36664fcee6c89e2f15d563ddd5cdd8c20cf7e Mon Sep 17 00:00:00 2001 From: "Mark A. Hunter" Date: Sat, 12 Mar 2022 13:55:45 +1100 Subject: [PATCH 11/11] Support for Patient Identifier --- pom.xml | 4 ++-- src/main/resources/hl7/resource/Patient.yml | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1e271276..07d6bf78 100644 --- a/pom.xml +++ b/pom.xml @@ -23,9 +23,9 @@ net.fhirfactory.pegacorn - pegacorn-ponos + pegacorn 1.5.0-SNAPSHOT - ../pegacorn-ponos + ../pegacorn pegacorn-hl7v2-fhir-converter diff --git a/src/main/resources/hl7/resource/Patient.yml b/src/main/resources/hl7/resource/Patient.yml index 9fc5fe12..52b1bd32 100644 --- a/src/main/resources/hl7/resource/Patient.yml +++ b/src/main/resources/hl7/resource/Patient.yml @@ -54,6 +54,18 @@ identifier_4: use: old mrgIdentifier: MRG.1 # Add the old MR # from the MRG segment +identifier_5: + condition: $valueIn NOT_NULL + valueOf: datatype/Identifier_var + generateList: true + expressionType: resource + specs: PID.2 + vars: + valueIn: String, PID.2.1 + constants: + system: http://terminology.hl7.org/CodeSystem/v2-0203 + code: MR + display: Medical Record Number name: valueOf: datatype/HumanName