Giter VIP home page Giter VIP logo

hl7v2-fhir-converter's Introduction

LinuxForHealth HL7 to FHIR Converter

The LinuxForHealth HL7 to FHIR converter is a Java based library that enables converting HL7v2 messages to FHIR resources in a declarative and configuration based manner.

Message parsing and modeling is supported using the "HAPI" libraries for HL7 and FHIR respectively.

The converter supports the following message types/events:

  • ADT_A01 - Patient Administration: Admit/Visit Notification
  • ADT_A03 - Patient Administration: Discharge/End Visit
  • ADT_A04 - Patient Administration: Register a Patient
  • ADT_A08 - Patient Administration: Update Patient Information
  • ADT_A28 - Patient Administration: Add Person or Patient Information
  • ADT_A31 - Patient Administration: Update Person Information
  • ADT_A34 - Patient Administration: Merge Patient Information - Patient ID Only
  • ADT_A40 - Patient Administration: Merge Patient - Patient Identifier List
  • DFT_P03 - Post Detail Financial Transaction (does not convert FT1)
  • MDM_T02 - Original Document Notifcication and Content
  • MDM_T06 - Document Addendum Notification and Content
  • OMP_O09 - Pharmacy/Treatment Order
  • ORM_O01 - General Order Message
  • ORU_R01 - Observation Reporting: Observation and Result Transmission (Laboratory)
  • PPR_PC1 - Patient Problem: Add Problem
  • RDE_O11 - Pharmacy/Treatment Encoded Order
  • RDE_O25 - Pharmacy/Treatment Refill Authorization Request
  • VXU_V04 - Vaccination: Update Vaccination Record

The converter supports the following message segments:

  • AL1 - Patient Allergy Information
  • DG1 - Diagnosis
  • EVN - Event Type
  • IN1 - Insurance
  • IN2 - Insurance Additional Information
  • MRG - Merge Patient Information
  • MSH - Message Header
  • NTE - Notes and Comments
  • OBR - Observation Request
  • OBX - Observation/Result
  • ORC - Common Order
  • PD1 - Patient Additional Demographic
  • PID - Patient Identification
  • PRB - Problem Details
  • PV1 - Patient Visit
  • PV2 - Patient Visit - Additional Information
  • RXA - Pharmacy/Treatment Administration
  • RXC - Pharmacy/Treatment Component Order
  • RXE - Pharmacy/Treatment Encoded Order
  • RXO - Pharmacy/Treatment Order (Ignored for RDE messages; RXE used instead)
  • RXR - Pharmacy/Treatment Route
  • SPM - Specimen
  • TXA - Transcription Document Header

The converter partially supports the following message types/events:

  • OML_O21 - Laboratory Order
    • Repeating ORDER groups are not supported
    • ServiceRequest resources are only created when both ORC and OBR are provided
    • PID must be provided to avoid FHIR validation errors
    • OBX and Observations are not yet supported

If you need another message type/event . . . contributions are welcome! See CONTRIBUTING.md!

Additional Documentation

Development Quickstart

The FHIR Converter has the following dependencies:

  • JDK 11 or later (upgraded on 10/28/21, version 1.0.12 and earlier supported Java 8)
  • Gradle

Note: The FHIR Converter includes a Gradle Wrapper, so a local Gradle install is not required.

Clone and build the project:

git clone [email protected]:LinuxForHealth/hl7v2-fhir-converter.git
cd hl7v2-fhir-converter
./gradlew build

Using the Converter in a Java Application

The HL7 to FHIR converter library is available as a maven dependency.

Library Coordinates

groupId = io.github.linuxforhealth
artifactId = hl7v2-fhir-converter
version = 1.0.10

Maven dependency

<dependency>
  <groupId>io.github.linuxforhealth</groupId>
  <artifactId>hl7v2-fhir-converter</artifactId>
  <version>1.0.10</version>
</dependency>

Gradle dependency:

    implementation 'io.github.linuxforhealth:hl7v2-fhir-converter:1.0.10'

Instantiate and execute the converter

    HL7ToFHIRConverter ftv = new HL7ToFHIRConverter();
    String output= ftv.convert(hl7message); // generated a FHIR output

Converter Configuration:

The converter configuration file, config.properties, supports the following settings

Property Name Description Example Value
base.path.resource Path to resource templates (optional). If not specified the library's default resources under src/resources are used. /opt/converter/resources
supported.hl7.messages Comma delimited list of hl7 message/event types. An asterisk * may be used to indicate all messages found in sub-directory /hl7/messages under the base.path.resource and sub-directory /hl7/messages under additional.resources.location are supported. If not specified, defaults to *. ADT_A01, ORU_R01, PPR_PC1
default.zoneid ISO 8601 timezone offset (optional). The zoneid is converted to java.time.ZoneId and applied to translations when the target FHIR resource field requires a timezone, but the source HL7 field does not include it. Requires a valid string value for java.time.ZoneId. +08:00
additional.conceptmap Path to additional concept map configuration. Concept maps are used for mapping one code system to another. /opt/converter/concept-map.yaml
additional.resources.location Path to additional resources. These supplement those base.path.resource. /opt/supplemental/resources

HL7 Converter Configuration Property Location

The config.properties file location is searched in the following order:

  • HL7CONVERTER_CONFIG_HOME environment variable is checked first

  • hl7converter.config.home system property is checked next

    -Dhl7converter.config.home=/opt/converter/config_home_folder/

  • Lastly, the local classpath resource folder will be searched for config.properties

Converter Runtime Parameters

The converter allows passing of certain parameters at run time through the options.

Parameter Name Description Example Call on Options Creation
ZoneIdText ZoneId override for the ISO 8601 timezone offset. Overrides default.zoneid in config.properties. Requires a valid ZoneId text value, which is converted to a java.time.ZoneId. options.withZoneIdText("+07:00") options.withZoneIdText("America/Chicago")
Property (Key/Value) A string property expressed as a key / value pair. Properties become available as variables to the templates. A property TENANT with value myTenantId is utilized in templates as $TENANT. options.withProperty("TENANT","myTenantId")

PHI (Protected Health Information)

Since this converter is used in production environments using real patient data it can not log or print out anything that may contain PHI data. We will be stripping out all debug log statements as part of the build. This allows developers to use these debug statements to debug issues with santized unit test data.

  • Please do not add any print outs (ie system.out.println etc). Use the logger.
  • When adding / editing current or future error, warn, and info log statements please be careful to not add any data structures that might contain PHI. If you aren't sure then make the log statement debug so it's stripped out.

Local development gradle build switch (localDevEnv)

Before the gradle build step where the compile happens the gradle build copies the src directory to the target directoy and sets the gradle build sourcesets to the target directory. Then it strips out all LOGGER.debug statements. This means the compile/build runs off the target directory where the debug statements have been stripped. However if you are running locally you still want the build to run off the src directory or otherwise you must build after each change to get it copied to the target directory. There is a flag in the gradle.properties named localDevEnv which should always be set to false in GIT but a developer can override this flag to true and the local build will keep the sourcesets tied to the src directory.

hl7v2-fhir-converter's People

Contributors

ayushgarg0694 avatar cjstadler avatar cragun47 avatar deangeliscm avatar dixonwhitmire avatar evbaron avatar hajiratasneem avatar jgrant22 avatar jorg3lopez avatar klwhaley avatar lisadier avatar lisawellman avatar mkalish avatar mkazia avatar pbhallam avatar snesm avatar xpander53 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hl7v2-fhir-converter's Issues

Conversion of Patient's name prefix and suffix are in the inverted order.

