crs4 / hl7apy

Python library to parse, create and handle HL7 v2 messages.
http://crs4.github.io/hl7apy/
MIT License
224 stars 88 forks source link

Can't get repetitions for several message types #76

Open n-mcf opened 4 years ago

n-mcf commented 4 years ago

Hello,

The "messages.py" files within the various version folders do not contain many of the possible elements. I believe this prevents us from being able to determine repetitions for elements when attempting to parse them.

For example, this message: MSH|^~\&|ATHENANET|99999^MA - athenahealth Testing^1^Test Clinic|TestInterface||201505181347||ADT^A31|183M90009|T|2.3.1 EVN|A31|201505180146|||username PID||456789|456789|456789|LASTNAME^FIRSTNAME^MIDDLE^SUFFIX||19900101|M|PREFERREDNAME|2028-9^Asian|ADDRESS^ADDRESS (CTD)^CITY^STATE^00000^COUNTRY||(111)111-1111^PRN^PH^^1^111^1111111~(333)333-3333^WPN^PH^^1^333^3333333~Patientemail@email.com^NET^^Patientemail@email.com~(222)222-2222^ORN^CP^^1^222^2222222|(333)333-3333^WPN^PH^^1^333^3333333|eng^English|S|||000000000||ATHENA|2186-5^Not Hispanic or Latino PD1||||A12123^PCPLASTNAME^PCPFIRSTNAME NK1|1|KIN^NEXTOF|CHILD||||N NK1|2|CONTACT^EMERGENCY|PARENT||||C PV1|||2^TEST DEPARTMENT^^TEST DEPARTMENT||||12345678^SEUSS^DOC|98765432^REFERRING^DOC|||||||||12345678^SEUSS^DOC GT1|1||GTORLASTNAME^GTORFIRSTNAME^GTORMIDDLE^GTORSUFFIX||ADDRESS^ADDRESS (CTD)^CITY^STATE^00000^COUNTRY|(gtorphone^gtoremail@email.com||19600601|||Child|||||ATHENA|GTOREMPLOYERADDRESS^^CITY^STATE^00000|(999)999-9999|||||||||||||||||||||||||||EMERGENCY CONTACT|(EChomephone||PARENT IN1|1|982^UNITED HEALTHCARE|123^United Healthcare|United Healthcare|PO BOX 740800^^ATLANTA^GA^30374-0800||(877)842-3210||||ATHENA||||C1|LASTNAME^FIRSTNAME^MIDDLENNAME|Self|19880601|ADDRESS^ADDRESS (CTD)^BRIGHTON^MA^02135^1^000000000|||1||||20150409||||||||||12345|||||||M Simply gives an empty dictionary when attempting to use the repetitions attribute. Contrast it against a message like the following where I can use the attribute to determine if segments can be repeated or not: MSH|^~\&|SendingApp|SendingFac|ReceivingApp|ReceivingFac|2007509101832132||ADT^A01^ADT_A01|200760910183213200723|D|2.5 EVN||2007509101832132 PID|1||P410000^^^||""||196505|M|||^^^OR^97007 PV1|1|I||||||||||||||||||||||||||||||||||||||||||200750816122536 PV2|||^^^^POSSIBLE MENINGITIS OR CVA OBX|1|NM|21612-7^REPORTED PATIENT AGE^LN||40|a^Year^UCUM|||||F DG1|1||784.3^APHASIA^I9C||200750816|A DG1|2||784.0^HEADACHE^I9C||200750816|A DG1|3||781.6^MENINGISMUS^I9C||200750816|A Is there something I'm missing in how to properly handle the former messages? Are elements intentionally not included in the messages.py file because they are supposed to be dealt with in a different way?

Thanks, Neil

svituz commented 4 years ago

Hi @n-mcf, the difference between the two messages is that the first one is a message of version 2.3.1 which misses the MSH.9.3 (MESSAGE_STRUCTURE), used by the module to get the correct structure. This is legal in HL7 version < 2.4 but makes it difficult to handle the message. I explain it (hopefully) clearer: in cases where MSH.9.3 is missing, HL7apy tries to infer the message name as "{MSH.9.1}_{MSH.9.2}"; if this formatting produces a legal structure (i.e., a valid message type), it uses it to get the reference structure from the messages.py of the correct version. Using this rule with your first message, we get ADT_A31 which, unfortunately, is not a correct message structure in the 2.3.1 version. In this case, the module handles it as an unknown message: that's why the repetitions dictionary is empty. It would be different if MSH.9 were, for example, ADT^A31^ADT_A05: in this case, the module would get the ADT_A05 structure to validate the message. The second message does not have this problem since version 2.5 made MSH.9.3 mandatory and all (legal) messages have it. So, long story short, unfortunately, it is not possible to get the repetitions in the first message since it is not possible to get the structure.

n-mcf commented 4 years ago

Ah, thanks for the explanation. I think I understand.

As per the specs, in 2.3.1, A31 doesn't have it's own unique message structure and instead reuses the one from ADT_A28.

In this case, the message should be written as ADT^A31^ADT_A28, am I correct?

If so, would we consider adding this as an additional mapping element for these inference cases?

Thanks!

svituz commented 4 years ago

Well, if you add ADT_A28 to the message, you will load the correct structure (although, currently, we don't have that structure, I don't know why, but this is easy to fix). But the problem still exists for messages without MSH.9.3. In this case, it's not possible to infer the structure since there are multiple messages with A31 as TRIGGER EVENT (e.g., ADT_A01, ADT_A28) and, if MSH.9.3 is not declared, we can't understand which one is to be considered. If you have any control over the messages you can add or ask your interoperability counterpart to add the MSH.9.3 to the messages.

n-mcf commented 4 years ago

That makes complete sense; A28 and A31 seem to be corner cases in that they can use two different message structures.

Would we consider the inferred mapping for elements that are a little less so, such as v2.3.1 A21?