I am not a person who loves to leave all things unfinished. This is no exception.
A while ago, I started blogging about how to work with HL7 in an easy way. I had to deal with it and I can guarantee you, my reader, that in some cases is not an easy task. On the first part I wrote about the structure of an HL7 message; now is time to handle this message in a systemic way (aka: developing).
While you have integration suites (I remember a few: Microsoft’s BizTalk, Oracle’s Fussion, SAP PI, etc.), some times you don’t need a über product for getting the job done. Sometimes it is perfect to write your-own-and-very-flexible code.
After googling a while, I found a little jewel for us developers. HAPI for Java developers and NHAPI for .Net ones. The original project is the Java one, so if you need some documentation you should go to the source project.
Now you got the essentials. It is time to show you some code, but first a little of context.
Recently I had to deal with the validation of affiliates to a Health Care company. This company uses HL7 internally. Also this company does not let you to contact them directly, you must use a carrier (another company who gets your message and, after validating it sends the data in HL7 format to the Health Care company). Some of this carriers asks for a plain (and proprietary) text file format to communicate with them, sometimes they expose an HL7 interface (Kudos from me to them).
Luckily for me in Argentina a long time ago there was an agreement (I don’t remember how I got this info, but it’s true) among the Carriers and the Health Care Companies to standardize the HL7 format for several operations (among others, the operations I needed to do).
HL7 Note: In reference to HL7, the protocol aims to create new customized messages types when those provided by the norm does not fit the business need. These messages are called Z messages. The Z messages can contain Z segments and Z groups, and all are locally defined by norm, so you can end up with a colliding set of HL7 Z elements (the same name of Z message/segment/group but different internal definition). In a nutshell: a nightmare.
Both HAPI and NHAPI are open source libraries and I choose NHAPI for the samples because I already have some code made on it.
Let’s define a new Z Segment:
Let’s define a new Z Message:
using System; using NHapi.Base; using NHapi.Base.Log; using NHapi.Base.Model; using NHapi.Base.Parser; using NHapi.Model.V24.Group; using NHapi.Model.V24.Segment; using ValidationProvider.HL7.Segment; namespace NHapi.Model.V24.Message { [Serializable] public class ZLA_Z22 : AbstractMessage { private string _n1; private string _n2; private string _n3; private string _n4; /// Creates a new ZLA_Z22 Group with custom IModelClassFactory. /// public ZLA_Z22(IModelClassFactory factory) : base(factory) { Init(factory); } /// /// Creates a new ZLA_Z22 Group with DefaultModelClassFactory. /// public ZLA_Z22() : base(new DefaultModelClassFactory()) { Init(new DefaultModelClassFactory()); } /// /// initalize method for ZLA_Z22. This does the segment setup for the message. /// private void Init(IModelClassFactory factory) { try { add(typeof(MSH), true, false); _n1 = add(typeof(ZLA_Z22_Authorization), false, false); add(typeof(ZXX), false, false); _n2 = add(typeof(ZLA_Z22_Data), true, false); add(typeof(PID), false, false); _n3 = add(typeof(ZLA_Z22_Insurance), false, true); add(typeof(DG1), false, true); _n4 = add(typeof(ZLA_Z22_ProcedureZ), true, true); add(typeof(PV1), false, false); add(typeof(NTE), false, true); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error creating " + GetType().Name + " - this is probably a bug in the source code generator.", e); } } #region Segments public MSH MSH { get { MSH ret; try { ret = (MSH)GetStructure("MSH"); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new Exception("An unexpected error ocurred", e); } return ret; } } public ZLA_Z22_Authorization Authorization { get { ZLA_Z22_Authorization ret; try { ret = (ZLA_Z22_Authorization)GetStructure(_n1); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new Exception("An unexpected error ocurred", e); } return ret; } } public ZXX ZXX { get { ZXX ret; try { ret = (ZXX)GetStructure("ZXX"); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new Exception("An unexpected error ocurred", e); } return ret; } } #region ZLA_Z22_Data /// /// Returns first repetition of ZLA_Z22_Data (Notes and Comments) - creates it if necessary /// public ZLA_Z22_Data GetZLA_Z22_Data() { ZLA_Z22_Data ret = null; try { ret = (ZLA_Z22_Data)GetStructure(_n2); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new System.Exception("An unexpected error ocurred", e); } return ret; } /// ///Returns a specific repetition of ZLA_Z22_Data /// * (Notes and Comments) - creates it if necessary /// throws HL7Exception if the repetition requested is more than one /// greater than the number of existing repetitions. /// public ZLA_Z22_Data GetZLA_Z22_Data(int rep) { return (ZLA_Z22_Data)GetStructure(_n2, rep); } /** * Returns the number of existing repetitions of ZLA_Z22_Data */ public int ZLA_Z22_DataRepetitionsUsed { get { int reps = -1; try { reps = GetAll(_n2).Length; } catch (HL7Exception e) { const string message = "Unexpected error accessing data - this is probably a bug in the source code generator."; HapiLogFactory.GetHapiLog(GetType()).Error(message, e); throw new System.Exception(message); } return reps; } } #endregion public PID PID { get { PID ret; try { ret = (PID)GetStructure("PID"); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new Exception("An unexpected error ocurred", e); } return ret; } } #region ZLA_Z22_Insurance /// /// Returns first repetition of ZLA_Z22_Insurance (Notes and Comments) - creates it if necessary /// public ZLA_Z22_Insurance GetZLA_Z22_Insurance() { ZLA_Z22_Insurance ret = null; try { ret = (ZLA_Z22_Insurance)GetStructure(_n3); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new System.Exception("An unexpected error ocurred", e); } return ret; } /// ///Returns a specific repetition of ZLA_Z22_Insurance /// * (Notes and Comments) - creates it if necessary /// throws HL7Exception if the repetition requested is more than one /// greater than the number of existing repetitions. /// public ZLA_Z22_Insurance GetZLA_Z22_Insurance(int rep) { return (ZLA_Z22_Insurance)GetStructure(_n3, rep); } /** * Returns the number of existing repetitions of ZLA_Z22_Insurance */ public int ZLA_Z22_InsuranceRepetitionsUsed { get { int reps = -1; try { reps = GetAll(_n3).Length; } catch (HL7Exception e) { const string message = "Unexpected error accessing data - this is probably a bug in the source code generator."; HapiLogFactory.GetHapiLog(GetType()).Error(message, e); throw new Exception(message); } return reps; } } #endregion #region ZIN /// /// Returns first repetition of ZIN (Notes and Comments) - creates it if necessary /// public ZIN GetZIN() { ZIN ret = null; try { ret = (ZIN)GetStructure("ZIN"); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new System.Exception("An unexpected error ocurred", e); } return ret; } /// ///Returns a specific repetition of ZIN /// * (Notes and Comments) - creates it if necessary /// throws HL7Exception if the repetition requested is more than one /// greater than the number of existing repetitions. /// public ZIN GetZIN(int rep) { return (ZIN)GetStructure("ZIN", rep); } /** * Returns the number of existing repetitions of ZIN */ public int ZINRepetitionsUsed { get { int reps = -1; try { reps = GetAll("ZIN").Length; } catch (HL7Exception e) { const string message = "Unexpected error accessing data - this is probably a bug in the source code generator."; HapiLogFactory.GetHapiLog(GetType()).Error(message, e); throw new System.Exception(message); } return reps; } } #endregion #region DG1 /// /// Returns first repetition of DG1 (Notes and Comments) - creates it if necessary /// public DG1 GetDG1() { DG1 ret = null; try { ret = (DG1)GetStructure("DG1"); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new System.Exception("An unexpected error ocurred", e); } return ret; } /// ///Returns a specific repetition of DG1 /// * (Notes and Comments) - creates it if necessary /// throws HL7Exception if the repetition requested is more than one /// greater than the number of existing repetitions. /// public DG1 GetDG1(int rep) { return (DG1)GetStructure("DG1", rep); } /** * Returns the number of existing repetitions of DG1 */ public int DG1RepetitionsUsed { get { int reps = -1; try { reps = GetAll("DG1").Length; } catch (HL7Exception e) { const string message = "Unexpected error accessing data - this is probably a bug in the source code generator."; HapiLogFactory.GetHapiLog(GetType()).Error(message, e); throw new System.Exception(message); } return reps; } } #endregion #region ZLA_Z22_ProcedureZ /// /// Returns first repetition of ZLA_Z22_ProcedureZ (Notes and Comments) - creates it if necessary /// public ZLA_Z22_ProcedureZ GetZLA_Z22_ProcedureZ() { ZLA_Z22_ProcedureZ ret = null; try { ret = (ZLA_Z22_ProcedureZ)GetStructure(_n4); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new System.Exception("An unexpected error ocurred", e); } return ret; } /// ///Returns a specific repetition of ZLA_Z22_ProcedureZ /// * (Notes and Comments) - creates it if necessary /// throws HL7Exception if the repetition requested is more than one /// greater than the number of existing repetitions. /// public ZLA_Z22_ProcedureZ GetZLA_Z22_ProcedureZ(int rep) { return (ZLA_Z22_ProcedureZ)GetStructure(_n4, rep); } /** * Returns the number of existing repetitions of ZLA_Z22_ProcedureZ */ public int ZLA_Z22_ProcedureZRepetitionsUsed { get { int reps = -1; try { reps = GetAll(_n4).Length; } catch (HL7Exception e) { string message = "Unexpected error accessing data - this is probably a bug in the source code generator."; HapiLogFactory.GetHapiLog(GetType()).Error(message, e); throw new System.Exception(message); } return reps; } } #endregion public PV1 PV1 { get { PV1 ret; try { ret = (PV1)GetStructure("PV1"); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new Exception("An unexpected error ocurred", e); } return ret; } } #region NTE /// /// Returns first repetition of NTE (Notes and Comments) - creates it if necessary /// public NTE GetNTE() { NTE ret = null; try { ret = (NTE)GetStructure("NTE"); } catch (HL7Exception e) { HapiLogFactory.GetHapiLog(GetType()).Error("Unexpected error accessing data - this is probably a bug in the source code generator.", e); throw new System.Exception("An unexpected error ocurred", e); } return ret; } /// ///Returns a specific repetition of NTE /// * (Notes and Comments) - creates it if necessary /// throws HL7Exception if the repetition requested is more than one /// greater than the number of existing repetitions. /// public NTE GetNTE(int rep) { return (NTE)GetStructure("NTE", rep); } /** * Returns the number of existing repetitions of NTE */ public int NTERepetitionsUsed { get { int reps = -1; try { reps = GetAll("NTE").Length; } catch (HL7Exception e) { const string message = "Unexpected error accessing data - this is probably a bug in the source code generator."; HapiLogFactory.GetHapiLog(GetType()).Error(message, e); throw new System.Exception(message); } return reps; } } #endregion #endregion } } |
Note: This is not the original post. I had to modify it to avoid futher problems with a previous employer. Feel free to contact me for any HL7 questions you may have.
using System; using NHapi.Base; using NHapi.Base.Parser; using NHapi.Base.Model; using NHapi.Model.V24.Datatype; using NHapi.Base.Log; namespace ValidationProvider.HL7.Segment { /// /// Represents a ZXX Segment. This is a locally defined segment /// [Serializable] public sealed class ZXX : AbstractSegment { public ZXX(IGroup parent, IModelClassFactory factory): base(parent, factory) { IMessage message = Message; try { add(typeof(EI), true, 0, 1, new object[] { message }, "NroControlDelPrestador"); add(typeof(EI), false,1, 4, new object[] { message }, "NroControlDelFinanciador"); add(typeof(CE), false, 1, 180, new object[] { message }, "EstadoDeLaAutorizacion"); add(typeof(EI), false, 1, 180, new object[] { message }, "NumeroDePreAutorizacion"); add(typeof(TS), false, 1, 180, new object[] { message }, "FechaDeEmisionDePreAutorizacion"); add(typeof(CPMO), false, 1, 180, new object[] { message }, "ValorDelArancelDelCopago"); } catch (HL7Exception he) { HapiLogFactory.GetHapiLog(GetType()).Error("Can't instantiate " + GetType().Name, he); } } public EI NroControlPrestador { get { EI ret; try { IType t = GetField(1,0); ret = (EI)t; } catch (HL7Exception he) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", he); throw new Exception("An unexpected error ocurred", he); } catch (Exception ex) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", ex); throw new Exception("An unexpected error ocurred", ex); } return ret; } } public EI NroControlFinanciador { get { EI ret; try { IType t = GetField(2, 0); ret = (EI)t; } catch (HL7Exception he) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", he); throw new Exception("An unexpected error ocurred", he); } catch (Exception ex) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", ex); throw new Exception("An unexpected error ocurred", ex); } return ret; } } public CE EstadoAutorizacion { get { CE ret; try { IType t = GetField(3, 0); ret = (CE)t; } catch (HL7Exception he) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", he); throw new Exception("An unexpected error ocurred", he); } catch (Exception ex) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", ex); throw new Exception("An unexpected error ocurred", ex); } return ret; } } public EI NumeroPreAutorizacion { get { EI ret; try { IType t = GetField(4, 0); ret = (EI)t; } catch (HL7Exception he) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", he); throw new Exception("An unexpected error ocurred", he); } catch (Exception ex) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", ex); throw new Exception("An unexpected error ocurred", ex); } return ret; } } public TS FechaEmisionPreAutorizacion { get { TS ret; try { IType t = GetField(5, 0); ret = (TS)t; } catch (HL7Exception he) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", he); throw new Exception("An unexpected error ocurred", he); } catch (Exception ex) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", ex); throw new Exception("An unexpected error ocurred", ex); } return ret; } } public CPMO ValorArancelCopago { get { CPMO ret; try { IType t = GetField(6, 0); ret = (CPMO)t; } catch (HL7Exception he) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", he); throw new Exception("An unexpected error ocurred", he); } catch (Exception ex) { HapiLogFactory.GetHapiLog(GetType()).Error( "Unexpected problem obtaining field value. This is a bug.", ex); throw new Exception("An unexpected error ocurred", ex); } return ret; } } } } |