Describe the bug
The converter converts the Patient name's prefix and suffix in the opposite order that it should be (according to the PID segment in HL7)
To Reproduce
HL7 segment : PID|1||12345678^^^^MR||Mouse^Mickey^J^III^Mr^^| ...
The order according to the HL7 reference should be : XPN.4 - Suffix and XPN.5 - Prefix
but in the current HL7toFHIR conversion I get in the .json:
Output:
"name": [
{
"family": "Mouse",
"given": [
"Mickey"
],
"prefix": [
"III"
],
"suffix": [
"Mr"

Expected behavior
"Mr" should be the prefix and "III" the suffix.

Screenshots

Desktop (please complete the following information):

  • OS: MacOS
  • Version Big Sur

Additional context

map Immunization dosage

Describe the enhancement:
Enhance converter to handle immunization dosage (amount and units)

Expected behavior:
HL7 converter should be able to handle immunization dosage and units

Desktop:
OS: Mac OS
Version Big Sur

Add additional patient Identification types.

Add more patient Identification types and improve the format.

  1. Add SSN from PID.19

  2. Instead of creating Assigning Authority references, add the CX.4 assigning authority as a system Id.
    Example:
    PID.3: 12345678^^^ID-XYZ^MR~111223333^^^USA^SS~MN1234567^^^MNDOT^DL
    Should create:

"identifier": [ {
        "type": {
          "coding": [ {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "MR",
            "display": "Medical record number"
          } ],
          "text": "MR"
        },
        "system": "urn:id:ID-XYZ",
        "value": "12345678"
      }, {
        "type": {
          "coding": [ {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "SS",
            "display": "Social Security number"
          } ],
          "text": "SS"
        },
        "system": "urn:id:USA",
        "value": "111223333"
      }, {
        "type": {
          "coding": [ {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "DL",
            "display": "Driver's license number"
          } ],
          "text": "DL"
        },
        "system": "urn:id:MNDOT",
        "value": "MN1234567"
      }]

Create Test Harness For End To End Testing

This issue enhances the converter's existing test case suite with a test harness we can use to run an end to end test. An "end to end" test is simply a test that validates the FHIR Resource output for a given HL7 message template.

To support this type of test we will need to add a "test harness" which does the following:

  • loads a source HL7 message from a file resource
  • loads the expected FHIR Bundle from a file resource
  • converts the source HL7 message to a FHIR bundle
  • executes assertions against the "expected" and "actual" FHIR bundle to confirm validity

The test harness could be a parameterized Java method or a JUnit5 parameterized test case. We may not be able to do a simple comparison of JSON objects for the actual and expected resources as we don't have field ordering guarantees and some generated fields such as uuid will be unique across test case runs. Using a Comparator or similar sorting mechanism could help here.

AL1-6 is allergy onset, not reaction onset

Describe the bug
AL1-6 should map to AllergyIntolerance.onsetDateTime, not AllergyIntolerance.reaction.onset

To Reproduce
Convert any AL1 message with a value in AL1-6

Expected behavior
AL1-6 should be placed in AllergyIntolerance.onsetDateTime

Additional context
Although http://hl7.org/fhir/R4/allergyintolerance-mappings.html indicates AL1-6 is AllergyIntolerance.reaction.onset, this seems to be incorrect according to the HL7 description.
From https://hl7-definition.caristix.com/v2/HL7v2.6/Fields/AL1.6
AL1.6 - Identification Date
This field contains the date that the allergy was identified.

Capture patient's mother's maiden name and religion

Describe the bug
Create FHIR Patient.extension.patient-mothersMaidenName (well-known extension) from PID-6.1

Create FHIR Patient.extension.patient-religion (well-known extension) from PID-17, use coding in table 0006

To Reproduce
Create a sample HL7V2.6 patient PID segment with aforementioned patient information.

Expected behavior
Patient information should be detected and added to corresponding fields in HL7 FHIR resources.

Example FHIR for mother's maiden name:

extension": [
 {
    "url": "http://hl7.org/fhir/StructureDefinition/patient-mothersMaidenName",
    "valueString": "BEILY"
 }

Example FHIR for religion:

      "extension": [ {
        "url": "http://hl7.org/fhir/StructureDefinition/patient-religion",
        "valueCodeableConcept": {
          "coding": [ {
            "system": "http://terminology.hl7.org/CodeSystem/v3-ReligiousAffiliation",
            "code": "1028",
            "display": "Lutheran"
          } ],
          "text": "Lutheran"
        }
      }

Additional context
Religion in HL7 V2.6 is from table 0006. It does not have a perfect correlation to FHIR extension for religion Map clear matches from V2.6 to FHIR, but be conservative in a first pass, and unclear matches should be left unmatched.

Capture Drivers License from PID 20 in ID section

The Drivers License information in PID.20.1 should be put in the ID section.

Ignore the state / country / expiration. Capture only the number:

Example:

{
        "type": {
          "coding": [ {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
            "code": "DL",
            "display": "Driver's license number"
          } ]
        },
        "value": "D-12445889-Z"
      } 

Currently capture only the value. If State and Expiration are required, will look at it in the future.

Convert patient address information

Describe the bug
Add capability to find and convert the following patient address information

  • Patient.address / PID-11
  • Patient.address.district / PID-12. (Also known as Country code)

This was broken off from work item #94

To Reproduce
Create a sample HL7V2.6 patient PID segment with aforementioned patient information.

Expected behavior
Patient information should be detected and added to corresponding fields in HL7 FHIR resources.

Examples:

Patient Address: This should handle a complete Extended Address XAD content (should allow for multiple)

{
  "resourceType": "Patient",
  "id": "address",
  "address": [
    {
      "use": "home",
      "type": "both",
      "text": "534 Erewhon St PeasantVille, Rainbow, Vic  3999",
      "line": [
        "534 Erewhon St"
      ],
      "city": "PleasantVille",
      "district": "Rainbow",    <<< comes from PID.12
      "state": "Vic",
      "postalCode": "3999",
      "period": {
        "start": "1974-12-25"
      }
    }
  ],

District / Country code
From HL7V2.6, it is four characters of local definition.
Inserted into .address as shown above

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Mac OS
  • Version Big Sur

Additional context

Use and Type Mappings

V2.6 Address and FHIR Address do not have clean 1:1 mappings for Type -> Use / Type. This is the design for meaningful mappings.

V2.6 Address is an XAD data type. https://hl7-definition.caristix.com/v2/HL7v2.6/DataTypes/XAD XAD is used for both Patients and Organizations, so we want to use the same mapping.

XAD has multiple special fields to get information from:

FHIR org has an V2 to FHIR mapping for address, but it does not account for the new fields (XAD.16/17/18) added in v2.6

FHIR Address reference: https://www.hl7.org/fhir/datatypes.html#Address
"use" and "type" are OPTIONAL, but are not extendable.

FHIR Use Code Display Definition
home Home A communication address at a home.
work Work An office address. First choice for business related contacts during business hours.
temp Temporary A temporary address. The period can provide more detailed information.
old Old / Incorrect This address is no longer in use (or was never correct but retained for records).
billing Billing An address to be used to send bills, invoices, receipts etc.
FHIR Type Code Display Definition
postal Postal Mailing addresses - PO Boxes and care-of addresses.
physical Physical A physical address that can be visited.
both Postal & Physical An address that is both physical and postal.

XAD Mapping Summary for FHIR Type

FHIR Type Code is mapped from XAD.18 table 0617
If XAD.18 is not present, but XAD.7 is "M" or "SH", XAD.7 will be used. If no conditions are satisfied, Type will remain empty.

XAD Type Code Definition FHIR Type
XAD.18 "M" : Mailing Identifies an address for mail correspondence from a healthcare provider as stipulated by the subject. For example, under the tenets of certain privacy regulations, it is exclusive to the patient and is typically maintained at the encounter or visit level versus the person level as it only has relevance to the specifics of a given encounter.  This is an exception category of address in that the patient has stipulated that they want all correspondence relevant to a given encounter sent to this address in lieu of any other address on file.  Providers are required to accommodate such requests under HIPAA promulgated regulation.  Note that mailing and legal address may be mutually exclusive as defined below.  "postal"
XAD.18 "V": Visit Identifies an address at which the individual is physically located and may be visited. "physical"
XAD.7 "M" : Mailing Retained for backward compatibility only as of v2.6. Refer to XAD.18, which takes priority. "postal"
XAD.7 "SH" : Shipping Address XAD.18 value takes priority. "physical"
XAD.18 "C" : Classification Identifies an address used for the purpose of demographic classification or searching.  Such addresses frequently contain insufficient information to be used as mailing or visit addresses.  For example, they may only indicate country and postal code, without providing a street address. Not supported

XAD Mapping Summary for FHIR Use

XAD Field, Code & Value XAD Description FHIR Use
XAD.16 (Temp) "Y" Temporary indicator "temp"
XAD.17 (Bad) "Y" Bad address "old"
XAD.7 "B" : Firm/Business Refers to an address specific to an organization, such as an insurance company or employer, versus an individual’s work location or place of employment. It would be specific to a firm or organization that has some sort of business relationship with the subject "work"
XAD.7 "BA" : Bad address Retained for backward compatibility only as of v2.6. Refer to XAD.17 "old"
XAD.7 "BDL" : Birth delivery location (address where birth occurred) Refers to the address where birth occurred. Not supported
XAD.7 "BI" : Billing Address May also be used for the validation/authorization of credit cards "billing"
XAD.7 "BR" : Residence at birth (home address at time of birth) Refers to the home address at time of birth. Not supported
XAD.7 "C" : Current Or Temporary Retained for backward compatibility only as of v2.6. Refer to XAD.16. XAD.16 (Y/N) takes priority. If XAD.16 is empty and XAD.7=="C" then "temp"
XAD.7 "F" : Country Of Origin   Not supported
XAD.7 "H" : Home Refers to a residence or domicile, literally the place where the subject resides the majority of the time. Generally speaking most people will have a home address and it will represent their primary address. Home address is mutually exclusive of permanent address. "home"
XAD.7 "L" : Legal Address Refers to a special case address specific to the status of a subject or legal action involving the subject. For example, prisoners being treated at a healthcare facility, etc. Not supported
XAD.7 "M" : Mailing Retained for backward compatibility only as of v2.6. Refer to XAD.18 not a use; this is a Type. See Type mapping table
XAD.7 "N" : Birth (nee) (birth address, not otherwise specified) Refers to the birth address, not otherwise specified Not supported
XAD.7 "O" : Office/Business Refers to a work address specific to the subject. "work"
XAD.7 "P" : Permanent Refers to a place where the residents know the subject and where correspondence addressed to the subject will eventually reach the subject regardless of their physical location. A permanent address generally reflects a tax jurisdiction.  Members of the military, flight attendants, and executives on rotational assignments are examples of those who typically maintain a permanent address. Although mutually exclusive of home address, in some instances, such as the executives mentioned above, it may be synonymous.  In such cases upon return from assignment this address would revert to the home address. Not supported
XAD.7 "RH" : Registry home. Refers to the information system, typically managed by a public health agency that stores patient information such as immunization histories or cancer data, regardless of where the patient obtains services Not supported
XAD.7 "S" : Service Location Refers to the location in which service is rendered. This would be used if reimbursement is based on the location of the service (to take into account the cost of those services). Not supported
XAD.7 "SH" : Shipping Address not a use; this is a Type. See Type mapping table
XAD.7 "V" : Vacation Not supported

XAD Address Mapping for FHIR Period

XAD Field Description FHIR field . subfield
XAD.12 Address Validity Range Address.period
XAD.13 Effective Date Address.period.start
XAD.14 Expiration Date Address.period.end

Capture Patient Race as an extension

Describe the bug
Create FHIR Patient.extension.patient-race (well-known extension) from PID-10.1

To Reproduce
Create a sample HL7V2.6 patient PID segment with aforementioned patient information.

Expected behavior
Patient information should be detected and added to corresponding fields in HL7 FHIR resources.

Example FHIR:

extension": [{
        "url": "http://ibm.com/fhir/cdm/StructureDefinition/local-race-cd",
        "valueCodeableConcept": {
          "coding": [ {
            "system": "http://terminology.hl7.org/CodeSystem/v3-Race",
            "code": "2028-9",
            "display": "Asian"
          } ],
          "text": "Asian"
        }
      }, {
        "url": "http://ibm.com/fhir/cdm/StructureDefinition/local-race-cd",
        "valueCodeableConcept": {
          "coding": [ {
            "system": "http://terminology.hl7.org/CodeSystem/v3-Race",
            "code": "2106-3",
            "display": "White"
          } ],
          "text": "White"
        }
      }
]

Additional context
HL7 FHIR Site
Sample results

LAB ORU messages does not contain Specimen information

The Specimen segments from ORU messages are not included in the converted FHIR bundles.

This HL7 message

MSH|^~\&|SomeSystem||TransformationAgent||201410060645||ORU^R01|182|T|2.5||
PID|1||10006579^^^1^MR^1||DUCK^DONALD^D||19241010|M||1|111 DUCK ST^^FOWL^CA^999990000^^M|1|8885551212|8885551212|1|2||40007716^^^AccMgr^VN^1|123121234|||||||||||NO
OBR|2|88502218|82503246|24317-0^Hemogram and platelet count, automated^LN||||||^COLLECT^JOHN|P|| |||^URO^^^^DR|||||||201410060929||F|F|||||||&CYTO&JANE^201410060929
OBX|1|NM|11156-7^LEUKOCYTES^LN||||||||I|
OBX|2|NM|11273-0^ERYTHROCYTES^LN||4.06|tera.l-1||N|||P|||201410060627
OBX|3|NM|20509-6^HEMOGLOBIN^LN||||||||I|
OBX|4|NM|20570-8^HEMATOCRIT^LN||40.1|%||N|||P|||201410060830
OBX|5|NM|11125-2^PLATELETS^LN||221|giga.l-1||N|||F|||201410060830
SPM|1|SpecimenID||BLD|||||||P||||||201410060535|201410060821||Y||||||1
OBR|1|855238581|890775544|26464-8^Differential WBC Count, buffy coat^LN||||||^COLLECT^JOHN|P| ||||^URO^^^^DR|||||||201410060929|||F|||||||&CYTO&JANE^201410060929
OBX|1|NM|23761-0^NEUTROPHILS/100 LEUKOCYTES^LN||72|%||N|||P|||201410060627
OBX|2|NM|26450-7^EOSINOPHILS/100 LEUKOCYTES^LN||2|%||N|||P|||201410060627
OBX|3|NM|26478-8^LYMPHOCYTES/100 LEUKOCYTES^LN||20|%||N|||P|||201410060627
OBX|4|NM|26485-3^MONOCYTES/100 LEUKOCYTES^LN||6|%||N|||P|||201410060627
OBX|5|NM|30180-4^BASOPHILS/100 LEUKOCYTES^LN||0|%||N|||P|||201410060627
SPM|1|SpecimenID||BLD|||||||P||||||201410060535|201410060821||Y||||||1

generates

{
  "resourceType": "Bundle",
  "id": "db2171a4-245b-4707-bdaf-7b7276174a85",
  "meta": {
    "lastUpdated": "2021-03-11T10:06:29.038-05:00"
  },
  "type": "collection",
  "entry": [
    {
      "fullUrl": "urn:uuid:Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb",
      "resource": {
        "resourceType": "Patient",
        "id": "041325d4-e2e2-46a3-9948-9106bfa56ebb",
        "identifier": [
          {
            "type": {
              "coding": [
                {
                  "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
                  "code": "MR",
                  "display": "Medical record number"
                }
              ],
              "text": "MR"
            },
            "value": "10006579",
            "assigner": {
              "reference": "Organization/1"
            }
          }
        ],
        "name": [
          {
            "family": "DUCK",
            "given": [
              "DONALD"
            ]
          }
        ],
        "gender": "male",
        "birthDate": "1924-10-10"
      }
    },
    {
      "fullUrl": "urn:uuid:Organization/1",
      "resource": {
        "resourceType": "Organization",
        "id": "1",
        "name": "Assigning Authority"
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/d143541e-b0e0-4758-97e3-55d13122dc82",
      "resource": {
        "resourceType": "Observation",
        "id": "d143541e-b0e0-4758-97e3-55d13122dc82",
        "identifier": [
          {
            "value": "11156-7_82503246"
          }
        ],
        "status": "registered",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "11156-7",
              "display": "LEUKOCYTES"
            }
          ],
          "text": "LEUKOCYTES"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        }
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/1d0e7439-44e6-45a5-82ef-58661e2caa7f",
      "resource": {
        "resourceType": "Observation",
        "id": "1d0e7439-44e6-45a5-82ef-58661e2caa7f",
        "identifier": [
          {
            "value": "11273-0_82503246"
          }
        ],
        "status": "preliminary",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "11273-0",
              "display": "ERYTHROCYTES"
            }
          ],
          "text": "ERYTHROCYTES"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "effectiveDateTime": "2014-10-06T06:27:00+08:00",
        "valueQuantity": {
          "value": 4.06,
          "unit": "tera.l-1"
        },
        "interpretation": [
          {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0078",
                "code": "N",
                "display": "Normal"
              }
            ],
            "text": "N"
          }
        ],
        "referenceRange": [
          {
            "low": {
              "unit": "tera.l-1"
            },
            "high": {
              "unit": "tera.l-1"
            }
          }
        ]
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/18aaa1bb-f91f-4610-84e1-e078cffd2578",
      "resource": {
        "resourceType": "Observation",
        "id": "18aaa1bb-f91f-4610-84e1-e078cffd2578",
        "identifier": [
          {
            "value": "20509-6_82503246"
          }
        ],
        "status": "registered",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "20509-6",
              "display": "HEMOGLOBIN"
            }
          ],
          "text": "HEMOGLOBIN"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        }
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/e208051e-03bf-4fec-8acf-840a15ec54ba",
      "resource": {
        "resourceType": "Observation",
        "id": "e208051e-03bf-4fec-8acf-840a15ec54ba",
        "identifier": [
          {
            "value": "20570-8_82503246"
          }
        ],
        "status": "preliminary",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "20570-8",
              "display": "HEMATOCRIT"
            }
          ],
          "text": "HEMATOCRIT"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "effectiveDateTime": "2014-10-06T08:30:00+08:00",
        "valueQuantity": {
          "value": 40.1,
          "unit": "%"
        },
        "interpretation": [
          {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0078",
                "code": "N",
                "display": "Normal"
              }
            ],
            "text": "N"
          }
        ],
        "referenceRange": [
          {
            "low": {
              "unit": "%"
            },
            "high": {
              "unit": "%"
            }
          }
        ]
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/7bb47aa6-783d-4541-8226-2dee25d7baf1",
      "resource": {
        "resourceType": "Observation",
        "id": "7bb47aa6-783d-4541-8226-2dee25d7baf1",
        "identifier": [
          {
            "value": "11125-2_82503246"
          }
        ],
        "status": "final",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "11125-2",
              "display": "PLATELETS"
            }
          ],
          "text": "PLATELETS"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "effectiveDateTime": "2014-10-06T08:30:00+08:00",
        "valueQuantity": {
          "value": 221,
          "unit": "giga.l-1"
        },
        "interpretation": [
          {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0078",
                "code": "N",
                "display": "Normal"
              }
            ],
            "text": "N"
          }
        ],
        "referenceRange": [
          {
            "low": {
              "unit": "giga.l-1"
            },
            "high": {
              "unit": "giga.l-1"
            }
          }
        ]
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/e9b4c89a-e675-45b0-9fc7-5108b657f49e",
      "resource": {
        "resourceType": "Observation",
        "id": "e9b4c89a-e675-45b0-9fc7-5108b657f49e",
        "identifier": [
          {
            "value": "23761-0_890775544"
          }
        ],
        "status": "preliminary",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "23761-0",
              "display": "NEUTROPHILS/100 LEUKOCYTES"
            }
          ],
          "text": "NEUTROPHILS/100 LEUKOCYTES"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "effectiveDateTime": "2014-10-06T06:27:00+08:00",
        "valueQuantity": {
          "value": 72,
          "unit": "%"
        },
        "interpretation": [
          {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0078",
                "code": "N",
                "display": "Normal"
              }
            ],
            "text": "N"
          }
        ],
        "referenceRange": [
          {
            "low": {
              "unit": "%"
            },
            "high": {
              "unit": "%"
            }
          }
        ]
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/d4102458-879c-4de2-be1d-f2120d93cdc7",
      "resource": {
        "resourceType": "Observation",
        "id": "d4102458-879c-4de2-be1d-f2120d93cdc7",
        "identifier": [
          {
            "value": "26450-7_890775544"
          }
        ],
        "status": "preliminary",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "26450-7",
              "display": "EOSINOPHILS/100 LEUKOCYTES"
            }
          ],
          "text": "EOSINOPHILS/100 LEUKOCYTES"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "effectiveDateTime": "2014-10-06T06:27:00+08:00",
        "valueQuantity": {
          "value": 2,
          "unit": "%"
        },
        "interpretation": [
          {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0078",
                "code": "N",
                "display": "Normal"
              }
            ],
            "text": "N"
          }
        ],
        "referenceRange": [
          {
            "low": {
              "unit": "%"
            },
            "high": {
              "unit": "%"
            }
          }
        ]
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/75c97357-284d-48ea-b907-37d62a92ca82",
      "resource": {
        "resourceType": "Observation",
        "id": "75c97357-284d-48ea-b907-37d62a92ca82",
        "identifier": [
          {
            "value": "26478-8_890775544"
          }
        ],
        "status": "preliminary",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "26478-8",
              "display": "LYMPHOCYTES/100 LEUKOCYTES"
            }
          ],
          "text": "LYMPHOCYTES/100 LEUKOCYTES"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "effectiveDateTime": "2014-10-06T06:27:00+08:00",
        "valueQuantity": {
          "value": 20,
          "unit": "%"
        },
        "interpretation": [
          {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0078",
                "code": "N",
                "display": "Normal"
              }
            ],
            "text": "N"
          }
        ],
        "referenceRange": [
          {
            "low": {
              "unit": "%"
            },
            "high": {
              "unit": "%"
            }
          }
        ]
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/23a7fbf1-8ce1-48b1-a83a-8e25c7ce729b",
      "resource": {
        "resourceType": "Observation",
        "id": "23a7fbf1-8ce1-48b1-a83a-8e25c7ce729b",
        "identifier": [
          {
            "value": "26485-3_890775544"
          }
        ],
        "status": "preliminary",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "26485-3",
              "display": "MONOCYTES/100 LEUKOCYTES"
            }
          ],
          "text": "MONOCYTES/100 LEUKOCYTES"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "effectiveDateTime": "2014-10-06T06:27:00+08:00",
        "valueQuantity": {
          "value": 6,
          "unit": "%"
        },
        "interpretation": [
          {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0078",
                "code": "N",
                "display": "Normal"
              }
            ],
            "text": "N"
          }
        ],
        "referenceRange": [
          {
            "low": {
              "unit": "%"
            },
            "high": {
              "unit": "%"
            }
          }
        ]
      }
    },
    {
      "fullUrl": "urn:uuid:Observation/e1b7746f-8a49-4489-9a0c-be0d9eba6fc9",
      "resource": {
        "resourceType": "Observation",
        "id": "e1b7746f-8a49-4489-9a0c-be0d9eba6fc9",
        "identifier": [
          {
            "value": "30180-4_890775544"
          }
        ],
        "status": "preliminary",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "30180-4",
              "display": "BASOPHILS/100 LEUKOCYTES"
            }
          ],
          "text": "BASOPHILS/100 LEUKOCYTES"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "effectiveDateTime": "2014-10-06T06:27:00+08:00",
        "valueQuantity": {
          "value": 0,
          "unit": "%"
        },
        "interpretation": [
          {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0078",
                "code": "N",
                "display": "Normal"
              }
            ],
            "text": "N"
          }
        ],
        "referenceRange": [
          {
            "low": {
              "unit": "%"
            },
            "high": {
              "unit": "%"
            }
          }
        ]
      }
    },
    {
      "fullUrl": "urn:uuid:DiagnosticReport/54d7edf8-51d5-4477-b2be-6dd2ac3dbfdd",
      "resource": {
        "resourceType": "DiagnosticReport",
        "id": "54d7edf8-51d5-4477-b2be-6dd2ac3dbfdd",
        "identifier": [
          {
            "value": "82503246"
          }
        ],
        "status": "final",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "24317-0",
              "display": "Hemogram and platelet count, automated"
            }
          ],
          "text": "Hemogram and platelet count, automated"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "result": [
          {
            "reference": "Observation/d143541e-b0e0-4758-97e3-55d13122dc82"
          },
          {
            "reference": "Observation/1d0e7439-44e6-45a5-82ef-58661e2caa7f"
          },
          {
            "reference": "Observation/18aaa1bb-f91f-4610-84e1-e078cffd2578"
          },
          {
            "reference": "Observation/e208051e-03bf-4fec-8acf-840a15ec54ba"
          },
          {
            "reference": "Observation/7bb47aa6-783d-4541-8226-2dee25d7baf1"
          },
          {
            "reference": "Observation/e9b4c89a-e675-45b0-9fc7-5108b657f49e"
          },
          {
            "reference": "Observation/d4102458-879c-4de2-be1d-f2120d93cdc7"
          },
          {
            "reference": "Observation/75c97357-284d-48ea-b907-37d62a92ca82"
          },
          {
            "reference": "Observation/23a7fbf1-8ce1-48b1-a83a-8e25c7ce729b"
          },
          {
            "reference": "Observation/e1b7746f-8a49-4489-9a0c-be0d9eba6fc9"
          }
        ]
      }
    },
    {
      "fullUrl": "urn:uuid:DiagnosticReport/6722f4db-a9f8-4be6-9758-d04a956ef89b",
      "resource": {
        "resourceType": "DiagnosticReport",
        "id": "6722f4db-a9f8-4be6-9758-d04a956ef89b",
        "identifier": [
          {
            "value": "890775544"
          }
        ],
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "26464-8",
              "display": "Differential WBC Count, buffy coat"
            }
          ],
          "text": "Differential WBC Count, buffy coat"
        },
        "subject": {
          "reference": "Patient/041325d4-e2e2-46a3-9948-9106bfa56ebb"
        },
        "result": [
          {
            "reference": "Observation/d143541e-b0e0-4758-97e3-55d13122dc82"
          },
          {
            "reference": "Observation/1d0e7439-44e6-45a5-82ef-58661e2caa7f"
          },
          {
            "reference": "Observation/18aaa1bb-f91f-4610-84e1-e078cffd2578"
          },
          {
            "reference": "Observation/e208051e-03bf-4fec-8acf-840a15ec54ba"
          },
          {
            "reference": "Observation/7bb47aa6-783d-4541-8226-2dee25d7baf1"
          },
          {
            "reference": "Observation/e9b4c89a-e675-45b0-9fc7-5108b657f49e"
          },
          {
            "reference": "Observation/d4102458-879c-4de2-be1d-f2120d93cdc7"
          },
          {
            "reference": "Observation/75c97357-284d-48ea-b907-37d62a92ca82"
          },
          {
            "reference": "Observation/23a7fbf1-8ce1-48b1-a83a-8e25c7ce729b"
          },
          {
            "reference": "Observation/e1b7746f-8a49-4489-9a0c-be0d9eba6fc9"
          }
        ]
      }
    }
  ]
}

It is missing SPM segments.

Add support for PD1.4 and create/update msg events that support AL1, PID, PD1

Add support for PD1.4 to create the patient.generalPractitioner

Also update existing msg events appropriately for support of AL1, PID, PD1
ADT_A01 --> PID, PD1, AL1
OMP_O09 --> PID, PD1, AL1
ORU_R01 --> PID, PD1
PPR_PC1 --> PID, PD1
RDE_O11 --> PID, PD1, AL1
RDE_O25 --> PID, PD1, AL1
VXU_V04 --> PID, PD1

Unable to read in message templates on Windows platform

On the Windows platform, the ADT_A01.yml file is attempted to be read in via the hl7 ResourceReader as "\hl7\message\ADT_A01.yml" (backward slash instead of forward). The file is not found and is thus not getting read in.
We suspect that this is due to the use of the java.io.File object on the Windows platform, in which the platform-dependent path separator is the backward slash instead of forward slash.
The message templates may need to get read in a little differently for this operation to function properly on a Windows platform.

This issue was reported by @ibmatc

MSH.9.2 returns MSH.9.1 value

Describe the bug
If referencing MSH.9.2 or MSH.9.3, the value for MSH.9.1 is returned. This happens in many cases but we have found one case where it works.

To Reproduce
In Address.yml, change addressee var to MSH.9.2:

line:
     type: STRING
     valueOf: 'GeneralUtils.makeStringArray( street, suiteApt, addressee)'
     generateList: true
     expressionType: JEXL
     vars:
          street: String, XAD.1
          suiteApt: String, XAD.2
          addressee: String, MSH.9.2

Run a test patient, such as Hl7AddressFHIRConversionTest.java, which has an MSH.9 with multiple values. Example: |VXU^V04^VXU_V04|

The output in the address is:

 "address": [ {
        "type": "postal",
        "line": [ "123 Any St", "VXU" ],
        "city": "Somewhere",
        "state": "WI",
        "postalCode": "54000"
      } ]

Expected behavior
MSH.9.2 should return the second value in MSH.9

Additional context
The value returns correctly in this case:

In MessageHeader.yml, change id as follows:

id:
  type: STRING
  valueOf: MSH.9.2
  expressionType: HL7Spec

Generated datetimes are not valid according to FHIR R4

The date times generated by the converter are not valid according to the $validate API in FHIR. I used:

hl7_input.txt
which I got from here: https://raw.githubusercontent.com/LinuxForHealth/hl7v2-fhir-converter/master/src/test/resources/sample_win.hl7

This produced this FHIR data:
hl7_produced_fhir.txt

which contains the datetime value of "2014-09-12T22:00:00"

When this FHIR bundle is sent to a FHIR R4 server using the $validate API, the following error is reported:

fhir_validate_message.txt

org full url space problem

Error: "text": "FHIRProvider: Id value: 'NIST MPI' contain invalid character ' ' [Bundle.entry[1]]"

{
"resourceType": "Bundle",
"id": "49bad1cf-ef5a-4728-943c-e3b99f523fe8",
"meta": {
"lastUpdated": "2021-03-17T20:00:53.944+00:00"
},
"type": "collection",
"entry": [
{
"fullUrl": "urn:uuid:Patient/6218f954-cbff-4b9d-881d-c10565a9cefe",
"resource": {
"resourceType": "Patient",
"id": "6218f954-cbff-4b9d-881d-c10565a9cefe",
"identifier": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "MR",
"display": "Medical record number"
}
],
"text": "MR"
},
"value": "18547545",
"assigner": {
"reference": "Organization/NIST MPI"
}
},
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "SS",
"display": "Social Security number"
}
],
"text": "SS"
},
"value": "111111111",
"assigner": {
"reference": "Organization/SSN"
}
}
],
"name": [
{
"family": "Lerr",
"given": [
"Todd"
],
"prefix": [
"Jr"
]
},
{
"family": "Gwinn",
"given": [
"Theodore"
],
"prefix": [
"Jr"
]
}
],
"gender": "male",
"birthDate": "2009-06-07"
}
},
{
"fullUrl": "urn:uuid:Organization/NISTMPI",
"resource": {
"resourceType": "Organization",
"id": "NIST MPI",
"name": "Assigning Authority"
}
},
{
"fullUrl": "urn:uuid:Organization/SSN",
"resource": {
"resourceType": "Organization",
"id": "SSN",
"name": "Assigning Authority"
}
},
{
"fullUrl": "urn:uuid:Observation/b449c70c-3972-4fbc-9b73-4d225f79a799",
"resource": {
"resourceType": "Observation",
"id": "b449c70c-3972-4fbc-9b73-4d225f79a799",
"identifier": [
{
"value": "5671-3_system generated"
}
],
"status": "final",
"code": {
"coding": [
{
"system": "http://loinc.org",
"version": "2.40",
"code": "5671-3",
"display": "Lead [Mass/volume] in Blood"
}
],
"text": "Lead [Mass/volume] in Blood"
},
"subject": {
"reference": "Patient/6218f954-cbff-4b9d-881d-c10565a9cefe"
},
"effectiveDateTime": "2012-06-15",
"issued": "2012-06-17T00:00:00-05:00",
"interpretation": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0078",
"code": "H",
"display": "High"
}
],
"text": "H"
}
],
"method": {
"coding": [
{
"version": "20090501",
"code": "0263",
"display": "Atomic Absorption Spectrophotometry"
}
],
"text": "Atomic Absorption Spectrophotometry"
},
"referenceRange": [
{
"low": {
"unit": "ug/dL"
},
"high": {
"unit": "ug/dL"
},
"text": "0.0 - 5.0"
}
]
}
},
{
"fullUrl": "urn:uuid:DiagnosticReport/94d57a12-84cc-4d6a-b157-8e2c2e56a087",
"resource": {
"resourceType": "DiagnosticReport",
"id": "94d57a12-84cc-4d6a-b157-8e2c2e56a087",
"identifier": [
{
"value": "system generated"
}
],
"status": "final",
"code": {
"coding": [
{
"system": "http://loinc.org",
"version": "2.40",
"code": "5671-3",
"display": "Lead [Mass/volume] in Blood"
}
],
"text": "Lead [Mass/volume] in Blood"
},
"subject": {
"reference": "Patient/6218f954-cbff-4b9d-881d-c10565a9cefe"
},
"effectiveDateTime": "2012-06-15",
"issued": "2012-06-17T00:00:00-05:00",
"result": [
{
"reference": "Observation/b449c70c-3972-4fbc-9b73-4d225f79a799"
}
]
}
}
]
}

How to use latest alpha release?

The latest release of 1.0.3-alpha doesn't seem to be available from mvnrepository. Is there any specific repository location should I add in my pom.xml?

Improve patient information capture

Describe the bug
Add capability to find and convert the following patient information

NOTE: the following were moved to #111

  • Patient.communication.language, Patient.communication.preferred / PID-15

NOTE: the following were moved to #110

  • Patient.telecom / PID-13 (home), PID-14 (work)

NOTE: the following were moved to #108

  • Patient.name.use / PID-5.7
  • Patient.name.given / PID-5.3 (middle name)

NOTE: the following were moved to #103

  • Patient.maritalStatus / PID-16

NOTE: the following were moved to #100

  • Patient.address / PID-11
  • Patient.address.district / PID-12. (Also known as Country code)

NOTE: the following were moved to #97

  • Patient.multipleBirthBoolean / PID-24
  • Patient.multipleBirthInteger / PID-25
  • Patient.deceasedDateTime / PID-29
  • Patient.deceasedBoolean / PID-30

To Reproduce
Create a sample HL7V2.6 patient PID segment with aforementioned patient information.

Expected behavior
Patient information should be detected and added to corresponding fields in HL7 FHIR resources.

Examples:

Patient Address: This should handle a complete Extended Address XAD content (should allow for multiple)

{
  "resourceType": "Patient",
  "id": "address",
  "address": [
    {
      "use": "home",
      "type": "both",
      "text": "534 Erewhon St PeasantVille, Rainbow, Vic  3999",
      "line": [
        "534 Erewhon St"
      ],
      "city": "PleasantVille",
      "district": "Rainbow",    <<< comes from PID.12
      "state": "Vic",
      "postalCode": "3999",
      "period": {
        "start": "1974-12-25"
      }
    }
  ],

District / Country code
From HL7V2.6, it is four characters of local definition.
Inserted into .address as shown above

Telcom (both home and work): follow the Extended Telephone Communication XTN format (should allow for multiple)

  "telecom": [
    {
      "system": "home",
      "value": "(03) 5555 6473",
      "use": "work",
      "rank": 1
    },
    {
      "system": "phone",
      "value": "(03) 5555 6473",
      "use": "work",
      "rank":2
    }
    }
  ],

Communication language: recommended based on ISO table 639. However ISO 639 has additional versions. This is a CWE encoding.

  "communication": [
    {
      "language": {
        "coding": [
          {
            "system": "urn:ietf:bcp:47",  << May not be this system.
            "code": "nl",
            "display": "Dutch"
          }
        ],
        "text": "Nederlands"
      },
      "preferred": true
    }
  ],

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Mac OS
  • Version Big Sur

Additional context
Add any other context about the problem here.

Do not assume multiple births unless explicitly stated.

Describe the bug
Multiple birth was implemented such that if the multiple births integer is present and N is set as indicator, parser assumes that deceased is true, and a .multipleBirthInteger is created.

However, the desired behavior is:

BOOL || NUMBER = Answer
-----------------------------
Y + number = integer number
N + number = N
Y + blank = Y
N + blank = N
blank + number = number   << in this case assume the number is meaningful data
blank + blank = nothing

To Reproduce
Use the value for boolean | number: `|N|16|'

Expected behavior
This should produce "multipleBirthBoolean": false

Capture Marital Status

Describe the bug
Add capability to find and convert the following patient information

  • Patient.maritalStatus / PID-16

NOTE: this was moved from #94

To Reproduce
Create a sample HL7V2.6 patient PID segment with aforementioned patient information.

Expected behavior
Patient information should be detected and added to corresponding fields in HL7 FHIR resources.

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Mac OS
  • Version Big Sur

Additional context

Information about HL7V2.6 codes
Information about HL7 FHIR codes
Tasks:
Create an addition to Patient.yml
Create a Utility in Hl7RelatedGeneralUtils.java to support the changes to Patient.yml. getAddressUse is a good pattern to follow.
Create a unit test for the utility you created. test_getAddressUse is a good pattern to follow.
Create or enhance an existing unit test with a patient in src/test/java/io/github/linuxforhealth/hl7/segments/Hl7PatientFHIRConversionTest.java

Capture patient preferred language

Describe the bug
Add capability to find and convert the following patient information

  • Patient.communication.language, Patient.communication.preferred / PID-15
    (Moved from #94)

To Reproduce
Create a sample HL7V2.6 patient PID segment with aforementioned patient information.

Expected behavior
Patient information should be detected and added to corresponding fields in HL7 FHIR resources.

Examples:

Communication language: recommended based on ISO table 639. However ISO 639 has additional versions. This is a CWE encoding.

  "communication": [
    {
      "language": {
        "coding": [
          {
            "system": "urn:ietf:bcp:47",  << May not be this system.
            "code": "nl",
            "display": "Dutch"
          }
        ],
        "text": "Nederlands"
      },
      "preferred": true
    }
  ],

Screenshots
N/A

Additional context
Add any other context about the problem here.

HL7Converter Fails To Run On Windows

Related to #38 - The following code blocks

    public void startConverter() throws IOException {
        HL7ToFHIRConverter converter = new HL7ToFHIRConverter();
        String fhirMessage = converter.convert(hl7Message);
        System.out.println(fhirMessage);
    }


    public static void main(String[] args) throws Exception {
        App app = new App();
        app.startConverter();
    }

fail to run due to the following stack trace

Exception in thread "main" java.lang.NullPointerException
	at java.io.Reader.<init>(Reader.java:78)
	at java.io.InputStreamReader.<init>(InputStreamReader.java:113)
	at org.apache.commons.io.IOUtils.copy(IOUtils.java:2440)
	at org.apache.commons.io.IOUtils.toString(IOUtils.java:1084)
	at io.github.linuxforhealth.hl7.resource.ResourceReader.loadClassPathResource(ResourceReader.java:66)
	at io.github.linuxforhealth.hl7.resource.ResourceReader.getResource(ResourceReader.java:84)
	at io.github.linuxforhealth.hl7.resource.ResourceReader.getResourceInHl7Folder(ResourceReader.java:164)
	at io.github.linuxforhealth.hl7.resource.ResourceReader.getMessageModel(ResourceReader.java:111)
	at io.github.linuxforhealth.hl7.resource.ResourceReader.getMessageTemplates(ResourceReader.java:99)
	at io.github.linuxforhealth.hl7.HL7ToFHIRConverter.<init>(HL7ToFHIRConverter.java:49)
	at io.github.linuxforhealth.converter.App.startConverter(App.java:19)
	at io.github.linuxforhealth.converter.App.main(App.java:26)

Improve patient name field capture

Describe the bug
Add capability to find and convert the following patient information

  • Patient.name.use / PID-5.7
  • Patient.name.given / PID-5.3 (middle name)

NOTE: moved from #94

To Reproduce
Create a sample HL7V2.6 patient PID segment with aforementioned patient information.

Expected behavior
Patient information should be detected and added to corresponding fields in HL7 FHIR resources.

Screenshots
N/A

Mismatch in dependencies

Hi -

Context: I am trying to do a POC using this hl7v2-fhir-converter to transform an HL7v2 message into the FHIR format.

Issue: There is a mismatch in the deps. See below for information. In the maven repository, the minimum version of the fhir-registry jar and the fhir-term jar is 4.7.0.

Possible Fix/Solution: I reckon the orginal hl7v2-fhir-converter project needs to be updated to refer the latest versions of the above-mentioned jars.

Question: Does this hl7v2-fhir-converter support all the HL72.x versions, or is there a specific version that it uses per design?Please advise.

Happy to answer any question/happy to help!

Thanks,
Hanuma

image

Some BiConditions do not work

Describe the bug
BiConditions, such as GREATER_THAN do not work in some cases.

To Reproduce
Create a condition with:
$var1 GREATER_THAN 6
$var1 GREATER_THAN_INTEGER 6

Example failing tests can be added to SimpleBiConditionTest.java

  @Test
  public void simple_GREATER_THAN_condition_of_integer_is_evaluated_true() {
    String condition = "$var1 GREATER_THAN 6";
    SimpleBiCondition simplecondition =
        (SimpleBiCondition) ConditionUtil.createCondition(condition);
    Map<String, EvaluationResult> contextVariables = new HashMap<>();
    contextVariables.put("var1", new SimpleEvaluationResult(9));
    assertThat(simplecondition.test(contextVariables)).isTrue();
  }

  @Test
  public void simple_GREATER_THAN_INTEGER_condition_is_evaluated_true() {
    String condition = "$var1 GREATER_THAN_INTEGER 6";
    SimpleBiCondition simplecondition =
        (SimpleBiCondition) ConditionUtil.createCondition(condition);
    Map<String, EvaluationResult> contextVariables = new HashMap<>();
    contextVariables.put("var1", new SimpleEvaluationResult(9));
    assertThat(simplecondition.test(contextVariables)).isTrue();
  }

Expected behavior
Conditions should evaluate correctly without error.

Additional context
Other BiConditions may also not work.

CodeableConcept has only one coding

Describe the bug
When a CWE segment is passed to the datatype/CodeableConcept, and CWE.4, CWE.5 and CWE.6 are present the coding section has only CWE.1, CWE.2 and CWE.3

To Reproduce
parse a message with SPM segment

SPM|1|SpecimenID||BLOOD^Blood^^87612001^BLOOD^SCT^^||||Cord Art^Blood, Cord Arterial^^^^^^^|||P||||||201410060535|201410060821||Y||||||1

the FHIR bundle has this section

"type": {
          "coding": [
            {
              "code": "BLOOD",
              "display": "Blood"
            }
          ],
          "text": "Blood"
        },

Expected behavior
The expected section is

"type": {
          "coding": [
            {
              "code": "BLOOD",
              "display": "Blood"
            },
            {
              "system": "http://snomed.info/sct",
              "code": "87612001",
              "display": "BLOOD"
            }
          ],
          "text": "Blood"
        },

Bundle.type must be either 'batch' or 'transaction'.

Bundle type is collection, it needs to be changed it to transaction/batch
** These types take a request field on each entry, which indicates that, for example, it should be PUT into Patient/2342

JSON file that was generated

{
"resourceType": "Bundle",
"id": "711e839f-f1d1-4e9d-807c-4bfedfeec08e",
"meta": {
"lastUpdated": "2021-03-17T20:08:12.174+00:00"
},
"type": "collection",
"entry": [
{
"fullUrl": "urn:uuid:Patient/863d3aea-54d8-4349-8e02-cf43bb45d47e",
"resource": {
"resourceType": "Patient",
"id": "863d3aea-54d8-4349-8e02-cf43bb45d47e",
"identifier": [
{
"value": "KL_000945",
"assigner": {
"reference": "Organization/MRN"
}
}
],
"name": [
{
"family": "PatientAccuracy000945",
"given": [
"Adam"
]
}
],
"gender": "male",
"birthDate": "1967-03-11"
}
},
{
"fullUrl": "urn:uuid:Organization/MRN",
"resource": {
"resourceType": "Organization",
"id": "MRN",
"name": "Assigning Authority"
}
},
{
"fullUrl": "urn:uuid:DiagnosticReport/81e388d7-f4f4-46fa-94d0-ef1cc1857006",
"resource": {
"resourceType": "DiagnosticReport",
"id": "81e388d7-f4f4-46fa-94d0-ef1cc1857006",
"identifier": [
{
"value": "CD_000945"
}
],
"status": "final",
"code": {
"coding": [
{
"code": "2244",
"display": "General Order"
}
],
"text": "General Order"
},
"subject": {
"reference": "Patient/863d3aea-54d8-4349-8e02-cf43bb45d47e"
},
"effectiveDateTime": "2017-08-25T01:05:00+08:00",
"resultsInterpreter": [
{
"reference": "Practitioner/05103a18-1e53-463e-ab20-4ca1cec6a41e"
}
]
}
},
{
"fullUrl": "urn:uuid:Practitioner/05103a18-1e53-463e-ab20-4ca1cec6a41e",
"resource": {
"resourceType": "Practitioner",
"id": "05103a18-1e53-463e-ab20-4ca1cec6a41e",
"identifier": [
{
"value": "770600"
}
],
"name": [
{
"text": "1234 A",
"prefix": [
"1234"
],
"suffix": [
"A"
]
}
]
}
}
]
}

Add support for patient email

Add support for patient email to telecom

If PID.13 (home) or PID.14 (work) has a value in XTN.4 create a ContactPoint element.
Example:

{
        "system": "email",
        "value": "[email protected]",
        "use": "home",   
        "rank": 1
      }
  • use will be "home" for PID.13, "work" for PID.14
  • rank will be included if there is a value in XTN.18

At this time, no need to check if XTN.2 has NET or XTN.3 has Internet or X.400. Although these would be expected. If there is any value in email, we will capture it. In the future if validation of email format is required, it can be added.

Fix null value (my particular example was in OBX.5)

I've updated this issue after finding where the problem in the code is, here is the line that errors out when OBX.5 has no value (being null):

Here is a sample line of what I'm talking about in the HL7 where the OBX.5 has no value:
"OBX|1|ST|14151-5^HCO3 BldCo-sCnc^LN|TEST|||||||F|||20210311122016|||||20210311122153||||"

A nullPointer error will trigger when that happens so I made a change in the Hl7DataHandlerUtil.java file:
FROM returnvalue = local.toString(); TO returnvalue = local == null ? "" : local.toString();

I also added a unit test to check for this in DifferentObservationValueTest.java :
@test
public void test_observation_ST_null_result() throws IOException {

String hl7message = baseMessage
        + "OBX|1|ST|14151-5^HCO3 BldCo-sCnc^LN|TEST|||||||F|||20210311122016|||||20210311122153||||";
String json = message.convert(hl7message, engine);

IBaseResource bundleResource = context.getParser().parseResource(json);
assertThat(bundleResource).isNotNull();
Bundle b = (Bundle) bundleResource;
List<BundleEntryComponent> e = b.getEntry();
List<Resource> obsResource =
        e.stream().filter(v -> ResourceType.Observation == v.getResource().getResourceType())
                .map(BundleEntryComponent::getResource).collect(Collectors.toList());
assertThat(obsResource).hasSize(1);
Observation obs = (Observation) obsResource.get(0);
assertThat(obs.getValueStringType()).isNotNull();
StringType q = obs.getValueStringType();
assertThat(q.asStringValue())
        .isEqualTo(null);

}

CodingSystemMapping.yml pointing to some deprecated code systems?

Describe the bug
I get warnings about invalid codes when running the current FHIR validator on files I have converted using the latest converter.
When looking at the contents of the CodingSystemMapping.yml included in the HL7toFHIR converter it reads they come from: https://www.hl7.org/fhir/v2/0396/index.html
According to this table they are deprecated?

To Reproduce
Convert an ORU-R01 HL7 message and run the latest FHIR validator (validator_cli.jar). See example attached. Search for references to "code-invalid" within it.
output-oru-r01-sample01-0428.txt

Expected behavior
These warnings should be resolved for the proper conversion of the files.

Desktop (please complete the following information):

  • OS: MacOS Big Sur
  • Version 11.2.1

Additional context
Some of the warnings mentioned:

"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-source",
"valueCode" : "TerminologyEngine"
}],
"severity" : "information",
"code" : "code-invalid",
"details" : {
"text" : "None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/report-codes (http://hl7.org/fhir/ValueSet/report-codes), and a coding is recommended to come from this value set) (codes = null#1000)"
},
"expression" : ["Bundle.entry[5].resource.ofType(DiagnosticReport).code"]
},
{
...
{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-source",
"valueCode" : "InstanceValidator"
}],
"severity" : "warning",
"code" : "code-invalid",
"details" : {
"text" : "A code with no system has no defined meaning. A system should be provided"
},
"expression" : ["Bundle.entry[2].resource.ofType(Observation).code.coding[0]"]

Diagnostic report generating incorrect value for field "issued".

Describe the bug
The value of the field issued fails the FHIR validation as the value is generated without timezone information

To Reproduce
Use the attached ORU message to reproduce the issue. Remove the .txt extension.

Expected behavior
Value of the issued field should have valid date with timezone information.

Converted HL7 VXU-V04 sample message reported “severity” : “error” messages on Immunization.occurrence and Immunization.status

HL7 VXU-V04 sample message was converted into FHIR .json (using converter version 1.0.5), which when I ran the FHIR validator on (FHIR Validation tool Version 5.3.7 (Git# 671a3bbfe9fe). Built 2021-03-29T08:05:33.611Z), it reported some “severity” : “error” messages:

e.g. "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-source",
"valueCode" : "InstanceValidator"
}],
"severity" : "error",
"code" : "structure",
"details" : {
"text" : "Immunization.occurrence[x]: minimum required = 1, but only found 0 (from http://hl7.org/fhir/StructureDefinition/Immunization)"
},
"expression" : ["Bundle.entry[1].resource.ofType(Immunization)"]
and
"severity" : "error",
"code" : "structure",
"details" : {
"text" : "Immunization.status: minimum required = 1, but only found 0 (from http://hl7.org/fhir/StructureDefinition/Immunization)"
},
"expression" : ["Bundle.entry[3].resource.ofType(Immunization)"]
and
"severity" : "error",
"code" : "invariant",
"details" : {
"text" : "org-1: 'The organization SHALL at least have a name or an identifier, and possibly more than one' failed"
},

To Reproduce
Run the FHIR validator on converted .json (I'll attach HL7, converted .json and my output file after saving issue)
ie. java -jar validator_cli.jar ./../path/L4H-converted-jsons/vxu-v04/vxu-v04-sample04.json -version 4.0.1 -output ./../path/fhir-validation/output-vxu-v04-sample04.json

Expected behavior
The errors seem to indicate something is not right in the conversion into FHIR...

I ran this on MacOS Big Sur version 12.2.1

Invalid content in meta.source for fhir bundle

When using the provided HL7 data to convert to FHIR, the resulting FHIR contains an invalid meta.source value:

		"source": "Message: ADT_A01, Message Control Id: 102"

To simplify I switched to only this for input HL7 data:
MSH|^~\\&|SE050|050|PACS|050|||ADT^A01|102|T|2.6|||AL|NE\r

The resulting entire bundle is:

{
	"resourceType": "Bundle",
	"id": "2dd486aa-7062-45e8-acd8-5fc274afc88d",
	"meta": {
		"lastUpdated": "2021-02-15T16:07:10.203-06:00",
		"source": "Message: ADT_A01, Message Control Id: 102"
	},
	"type": "collection"
}

This fhir bundle sent to the $validate API of a FHIR server results in the following error message:

{
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "fatal",
            "code": "invalid",
            "details": {
                "text": "FHIRProvider: Uri value: 'Message: ADT_A01, Message Control Id: 102' must not contain whitespace [Bundle.meta]"
            },
            "expression": [
                "Bundle.meta"
            ]
        }
    ]
}

I have not dug into the meaning of the data passed in enough to understand whether it's in the wrong field or invalidly converted to FHIR, but the validate API indicates it is not correct as-is.

DiagnosticReport.status: minimum required =1, but only found 0 when validating HL7 ORU-R01 message.

Describe the bug
Error: "DiagnosticReport.status: minimum required = 1, but only found 0 (from http://hl7.org/fhir/StructureDefinition/DiagnosticReport)" shows when running the current FHIR validator on the converted file from attached HL7 message.

To Reproduce
Run attached HL7 message within latest FHIR validator available and check the output for errors.

Expected behavior
The HL7 message
oru-r01-sample01.txt
is missing that field, but should the converter be able to deal with it? (ie. map null to Unknown when the expected value is not found?) rather than throw an error?

pydantic.error_wrappers.ValidationError: 1 validation error for DiagnosticReport
root -> status
field required (type=value_error.missing)

Desktop (please complete the following information):

  • OS: MacOS Big Sur
  • Version 11.2.1

Additional context
Add any other context about the problem here.

Add missing systems

Describe the bug
The following systems are not recognized if found in valid HL7 V2.6 input.

Missing system NIP001
MVX system with url missing
HL70163 needs to be added to coding system
NCIT needs to be added to coding systems
HL70064 system needs to be added to systems
HL70162 coding system missing "Route of Administration"
CDCREC
HL70005

To Reproduce
Create a message or segment and try converting.

Expected behavior
When the message contains the sources used correctly, it should reference the correct system

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Mac Big Sur

Additional context

These are the proposed URLs for the following

NIP001

Depricated

MVX system with url missing

This is already present. The datatype needs to create the system.

- id: "MVX"
  description: "CDC Vaccine Manufacturer Codes"
  url: "http://terminology.hl7.org/CodeSystem/MVX"
  oid: "urn:oid:2.16.840.1.113883.6.60"

HL70163 needs to be added to coding system

- id: "HL70163"
  description: "bodySite"
  url: "http://terminology.hl7.org/CodeSystem/v2-0163"
  oid: "urn:oid:2.16.840.1.113883.18.81"

NCIT needs to be added to coding systems

- id: "NCIT"
  description: "NCI Thesaurus"
  url: "http://ncithesaurus-stage.nci.nih.gov"
  oid: "urn:oid:2.16.840.1.113883.3.26.1.1"

HL70064 system " Financial Class"

Recommended source CDC

- id: "HL70064"
  description: "Financial Class (HL7)"
  url: "https://phinvads.cdc.gov/vads/ViewCodeSystem.action?id=2.16.840.1.113883.12.64#"
  oid: "urn:oid:2.16.840.1.113883.12.64"

HL70162 coding system missing "Route of Administration"

HL7 Version 2 Table 0162

- id: "HL70162"
  description: "routeOfAdministration"
  url: "http://terminology.hl7.org/CodeSystem/v2-0162"
  oid: "urn:oid:2.16.840.1.113883.18.80"  

CDCREC

- id: "CDCREC"
  description: "RaceAndEthnicityCDC"
  url: "http://hl7.org/fhir/us/core/CodeSystem-cdcrec.html"
  oid: "urn:oid:2.16.840.1.113883.6.238"

HL70005

Error in parsing sample_unix.hl7

I tried to parse the sample_unix.hl7 which is included in the source code. That also has show many warnings.

2020-11-17 23:56:18.889  WARN 1025953 --- [           main] ca.uhn.fhir.parser.LenientErrorHandler   : Found incorrect type for element coding - Expected ARRAY and found OBJECT
2020-11-17 23:56:18.890  WARN 1025953 --- [           main] ca.uhn.fhir.parser.LenientErrorHandler   : Found incorrect type for element coding - Expected ARRAY and found OBJECT
2020-11-17 23:56:18.894  WARN 1025953 --- [           main] i.g.l.hl7.parsing.HL7DataExtractor       : Failure in checking if segment exsts: PV2

java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
	at ca.uhn.hl7v2.model.Unmodifiable$UnmodifiableGroup.get(Unmodifiable.java:298) ~[hapi-base-2.3.jar:na]
	at ca.uhn.hl7v2.model.Unmodifiable$UnmodifiableGroup.get(Unmodifiable.java:285) ~[hapi-base-2.3.jar:na]
	at io.github.linuxforhealth.hl7.parsing.HL7DataExtractor.doesSegmentExists(HL7DataExtractor.java:143) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.parsing.HL7DataExtractor.getAllStructures(HL7DataExtractor.java:198) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.util.SegmentExtractorUtil.extractAdditionalSegmentValue(SegmentExtractorUtil.java:163) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.util.SegmentExtractorUtil.extractSegmentGroup(SegmentExtractorUtil.java:258) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageEngine.generateSingle(HL7MessageEngine.java:198) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageEngine.transform(HL7MessageEngine.java:112) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageModel.convert(HL7MessageModel.java:75) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.HL7ToFHIRConverter.convert(HL7ToFHIRConverter.java:128) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.HL7ToFHIRConverter.convert(HL7ToFHIRConverter.java:87) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at com.e314.hl7.Hl7Application.run(Hl7Application.java:29) ~[classes/:na]
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:788) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-2.4.0.jar:2.4.0]
	at com.e314.hl7.Hl7Application.main(Hl7Application.java:22) ~[classes/:na]

2020-11-17 23:56:18.920  WARN 1025953 --- [           main] i.g.l.hl7.data.date.DateUtil             : Date parsing error for instant 2014-09-12T22:00:00

java.time.format.DateTimeParseException: Text '2014-09-12T22:00:00' could not be parsed at index 19
	at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046) ~[na:na]
	at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948) ~[na:na]
	at java.base/java.time.Instant.parse(Instant.java:395) ~[na:na]
	at io.github.linuxforhealth.hl7.data.date.DateUtil.getTemporal(DateUtil.java:145) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.data.Hl7RelatedGeneralUtils.diffDateMin(Hl7RelatedGeneralUtils.java:103) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.apache.commons.jexl3.internal.introspection.MethodExecutor.invoke(MethodExecutor.java:93) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.call(Interpreter.java:1598) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1306) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.parser.ASTMethodNode.jjtAccept(ASTMethodNode.java:18) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1018) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:18) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:892) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:55) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:186) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Script.execute(Script.java:178) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:170) ~[commons-jexl3-3.1.jar:3.1]
	at io.github.linuxforhealth.core.data.JexlEngineUtil.evaluate(JexlEngineUtil.java:76) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageData.evaluateJexlExpression(HL7MessageData.java:165) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.JELXExpression.evaluateExpression(JELXExpression.java:80) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.generateValue(AbstractExpression.java:264) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.evaluateSingle(AbstractExpression.java:183) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.evaluate(AbstractExpression.java:148) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.resource.HL7DataBasedResourceModel.executeExpression(HL7DataBasedResourceModel.java:240) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.resource.HL7DataBasedResourceModel.evaluate(HL7DataBasedResourceModel.java:143) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.ResourceExpression.evaluateExpression(ResourceExpression.java:105) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.generateValue(AbstractExpression.java:264) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.evaluateSingle(AbstractExpression.java:183) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.evaluate(AbstractExpression.java:148) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.resource.HL7DataBasedResourceModel.evaluateResourceExpression(HL7DataBasedResourceModel.java:217) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.resource.HL7DataBasedResourceModel.evaluate(HL7DataBasedResourceModel.java:131) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageEngine.generateSingle(HL7MessageEngine.java:212) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageEngine.transform(HL7MessageEngine.java:112) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageModel.convert(HL7MessageModel.java:75) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.HL7ToFHIRConverter.convert(HL7ToFHIRConverter.java:128) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.HL7ToFHIRConverter.convert(HL7ToFHIRConverter.java:87) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at com.e314.hl7.Hl7Application.run(Hl7Application.java:29) ~[classes/:na]
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:788) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-2.4.0.jar:2.4.0]
	at com.e314.hl7.Hl7Application.main(Hl7Application.java:22) ~[classes/:na]

2020-11-17 23:56:18.922  WARN 1025953 --- [           main] i.g.l.hl7.data.date.DateUtil             : Date parsing error for ZonedDateTime 2014-09-12T22:00:00

java.time.format.DateTimeParseException: Text '2014-09-12T22:00:00' could not be parsed at index 19
	at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046) ~[na:na]
	at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948) ~[na:na]
	at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:598) ~[na:na]
	at io.github.linuxforhealth.hl7.data.date.DateUtil.getTemporal(DateUtil.java:152) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.data.Hl7RelatedGeneralUtils.diffDateMin(Hl7RelatedGeneralUtils.java:103) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.apache.commons.jexl3.internal.introspection.MethodExecutor.invoke(MethodExecutor.java:93) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.call(Interpreter.java:1598) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1306) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.parser.ASTMethodNode.jjtAccept(ASTMethodNode.java:18) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:1018) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.parser.ASTReference.jjtAccept(ASTReference.java:18) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.visit(Interpreter.java:892) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.parser.ASTJexlScript.jjtAccept(ASTJexlScript.java:55) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Interpreter.interpret(Interpreter.java:186) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Script.execute(Script.java:178) ~[commons-jexl3-3.1.jar:3.1]
	at org.apache.commons.jexl3.internal.Script.evaluate(Script.java:170) ~[commons-jexl3-3.1.jar:3.1]
	at io.github.linuxforhealth.core.data.JexlEngineUtil.evaluate(JexlEngineUtil.java:76) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageData.evaluateJexlExpression(HL7MessageData.java:165) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.JELXExpression.evaluateExpression(JELXExpression.java:80) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.generateValue(AbstractExpression.java:264) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.evaluateSingle(AbstractExpression.java:183) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.evaluate(AbstractExpression.java:148) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.resource.HL7DataBasedResourceModel.executeExpression(HL7DataBasedResourceModel.java:240) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.resource.HL7DataBasedResourceModel.evaluate(HL7DataBasedResourceModel.java:143) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.ResourceExpression.evaluateExpression(ResourceExpression.java:105) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.generateValue(AbstractExpression.java:264) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.evaluateSingle(AbstractExpression.java:183) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.expression.AbstractExpression.evaluate(AbstractExpression.java:148) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.resource.HL7DataBasedResourceModel.evaluateResourceExpression(HL7DataBasedResourceModel.java:217) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.resource.HL7DataBasedResourceModel.evaluate(HL7DataBasedResourceModel.java:131) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageEngine.generateSingle(HL7MessageEngine.java:212) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageEngine.transform(HL7MessageEngine.java:112) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.message.HL7MessageModel.convert(HL7MessageModel.java:75) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.HL7ToFHIRConverter.convert(HL7ToFHIRConverter.java:128) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at io.github.linuxforhealth.hl7.HL7ToFHIRConverter.convert(HL7ToFHIRConverter.java:87) ~[hl7v2-fhir-converter-1.0.3-alpha.jar:na]
	at com.e314.hl7.Hl7Application.run(Hl7Application.java:29) ~[classes/:na]
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:788) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-2.4.0.jar:2.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-2.4.0.jar:2.4.0]
	at com.e314.hl7.Hl7Application.main(Hl7Application.java:22) ~[classes/:na]

2020-11-17 23:56:19.327  WARN 1025953 --- [           main] ca.uhn.fhir.parser.LenientErrorHandler   : Found incorrect type for element coding - Expected ARRAY and found OBJECT
2020-11-17 23:56:19.328  WARN 1025953 --- [           main] ca.uhn.fhir.parser.LenientErrorHandler   : Found incorrect type for element coding - Expected ARRAY and found OBJECT
2020-11-17 23:56:19.353 ERROR 1025953 --- [           main] i.g.l.hl7.parsing.HL7DataExtractor       : HL7 String OBR-22Can't find OBR as a direct child  
2020-11-17 23:56:19.361  WARN 1025953 --- [           main] ca.uhn.fhir.parser.LenientErrorHandler   : Found incorrect type for element reaction - Expected ARRAY and found OBJECT
2020-11-17 23:56:19.364  WARN 1025953 --- [           main] ca.uhn.fhir.parser.LenientErrorHandler   : Found incorrect type for element reaction - Expected ARRAY and found OBJECT

Capture Patient Telcom information

Describe the bug
Add capability to find and convert the following patient information

  • Patient.telecom / PID-13 (home), PID-14 (work)
    Moved from #94

To Reproduce
Create a sample HL7V2.6 patient PID segment with aforementioned patient information.

Expected behavior
Patient information should be detected and added to corresponding fields in HL7 FHIR resources.

Examples:

Telcom (both home and work): follow the Extended Telephone Communication XTN format (should allow for multiple)

  "telecom": [
    {
      "system": "phone",
      "value": "(203) 555 6473",
      "use": "home",
      "rank": 1
    },
    {
      "system": "phone",
      "value": "(203) 555 6473",
      "use": "work",
    }
    }
  ],

The following references PID.13, but the same applies to PID.14, or anything of type XTN

  1. Logic for what Data to put into ContactPoint.value:
    Use 13.5, 13.6, and 13.7 if 13.7 if not blank
    else use 13.12 if not blank
    else use 13.1 if not blank
    1. We will not check if these fields have inconsistent information, but use the first one that has data
  2. Format of data in ContactPoint.value:
    1. if using 13.5, 13.6, 13.7, and 13.5 is not blank, format like this:
      (607) 123 4567
    2. if using 13.5, 13.6, 13.7, and 13.5 is blank, format like this:
      +22 607 123 4567
    3. Otherwise take the value as it is (do not alter the format)
  3. We will not use the FHIR extensions at https://build.fhir.org/ig/HL7/v2-to-fhir/ConceptMap-datatype-xtn-to-contactpoint.html
  4. Use 13.18 Preference Order as the rank.
  5. If 13.3 is "CP" then set Patient.telecom.use to "mobile" and Patient.telecom.system to "phone"

Screenshots
N/A

Additional context
Add any other context about the problem here.

Do not set Coding.display from hl7 CWE.2 text

Describe the bug
Coding.display should not be set from CWE.2

To Reproduce"
AL1|1|DA|00000741^OXYCODONE||HYPOTENSION
should result in

"code": {
	"coding": [
		{
			"code": "00000741"
		}
	],
	"text": "OXYCODONE"
},

not

"code": {
	"coding": [
		{
			"code": "00000741"
			"display": "OXYCODONE"
		}
	],
	"text": "OXYCODONE"
},

Expected behavior
In FHIR, coding.display needs to match coding.code, and should come from the coding system, not the text from the HL7 message. The text from the HL7 message (CWE.2) should be put in FHIR's CodeableConcept.text

HL7 message without including Patient.gender info (blank PID-8 field) fails to convert

Describe the bug
An HL7 message without including the patient's gender info (blank PID-8 field) fails to convert.
This field is optional (Cardinality 0..1 in FHIR 4.0 reference and according to the HL7 reference as well), thus it should convert into a JSON file.

To Reproduce
I tried to convert sample_unix.hl7 included in the converter (under src/test/resources) after having removed the gender info from it (|F|), so the PID segment became:

PID|0010||PID1234^5^M11^A^MR^HOSP~1234568965^^^USA^SS||DOE^JOHN^A^||19800202|||W|111 TEST_STREET_NAME^^TEST_CITY^NY^111-1111^USA||(905)111-1111|||S|ZZ|12^^^124|34-13-312||||TEST_BIRTH_PLACE

I ran the current HL7toFHIR converter on the edited sample_unix.hl7 and I got the error below:
ca.uhn.fhir.parser.DataFormatException: [element=“gender”] Invalid attribute value “?”: Unknown AdministrativeGender code ‘?’
at ca.uhn.fhir.parser.StrictErrorHandler.invalidValue(StrictErrorHandler.java:50)
at ca.uhn.fhir.parser.LenientErrorHandler.invalidValue(LenientErrorHandler.java:90)
at ca.uhn.fhir.parser.ParserState$PrimitiveState.attributeValue(ParserState.java:1350)
...
Expected behavior
I would expect the HL7 message to convert without that error, as the gender field is optional.

Desktop (please complete the following information):

  • OS: Mac OS
  • Version Big Sur

Convert patient multiple birth and deceased information

NOTE: This work was broken off from #94

Describe the bug
Add capability to find and convert the following patient information

  • Patient.multipleBirthBoolean / PID-24
  • Patient.multipleBirthInteger / PID-25
  • Patient.deceasedDateTime / PID-29
  • Patient.deceasedBoolean / PID-30

To Reproduce
Create a sample HL7V2.6 patient PID segment with aforementioned patient information.

Expected behavior
Patient information should be detected and added to corresponding fields in HL7 FHIR resources. See also Implementation Notes

Examples:

Multiple birth

{
  "resourceType": "Patient",
  "id": "infant-twin-1",
  "multipleBirthInteger": 1,      OR
  "multipleBirthBoolean": true,
...

Deceased

{
  "resourceType": "Patient",
  "id": "dead-person-example",
  "deceasedDateTime": "2015-02-14T13:42:00+10:00",      OR
  "deceasedBoolean": true,
...

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Mac OS
  • Version Big Sur

Additional context
Add any other context about the problem here.

Implementation Notes
Deceased
If the deceased date is present, parser assumes that deceased is true, and a .deceasedDateTime is created.
Multiple Births
If the multiple births integer is present, parser assumes that deceased is true, and a .multipleBirthInteger is created.

MSH-24.2 should not be required in the MSH segment

Describe the bug
Currently MSH-24.2 is required in the Message Header. The HL7 spec lists this as an Optional field so it shouldn't be required.

To Reproduce
Any HL7 message without a field entry in MSH-24.2 will fail conversion

Expected behavior
Any HL7 message without a field entry in MSH-24.2 should convert

Desktop (please complete the following information):

  • OS: Windows
  • Latest version of the converter

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.