///<summary>Returns null if there is no DFT defined for the enabled HL7Def.</summary> public static MessageHL7 GenerateDFT(List<Procedure> procList,EventTypeHL7 eventType,Patient pat,Patient guar,long aptNum,string pdfDescription,string pdfDataString) {//add event (A04 etc) parameters later if needed //In \\SERVERFILES\storage\OPEN DENTAL\Programmers Documents\Standards (X12, ADA, etc)\HL7\Version2.6\V26_CH02_Control_M4_JAN2007.doc //On page 28, there is a Message Construction Pseudocode as well as a flowchart which might help. Provider prov=Providers.GetProv(Patients.GetProvNum(pat)); Appointment apt=Appointments.GetOneApt(aptNum); MessageHL7 messageHL7=new MessageHL7(MessageTypeHL7.DFT); HL7Def hl7Def=HL7Defs.GetOneDeepEnabled(); if(hl7Def==null) { return null; } //find a DFT message in the def HL7DefMessage hl7DefMessage=null; for(int i=0;i<hl7Def.hl7DefMessages.Count;i++) { if(hl7Def.hl7DefMessages[i].MessageType==MessageTypeHL7.DFT) { hl7DefMessage=hl7Def.hl7DefMessages[i]; //continue; break; } } if(hl7DefMessage==null) {//DFT message type is not defined so do nothing and return return null; } for(int s=0;s<hl7DefMessage.hl7DefSegments.Count;s++) { int countRepeat=1; if(hl7DefMessage.hl7DefSegments[s].SegmentName==SegmentNameHL7.FT1) { countRepeat=procList.Count; } //for example, countRepeat can be zero in the case where we are only sending a PDF of the TP to eCW, and no procs. for(int repeat=0;repeat<countRepeat;repeat++) {//FT1 is optional and can repeat so add as many FT1's as procs in procList //if(hl7DefMessage.hl7DefSegments[s].SegmentName==SegmentNameHL7.FT1) { if(hl7DefMessage.hl7DefSegments[s].SegmentName==SegmentNameHL7.FT1 && procList.Count>repeat) { prov=Providers.GetProv(procList[repeat].ProvNum); } SegmentHL7 seg=new SegmentHL7(hl7DefMessage.hl7DefSegments[s].SegmentName); seg.SetField(0,hl7DefMessage.hl7DefSegments[s].SegmentName.ToString()); for(int f=0;f<hl7DefMessage.hl7DefSegments[s].hl7DefFields.Count;f++) { string fieldName=hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].FieldName; if(fieldName=="") {//If fixed text instead of field name just add text to segment seg.SetField(hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].OrdinalPos,hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].FixedText); } else { //seg.SetField(hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].OrdinalPos, //FieldConstructor.GenerateDFT(hl7Def,fieldName,pat,prov,procList[repeat],guar,apt,repeat+1,eventType,pdfDescription,pdfDataString)); Procedure proc=null; if(procList.Count>repeat) {//procList could be an empty list proc=procList[repeat]; } seg.SetField(hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].OrdinalPos, FieldConstructor.GenerateDFT(hl7Def,fieldName,pat,prov,proc,guar,apt,repeat+1,eventType,pdfDescription,pdfDataString)); } } messageHL7.Segments.Add(seg); } } return messageHL7; }
public void AddMessage(HL7DefMessage msg,MessageTypeHL7 messageType,EventTypeHL7 eventType,InOutHL7 inOrOut,int itemOrder,string note) { if(hl7DefMessages==null) { hl7DefMessages=new List<HL7DefMessage>(); } msg.MessageType=messageType; msg.EventType=eventType; msg.InOrOut=inOrOut; msg.ItemOrder=itemOrder; msg.Note=note; this.hl7DefMessages.Add(msg); }
public MessageHL7(string msgtext) { AckCode = ""; ControlId = ""; AckEvent = ""; originalMsgText = msgtext; Segments = new List <SegmentHL7>(); string[] rows = msgtext.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); SegmentHL7 segment; for (int i = 0; i < rows.Length; i++) { segment = new SegmentHL7(rows[i]); //this creates the field objects. Segments.Add(segment); if (i == 0 && segment.Name == SegmentNameHL7.MSH) { //js 7/3/12 Make this more intelligent because we also now need the suffix string msgtype = segment.GetFieldComponent(8, 0); //We force the user to leave the 'messageType' field in this position, position 8 of the MSH segment string evnttype = segment.GetFieldComponent(8, 1); AckEvent = evnttype; //We will use this when constructing the acknowledgment to echo back to sender the same event type sent to us //If message type or event type are not in this list, they will default to the not supported type and will not be processed if (msgtype == MessageTypeHL7.ADT.ToString()) { MsgType = MessageTypeHL7.ADT; } else if (msgtype == MessageTypeHL7.ACK.ToString()) { MsgType = MessageTypeHL7.ACK; } else if (msgtype == MessageTypeHL7.SIU.ToString()) { MsgType = MessageTypeHL7.SIU; } else if (msgtype == MessageTypeHL7.DFT.ToString()) { MsgType = MessageTypeHL7.DFT; } if (evnttype == EventTypeHL7.A04.ToString()) { EventType = EventTypeHL7.A04; } else if (evnttype == EventTypeHL7.P03.ToString()) { EventType = EventTypeHL7.P03; } else if (evnttype == EventTypeHL7.S12.ToString()) { EventType = EventTypeHL7.S12; } } } }
public void AddMessage(HL7DefMessage msg, MessageTypeHL7 messageType, EventTypeHL7 eventType, InOutHL7 inOrOut, int itemOrder, string note) { if (hl7DefMessages == null) { hl7DefMessages = new List <HL7DefMessage>(); } msg.MessageType = messageType; msg.EventType = eventType; msg.InOrOut = inOrOut; msg.ItemOrder = itemOrder; msg.Note = note; this.hl7DefMessages.Add(msg); }
public MessageHL7(string msgtext) { AckCode=""; ControlId=""; AckEvent=""; originalMsgText=msgtext; Segments=new List<SegmentHL7>(); string[] rows=msgtext.Split(new string[] { "\r","\n" },StringSplitOptions.RemoveEmptyEntries); //We need to get the separator characters in order to create the field objects. //The separators are part of the MSH segment and we force users to leave them in position 1 for incoming messages. Delimiters=new char[] { '^','~','\\','&' };//this is the default, but we will get them from the MSH segment of the incoming message in case they are using something unique. for(int i=0;i<rows.Length;i++) { string[] fields=rows[i].Split(new string[] { "|" },StringSplitOptions.None); if(fields.Length>1 && fields[0]=="MSH" && fields[1].Length>0) { //Encoding characters are in the following order: component separator, repetition separator, escape character, subcomponent separator Delimiters=fields[1].ToCharArray();//we force users to leave the delimiters in position 1 of the MSH segment break; } } SegmentHL7 segment; for(int i=0;i<rows.Length;i++) { segment=new SegmentHL7(rows[i],Delimiters);//this creates the field objects. Segments.Add(segment); if(i==0 && segment.Name==SegmentNameHL7.MSH) { //js 7/3/12 Make this more intelligent because we also now need the suffix string msgtype=segment.GetFieldComponent(8,0);//We force the user to leave the 'messageType' field in this position, position 8 of the MSH segment string evnttype=segment.GetFieldComponent(8,1); string msgStructure=segment.GetFieldComponent(8,2); AckEvent=evnttype;//We will use this when constructing the acknowledgment to echo back to sender the same event type sent to us //If message type or event type are not in this list, they will default to the not supported type and will not be processed try { MsgType=(MessageTypeHL7)Enum.Parse(typeof(MessageTypeHL7),msgtype,true); } catch(Exception ex) { MsgType=MessageTypeHL7.NotDefined; } try { EventType=(EventTypeHL7)Enum.Parse(typeof(EventTypeHL7),evnttype,true); } catch(Exception ex) { EventType=EventTypeHL7.NotDefined; } try { MsgStructure=(MessageStructureHL7)Enum.Parse(typeof(MessageStructureHL7),msgStructure,true); } catch(Exception ex) { MsgStructure=MessageStructureHL7.NotDefined; } } } }
public MessageHL7(string msgtext) { AckCode=""; ControlId=""; AckEvent=""; originalMsgText=msgtext; Segments=new List<SegmentHL7>(); string[] rows=msgtext.Split(new string[] { "\r","\n" },StringSplitOptions.RemoveEmptyEntries); SegmentHL7 segment; for(int i=0;i<rows.Length;i++) { segment=new SegmentHL7(rows[i]);//this creates the field objects. Segments.Add(segment); if(i==0 && segment.Name==SegmentNameHL7.MSH) { //js 7/3/12 Make this more intelligent because we also now need the suffix string msgtype=segment.GetFieldComponent(8,0);//We force the user to leave the 'messageType' field in this position, position 8 of the MSH segment string evnttype=segment.GetFieldComponent(8,1); AckEvent=evnttype;//We will use this when constructing the acknowledgment to echo back to sender the same event type sent to us //If message type or event type are not in this list, they will default to the not supported type and will not be processed if(msgtype==MessageTypeHL7.ADT.ToString()) { MsgType=MessageTypeHL7.ADT; } else if(msgtype==MessageTypeHL7.ACK.ToString()) { MsgType=MessageTypeHL7.ACK; } else if(msgtype==MessageTypeHL7.SIU.ToString()) { MsgType=MessageTypeHL7.SIU; } else if(msgtype==MessageTypeHL7.DFT.ToString()) { MsgType=MessageTypeHL7.DFT; } if(evnttype==EventTypeHL7.A04.ToString()) { EventType=EventTypeHL7.A04; } else if(evnttype==EventTypeHL7.P03.ToString()) { EventType=EventTypeHL7.P03; } else if(evnttype==EventTypeHL7.S12.ToString()) { EventType=EventTypeHL7.S12; } } } }
///<summary>Returns null if there is no HL7Def enabled or if there is no outbound ADT defined for the enabled HL7Def.</summary> public static MessageHL7 GenerateADT(Patient pat, Patient guar, EventTypeHL7 eventType) { HL7Def hl7Def = HL7Defs.GetOneDeepEnabled(); if (hl7Def == null) { return(null); } //find an outbound ADT message in the def HL7DefMessage hl7DefMessage = null; for (int i = 0; i < hl7Def.hl7DefMessages.Count; i++) { if (hl7Def.hl7DefMessages[i].MessageType == MessageTypeHL7.ADT && hl7Def.hl7DefMessages[i].InOrOut == InOutHL7.Outgoing) { hl7DefMessage = hl7Def.hl7DefMessages[i]; //continue; break; } } if (hl7DefMessage == null) //ADT message type is not defined so do nothing and return { return(null); } if (PrefC.GetBool(PrefName.ShowFeaturePatientClone)) { pat = Patients.GetOriginalPatientForClone(pat); } MessageHL7 messageHL7 = new MessageHL7(MessageTypeHL7.ADT); Provider prov = Providers.GetProv(Patients.GetProvNum(pat)); List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum); for (int i = 0; i < hl7DefMessage.hl7DefSegments.Count; i++) { int countRepeat = 1; //IN1 segment can repeat, get the number of current insurance plans attached to the patient if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1) { countRepeat = listPatPlans.Count; } //countRepeat is usually 1, but for repeatable/optional fields, it may be 0 or greater than 1 //for example, countRepeat can be zero if the patient does not have any current insplans, in which case no IN1 segments will be included for (int j = 0; j < countRepeat; j++) //IN1 is optional and can repeat so add as many as listPatplans { PatPlan patplanCur = null; InsPlan insplanCur = null; InsSub inssubCur = null; Carrier carrierCur = null; Patient patSub = null; if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1) //index repeat is guaranteed to be less than listPatplans.Count { patplanCur = listPatPlans[j]; inssubCur = InsSubs.GetOne(patplanCur.InsSubNum); insplanCur = InsPlans.RefreshOne(inssubCur.PlanNum); carrierCur = Carriers.GetCarrier(insplanCur.CarrierNum); if (pat.PatNum == inssubCur.Subscriber) { patSub = pat.Copy(); } else { patSub = Patients.GetPat(inssubCur.Subscriber); } } SegmentHL7 seg = new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName); seg.SetField(0, hl7DefMessage.hl7DefSegments[i].SegmentName.ToString()); for (int k = 0; k < hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count; k++) { string fieldName = hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FieldName; if (fieldName == "") //If fixed text instead of field name just add text to segment { seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos, hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FixedText); } else { string fieldValue = ""; if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1) { fieldValue = FieldConstructor.GenerateFieldIN1(hl7Def, fieldName, j + 1, patplanCur, inssubCur, insplanCur, carrierCur, listPatPlans.Count, patSub); } else { fieldValue = FieldConstructor.GenerateFieldADT(hl7Def, fieldName, pat, prov, guar, j + 1, eventType, seg.Name); } seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos, fieldValue); } } messageHL7.Segments.Add(seg); } } return(messageHL7); }
public void AddMessage(HL7DefMessage msg, MessageTypeHL7 messageType, EventTypeHL7 eventType, InOutHL7 inOrOut, int itemOrder) { AddMessage(msg, messageType, eventType, inOrOut, itemOrder, ""); }
///<summary>apt, guar, proc, prov and pdfDataString can be null and will return an empty string if a field requires that object</summary> public static string GenerateDFT(HL7Def def,string fieldName,Patient pat,Provider prov,Procedure proc,Patient guar,Appointment apt,int sequenceNum,EventTypeHL7 eventType,string pdfDescription,string pdfDataString) { //big long list of fieldnames that we support switch(fieldName){ case "apt.AptNum": if(apt==null) { return ""; } else { return apt.AptNum.ToString(); } case "dateTime.Now": return gDTM(DateTime.Now,14); case "eventType": return eventType.ToString(); case "guar.addressCityStateZip": if(guar==null) { return ""; } else { return gConcat(def.ComponentSeparator,guar.Address,guar.Address2,guar.City,guar.State,guar.Zip); } case "guar.birthdateTime": if(guar==null) { return ""; } else { return gDTM(guar.Birthdate,8); } case "guar.Gender": if(guar==null) { return ""; } else { return gIS(guar); } case "guar.HmPhone": if(guar==null) { return ""; } else { return gXTN(guar.HmPhone,10); } case "guar.nameLFM": if(guar==null) { return ""; } else { return gConcat(def.ComponentSeparator,guar.LName,guar.FName,guar.MiddleI); } case "guar.PatNum": if(guar==null) { return ""; } else { return guar.PatNum.ToString(); } case "guar.SSN": if(guar==null) { return ""; } else { return guar.SSN; } case "guar.WkPhone": if(guar==null) { return ""; } else { return gXTN(guar.WkPhone,10); } case "messageControlId": return Guid.NewGuid().ToString("N"); case "messageType": return gConcat(def.ComponentSeparator,"DFT",eventType.ToString()); case "pat.addressCityStateZip": return gConcat(def.ComponentSeparator,pat.Address,pat.Address2,pat.City,pat.State,pat.Zip); case "pat.birthdateTime": return gDTM(pat.Birthdate,8); case "pat.ChartNumber": return pat.ChartNumber; case "pat.Gender": return gIS(pat); case "pat.HmPhone": return gXTN(pat.HmPhone,10); case "pat.nameLFM": return gConcat(def.ComponentSeparator,pat.LName,pat.FName,pat.MiddleI); case "pat.PatNum": return pat.PatNum.ToString(); case "pat.Position": return gPos(pat); case "pat.Race": return gRace(pat); case "pat.SSN": return pat.SSN; case "pat.WkPhone": return gXTN(pat.WkPhone,10); case "pdfDescription": return pdfDescription; case "pdfDataAsBase64": if(pdfDataString==null) { return ""; } else { return pdfDataString; } case "proc.DiagnosticCode": if(proc==null) { return ""; } if(proc.DiagnosticCode==null) { return ""; } else { return proc.DiagnosticCode; } case "proc.procDateTime": if(proc==null) { return ""; } else { return gDTM(proc.ProcDate,14); } case "proc.ProcFee": if(proc==null) { return ""; } else { return proc.ProcFee.ToString("F2"); } case "proc.ProcNum": if(proc==null) { return ""; } else { return proc.ProcNum.ToString(); } case "proc.toothSurfRange": if(proc==null) { return ""; } else { return gTreatArea(def.ComponentSeparator,proc); } case "proccode.ProcCode": if(proc==null) { return ""; } else { return gProcCode(proc); } case "prov.provIdNameLFM": if(prov==null) { return ""; } else { return gConcat(def.ComponentSeparator,prov.EcwID,prov.LName,prov.FName,prov.MI); } case "separators^~\\&": return gSep(def); case "sequenceNum": return sequenceNum.ToString(); default: return ""; } }
///<summary>Returns null if there is no HL7Def enabled or if there is no outbound SIU defined for the enabled HL7Def.</summary> public static MessageHL7 GenerateSIU(Patient pat, Patient guar, EventTypeHL7 eventType, Appointment apt) { HL7Def hl7Def = HL7Defs.GetOneDeepEnabled(); if (hl7Def == null) { return(null); } //find an outbound SIU message in the def HL7DefMessage hl7DefMessage = null; for (int i = 0; i < hl7Def.hl7DefMessages.Count; i++) { if (hl7Def.hl7DefMessages[i].MessageType == MessageTypeHL7.SIU && hl7Def.hl7DefMessages[i].InOrOut == InOutHL7.Outgoing) { hl7DefMessage = hl7Def.hl7DefMessages[i]; //continue; break; } } if (hl7DefMessage == null) //SIU message type is not defined so do nothing and return { return(null); } if (apt == null) //SIU messages must have an appointment { return(null); } if (PrefC.GetBool(PrefName.ShowFeaturePatientClone)) { pat = Patients.GetOriginalPatientForClone(pat); } MessageHL7 messageHL7 = new MessageHL7(MessageTypeHL7.SIU); Provider prov = Providers.GetProv(apt.ProvNum); for (int i = 0; i < hl7DefMessage.hl7DefSegments.Count; i++) { int repeatCount = 1; //AIP segment can repeat, once for the dentist on the appt and once for the hygienist if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.AIP && apt.ProvHyg > 0) { repeatCount = 2; } for (int j = 0; j < repeatCount; j++) //AIP will be repeated if there is a dentist and a hygienist on the appt { if (j > 0) { prov = Providers.GetProv(apt.ProvHyg); if (prov == null) { break; //shouldn't happen, apt.ProvHyg would have to be set to an invalid ProvNum on the appt, just in case } } SegmentHL7 seg = new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName); seg.SetField(0, hl7DefMessage.hl7DefSegments[i].SegmentName.ToString()); for (int k = 0; k < hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count; k++) { string fieldName = hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FieldName; if (fieldName == "") //If fixed text instead of field name just add text to segment { seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos, hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FixedText); } else { string fieldValue = FieldConstructor.GenerateFieldSIU(hl7Def, fieldName, pat, prov, guar, apt, j + 1, eventType, seg.Name); seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos, fieldValue); } } messageHL7.Segments.Add(seg); } } return(messageHL7); }
///<summary>Returns null if there is no HL7Def enabled or if there is no outbound ADT defined for the enabled HL7Def.</summary> public static MessageHL7 GenerateADT(Patient pat,Patient guar,EventTypeHL7 eventType) { HL7Def hl7Def=HL7Defs.GetOneDeepEnabled(); if(hl7Def==null) { return null; } //find an outbound ADT message in the def HL7DefMessage hl7DefMessage=null; for(int i=0;i<hl7Def.hl7DefMessages.Count;i++) { if(hl7Def.hl7DefMessages[i].MessageType==MessageTypeHL7.ADT && hl7Def.hl7DefMessages[i].InOrOut==InOutHL7.Outgoing) { hl7DefMessage=hl7Def.hl7DefMessages[i]; //continue; break; } } if(hl7DefMessage==null) {//ADT message type is not defined so do nothing and return return null; } if(PrefC.GetBool(PrefName.ShowFeaturePatientClone)) { Patient patClone; Patient patNonClone; List<Patient> listAmbiguousMatches; Patients.GetCloneAndNonClone(pat,out patClone,out patNonClone,out listAmbiguousMatches); if(patNonClone!=null) { pat=patNonClone; } } MessageHL7 messageHL7=new MessageHL7(MessageTypeHL7.ADT); Provider prov=Providers.GetProv(Patients.GetProvNum(pat)); List<PatPlan> listPatPlans=PatPlans.Refresh(pat.PatNum); for(int i=0;i<hl7DefMessage.hl7DefSegments.Count;i++) { int countRepeat=1; //IN1 segment can repeat, get the number of current insurance plans attached to the patient if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.IN1) { countRepeat=listPatPlans.Count; } //countRepeat is usually 1, but for repeatable/optional fields, it may be 0 or greater than 1 //for example, countRepeat can be zero if the patient does not have any current insplans, in which case no IN1 segments will be included for(int j=0;j<countRepeat;j++) {//IN1 is optional and can repeat so add as many as listPatplans PatPlan patplanCur=null; InsPlan insplanCur=null; InsSub inssubCur=null; Carrier carrierCur=null; Patient patSub=null; if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.IN1) {//index repeat is guaranteed to be less than listPatplans.Count patplanCur=listPatPlans[j]; inssubCur=InsSubs.GetOne(patplanCur.InsSubNum); insplanCur=InsPlans.RefreshOne(inssubCur.PlanNum); carrierCur=Carriers.GetCarrier(insplanCur.CarrierNum); if(pat.PatNum==inssubCur.Subscriber) { patSub=pat.Copy(); } else { patSub=Patients.GetPat(inssubCur.Subscriber); } } SegmentHL7 seg=new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName); seg.SetField(0,hl7DefMessage.hl7DefSegments[i].SegmentName.ToString()); for(int k=0;k<hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count;k++) { string fieldName=hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FieldName; if(fieldName=="") {//If fixed text instead of field name just add text to segment seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos,hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FixedText); } else { string fieldValue=""; if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.IN1) { fieldValue=FieldConstructor.GenerateFieldIN1(hl7Def,fieldName,j+1,patplanCur,inssubCur,insplanCur,carrierCur,listPatPlans.Count,patSub); } else { fieldValue=FieldConstructor.GenerateFieldADT(hl7Def,fieldName,pat,prov,guar,j+1,eventType,seg.Name); } seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos,fieldValue); } } messageHL7.Segments.Add(seg); } } return messageHL7; }
///<summary>Returns null if there is no DFT defined for the enabled HL7Def.</summary> public static MessageHL7 GenerateDFT(List <Procedure> procList, EventTypeHL7 eventType, Patient pat, Patient guar, long aptNum, string pdfDescription, string pdfDataString) //add event (A04 etc) parameters later if needed //In \\SERVERFILES\storage\OPEN DENTAL\Programmers Documents\Standards (X12, ADA, etc)\HL7\Version2.6\V26_CH02_Control_M4_JAN2007.doc //On page 28, there is a Message Construction Pseudocode as well as a flowchart which might help. { Provider prov = Providers.GetProv(Patients.GetProvNum(pat)); Appointment apt = Appointments.GetOneApt(aptNum); MessageHL7 messageHL7 = new MessageHL7(MessageTypeHL7.DFT); HL7Def hl7Def = HL7Defs.GetOneDeepEnabled(); if (hl7Def == null) { return(null); } //find a DFT message in the def HL7DefMessage hl7DefMessage = null; for (int i = 0; i < hl7Def.hl7DefMessages.Count; i++) { if (hl7Def.hl7DefMessages[i].MessageType == MessageTypeHL7.DFT) { hl7DefMessage = hl7Def.hl7DefMessages[i]; //continue; break; } } if (hl7DefMessage == null) //DFT message type is not defined so do nothing and return { return(null); } for (int s = 0; s < hl7DefMessage.hl7DefSegments.Count; s++) { int countRepeat = 1; if (hl7DefMessage.hl7DefSegments[s].SegmentName == SegmentNameHL7.FT1) { countRepeat = procList.Count; } //for example, countRepeat can be zero in the case where we are only sending a PDF of the TP to eCW, and no procs. for (int repeat = 0; repeat < countRepeat; repeat++) //FT1 is optional and can repeat so add as many FT1's as procs in procList //if(hl7DefMessage.hl7DefSegments[s].SegmentName==SegmentNameHL7.FT1) { { if (hl7DefMessage.hl7DefSegments[s].SegmentName == SegmentNameHL7.FT1 && procList.Count > repeat) { prov = Providers.GetProv(procList[repeat].ProvNum); } SegmentHL7 seg = new SegmentHL7(hl7DefMessage.hl7DefSegments[s].SegmentName); seg.SetField(0, hl7DefMessage.hl7DefSegments[s].SegmentName.ToString()); for (int f = 0; f < hl7DefMessage.hl7DefSegments[s].hl7DefFields.Count; f++) { string fieldName = hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].FieldName; if (fieldName == "") //If fixed text instead of field name just add text to segment { seg.SetField(hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].OrdinalPos, hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].FixedText); } else { //seg.SetField(hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].OrdinalPos, //FieldConstructor.GenerateDFT(hl7Def,fieldName,pat,prov,procList[repeat],guar,apt,repeat+1,eventType,pdfDescription,pdfDataString)); Procedure proc = null; if (procList.Count > repeat) //procList could be an empty list { proc = procList[repeat]; } seg.SetField(hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].OrdinalPos, FieldConstructor.GenerateDFT(hl7Def, fieldName, pat, prov, proc, guar, apt, repeat + 1, eventType, pdfDescription, pdfDataString)); } } messageHL7.Segments.Add(seg); } } return(messageHL7); }
public void AddMessage(HL7DefMessage msg,MessageTypeHL7 messageType,EventTypeHL7 eventType,InOutHL7 inOrOut,int itemOrder) { AddMessage(msg,messageType,eventType,inOrOut,itemOrder,""); }
///<summary>Returns null if no HL7 def is enabled or no SRR is defined in the enabled def. An SRR - Schedule Request Response message is sent when an SRM - Schedule Request Message is received. The SRM is acknowledged just like any inbound message, but the SRR notifies the placer application that the requested modification took place. Currently the only appointment modifications allowed are updating the appt note, setting the dentist and hygienist, updating the confirmation status, and changing the ClinicNum. Setting the appointment status to Broken is also supported.</summary> public static MessageHL7 GenerateSRR(Patient pat,Appointment apt,EventTypeHL7 eventType,string controlId,bool isAck,string ackEvent) { HL7Def hl7Def=HL7Defs.GetOneDeepEnabled(); if(hl7Def==null) { return null; } //find an outbound SRR message in the def HL7DefMessage hl7DefMessage=null; for(int i=0;i<hl7Def.hl7DefMessages.Count;i++) { if(hl7Def.hl7DefMessages[i].MessageType==MessageTypeHL7.SRR && hl7Def.hl7DefMessages[i].InOrOut==InOutHL7.Outgoing) { hl7DefMessage=hl7Def.hl7DefMessages[i]; break; } } if(hl7DefMessage==null) {//SRR message type is not defined so do nothing and return return null; } if(PrefC.GetBool(PrefName.ShowFeaturePatientClone)) { Patient patClone; Patient patNonClone; List<Patient> listAmbiguousMatches; Patients.GetCloneAndNonClone(pat,out patClone,out patNonClone,out listAmbiguousMatches); if(patNonClone!=null) { pat=patNonClone; } } MessageHL7 msgHl7=new MessageHL7(MessageTypeHL7.SRR); Provider provPri=Providers.GetProv(apt.ProvNum); //go through each segment in the def for(int i=0;i<hl7DefMessage.hl7DefSegments.Count;i++) { List<Provider> listProvs=new List<Provider>(); listProvs.Add(provPri); if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.AIP && apt.ProvHyg>0) { listProvs.Add(Providers.GetProv(apt.ProvHyg)); } for(int j=0;j<listProvs.Count;j++) {//AIP will be repeated if there is a dentist and a hygienist on the appt Provider prov=listProvs[j]; SegmentHL7 seg=new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName); seg.SetField(0,hl7DefMessage.hl7DefSegments[i].SegmentName.ToString()); for(int k=0;k<hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count;k++) { string fieldName=hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FieldName; if(fieldName=="") {//If fixed text instead of field name just add text to segment seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos,hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FixedText); } else { string fieldValue=""; if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.MSA) { fieldValue=FieldConstructor.GenerateFieldACK(hl7Def,fieldName,controlId,isAck,ackEvent); } else { fieldValue=FieldConstructor.GenerateFieldSRR(hl7Def,fieldName,pat,prov,apt,j+1,eventType,seg.Name); } seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos,fieldValue); } } msgHl7.Segments.Add(seg); } } return msgHl7; }
///<summary>Sends null values in for objects not required. GenerateField will return an empty string if a field requires an object and that object is null.</summary> public static string GenerateFieldSRR(HL7Def def,string fieldName,Patient pat,Provider prov,Appointment apt,int sequenceNum,EventTypeHL7 eventType,SegmentNameHL7 segName) { return GenerateField(def,fieldName,MessageTypeHL7.SRR,pat,prov,null,null,apt,sequenceNum,eventType,null,null,MessageStructureHL7.SRR_S01,segName); }
public MessageHL7(string msgtext) { AckCode = ""; ControlId = ""; AckEvent = ""; originalMsgText = msgtext; Segments = new List <SegmentHL7>(); string[] rows = msgtext.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); //We need to get the separator characters in order to create the field objects. //The separators are part of the MSH segment and we force users to leave them in position 1 for incoming messages. Delimiters = new char[] { '^', '~', '\\', '&' }; //this is the default, but we will get them from the MSH segment of the incoming message in case they are using something unique. //if def is enabled, set delimiters to user defined values HL7Def enabledDef = HL7Defs.GetOneDeepEnabled(); if (enabledDef != null) { for (int i = 0; i < rows.Length; i++) { //we're going to assume that the user has not inserted an escaped '|' before the second field of the message and just split by '|'s without //checking for escaped '|'s. Technically '\|' would be a literal pipe and should not indicate a new field, but we only want to retrieve the //delimiters from MSH.1 and we require field 0 to be MSH and field 1 should be ^~\&. string[] fields = rows[i].Split(new string[] { "|" }, StringSplitOptions.None); if (fields.Length > 1 && fields[0] == "MSH" && fields[1].Length == 4) { //Encoding characters are in the following order: component separator, repetition separator, escape character, subcomponent separator Delimiters = fields[1].ToCharArray(); //we force users to leave the delimiters in position 1 of the MSH segment break; } } } SegmentHL7 segment; for (int i = 0; i < rows.Length; i++) { segment = new SegmentHL7(rows[i], Delimiters); //this creates the field objects. Segments.Add(segment); if (i == 0 && segment.Name == SegmentNameHL7.MSH) { //js 7/3/12 Make this more intelligent because we also now need the suffix string msgtype = segment.GetFieldComponent(8, 0); //We force the user to leave the 'messageType' field in this position, position 8 of the MSH segment string evnttype = segment.GetFieldComponent(8, 1); string msgStructure = segment.GetFieldComponent(8, 2); AckEvent = evnttype; //We will use this when constructing the acknowledgment to echo back to sender the same event type sent to us //If message type or event type are not in this list, they will default to the not supported type and will not be processed try { MsgType = (MessageTypeHL7)Enum.Parse(typeof(MessageTypeHL7), msgtype, true); } catch (Exception ex) { ex.DoNothing(); MsgType = MessageTypeHL7.NotDefined; } try { EventType = (EventTypeHL7)Enum.Parse(typeof(EventTypeHL7), evnttype, true); } catch (Exception ex) { ex.DoNothing(); EventType = EventTypeHL7.NotDefined; } try { MsgStructure = (MessageStructureHL7)Enum.Parse(typeof(MessageStructureHL7), msgStructure, true); } catch (Exception ex) { ex.DoNothing(); MsgStructure = MessageStructureHL7.NotDefined; } } } }
///<summary>apt, guar, proc, prov and pdfDataString can be null and will return an empty string if a field requires that object</summary> public static string GenerateDFT(HL7Def def, string fieldName, Patient pat, Provider prov, Procedure proc, Patient guar, Appointment apt, int sequenceNum, EventTypeHL7 eventType, string pdfDescription, string pdfDataString) { //big long list of fieldnames that we support switch (fieldName) { case "apt.AptNum": if (apt == null) { return(""); } else { return(apt.AptNum.ToString()); } case "dateTime.Now": return(gDTM(DateTime.Now, 14)); case "eventType": return(eventType.ToString()); case "guar.addressCityStateZip": if (guar == null) { return(""); } else { return(gConcat(def.ComponentSeparator, guar.Address, guar.Address2, guar.City, guar.State, guar.Zip)); } case "guar.birthdateTime": if (guar == null) { return(""); } else { return(gDTM(guar.Birthdate, 8)); } case "guar.Gender": if (guar == null) { return(""); } else { return(gIS(guar)); } case "guar.HmPhone": if (guar == null) { return(""); } else { return(gXTN(guar.HmPhone, 10)); } case "guar.nameLFM": if (guar == null) { return(""); } else { return(gConcat(def.ComponentSeparator, guar.LName, guar.FName, guar.MiddleI)); } case "guar.PatNum": if (guar == null) { return(""); } else { return(guar.PatNum.ToString()); } case "guar.SSN": if (guar == null) { return(""); } else { return(guar.SSN); } case "guar.WkPhone": if (guar == null) { return(""); } else { return(gXTN(guar.WkPhone, 10)); } case "messageControlId": return(Guid.NewGuid().ToString("N")); case "messageType": return(gConcat(def.ComponentSeparator, "DFT", eventType.ToString())); case "pat.addressCityStateZip": return(gConcat(def.ComponentSeparator, pat.Address, pat.Address2, pat.City, pat.State, pat.Zip)); case "pat.birthdateTime": return(gDTM(pat.Birthdate, 8)); case "pat.ChartNumber": return(pat.ChartNumber); case "pat.Gender": return(gIS(pat)); case "pat.HmPhone": return(gXTN(pat.HmPhone, 10)); case "pat.nameLFM": return(gConcat(def.ComponentSeparator, pat.LName, pat.FName, pat.MiddleI)); case "pat.PatNum": return(pat.PatNum.ToString()); case "pat.Position": return(gPos(pat)); case "pat.Race": return(gRace(pat)); case "pat.SSN": return(pat.SSN); case "pat.WkPhone": return(gXTN(pat.WkPhone, 10)); case "pdfDescription": return(pdfDescription); case "pdfDataAsBase64": if (pdfDataString == null) { return(""); } else { return(pdfDataString); } case "proc.DiagnosticCode": if (proc == null) { return(""); } if (proc.DiagnosticCode == null) { return(""); } else { return(proc.DiagnosticCode); } case "proc.procDateTime": if (proc == null) { return(""); } else { return(gDTM(proc.ProcDate, 14)); } case "proc.ProcFee": if (proc == null) { return(""); } else { return(proc.ProcFee.ToString("F2")); } case "proc.ProcNum": if (proc == null) { return(""); } else { return(proc.ProcNum.ToString()); } case "proc.toothSurfRange": if (proc == null) { return(""); } else { return(gTreatArea(def.ComponentSeparator, proc)); } case "proccode.ProcCode": if (proc == null) { return(""); } else { return(gProcCode(proc)); } case "prov.provIdNameLFM": if (prov == null) { return(""); } else { return(gConcat(def.ComponentSeparator, prov.EcwID, prov.LName, prov.FName, prov.MI)); } case "separators^~\\&": return(gSep(def)); case "sequenceNum": return(sequenceNum.ToString()); default: return(""); } }
///<summary>Returns null if no HL7 def is enabled or no SRR is defined in the enabled def. An SRR - Schedule Request Response message is sent when an SRM - Schedule Request Message is received. The SRM is acknowledged just like any inbound message, but the SRR notifies the placer application that the requested modification took place. Currently the only appointment modifications allowed are updating the appt note, setting the dentist and hygienist, updating the confirmation status, and changing the ClinicNum. Setting the appointment status to Broken is also supported.</summary> public static MessageHL7 GenerateSRR(Patient pat, Appointment apt, EventTypeHL7 eventType, string controlId, bool isAck, string ackEvent) { HL7Def hl7Def = HL7Defs.GetOneDeepEnabled(); if (hl7Def == null) { return(null); } //find an outbound SRR message in the def HL7DefMessage hl7DefMessage = null; for (int i = 0; i < hl7Def.hl7DefMessages.Count; i++) { if (hl7Def.hl7DefMessages[i].MessageType == MessageTypeHL7.SRR && hl7Def.hl7DefMessages[i].InOrOut == InOutHL7.Outgoing) { hl7DefMessage = hl7Def.hl7DefMessages[i]; break; } } if (hl7DefMessage == null) //SRR message type is not defined so do nothing and return { return(null); } if (PrefC.GetBool(PrefName.ShowFeaturePatientClone)) { pat = Patients.GetOriginalPatientForClone(pat); } MessageHL7 msgHl7 = new MessageHL7(MessageTypeHL7.SRR); Provider provPri = Providers.GetProv(apt.ProvNum); //go through each segment in the def for (int i = 0; i < hl7DefMessage.hl7DefSegments.Count; i++) { List <Provider> listProvs = new List <Provider>(); listProvs.Add(provPri); if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.AIP && apt.ProvHyg > 0) { listProvs.Add(Providers.GetProv(apt.ProvHyg)); } for (int j = 0; j < listProvs.Count; j++) //AIP will be repeated if there is a dentist and a hygienist on the appt { Provider prov = listProvs[j]; SegmentHL7 seg = new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName); seg.SetField(0, hl7DefMessage.hl7DefSegments[i].SegmentName.ToString()); for (int k = 0; k < hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count; k++) { string fieldName = hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FieldName; if (fieldName == "") //If fixed text instead of field name just add text to segment { seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos, hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FixedText); } else { string fieldValue = ""; if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.MSA) { fieldValue = FieldConstructor.GenerateFieldACK(hl7Def, fieldName, controlId, isAck, ackEvent); } else { fieldValue = FieldConstructor.GenerateFieldSRR(hl7Def, fieldName, pat, prov, apt, j + 1, eventType, seg.Name); } seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos, fieldValue); } } msgHl7.Segments.Add(seg); } } return(msgHl7); }
///<summary>Returns null if there is no HL7Def enabled or if there is no outbound DFT defined for the enabled HL7Def.</summary> public static MessageHL7 GenerateDFT(List <Procedure> listProcs, EventTypeHL7 eventType, Patient pat, Patient guar, long aptNum, string pdfDescription, string pdfDataString) { //In \\SERVERFILES\storage\OPEN DENTAL\Programmers Documents\Standards (X12, ADA, etc)\HL7\Version2.6\V26_CH02_Control_M4_JAN2007.doc //On page 28, there is a Message Construction Pseudocode as well as a flowchart which might help. MessageHL7 msgHl7 = new MessageHL7(MessageTypeHL7.DFT); HL7Def hl7Def = HL7Defs.GetOneDeepEnabled(); if (hl7Def == null) { return(null); } //find a DFT message in the def HL7DefMessage hl7DefMessage = null; for (int i = 0; i < hl7Def.hl7DefMessages.Count; i++) { if (hl7Def.hl7DefMessages[i].MessageType == MessageTypeHL7.DFT && hl7Def.hl7DefMessages[i].InOrOut == InOutHL7.Outgoing) { hl7DefMessage = hl7Def.hl7DefMessages[i]; //continue; break; } } if (hl7DefMessage == null) //DFT message type is not defined so do nothing and return { return(null); } if (PrefC.GetBool(PrefName.ShowFeaturePatientClone)) { pat = Patients.GetOriginalPatientForClone(pat); } Provider prov = Providers.GetProv(Patients.GetProvNum(pat)); Appointment apt = Appointments.GetOneApt(aptNum); List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum); for (int i = 0; i < hl7DefMessage.hl7DefSegments.Count; i++) { int repeatCount = 1; if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.FT1) { repeatCount = listProcs.Count; } else if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1) { repeatCount = listPatPlans.Count; } //for example, countRepeat can be zero in the case where we are only sending a PDF of the TP to eCW, and no procs. //or the patient does not have any current insplans for IN1 segments for (int j = 0; j < repeatCount; j++) //FT1 is optional and can repeat so add as many FT1's as procs in procList, IN1 is optional and can repeat as well, repeat for the number of patplans in patplanList { if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.FT1 && listProcs.Count > j) { prov = Providers.GetProv(listProcs[j].ProvNum); } Procedure proc = null; if (listProcs.Count > j) //procList could be an empty list { proc = listProcs[j]; } PatPlan patPlanCur = null; InsPlan insPlanCur = null; InsSub insSubCur = null; Carrier carrierCur = null; Patient subscriber = null; if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1) { patPlanCur = listPatPlans[j]; insSubCur = InsSubs.GetOne(patPlanCur.InsSubNum); insPlanCur = InsPlans.RefreshOne(insSubCur.PlanNum); carrierCur = Carriers.GetCarrier(insPlanCur.CarrierNum); subscriber = Patients.GetPat(insSubCur.Subscriber); } SegmentHL7 seg = new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName); seg.SetField(0, hl7DefMessage.hl7DefSegments[i].SegmentName.ToString()); for (int f = 0; f < hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count; f++) { string fieldName = hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].FieldName; if (fieldName == "") //If fixed text instead of field name just add text to segment { seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].OrdinalPos, hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].FixedText); } else { string fieldValue = ""; if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1) { fieldValue = FieldConstructor.GenerateFieldIN1(hl7Def, fieldName, j + 1, patPlanCur, insSubCur, insPlanCur, carrierCur, listPatPlans.Count, subscriber); } else { fieldValue = FieldConstructor.GenerateField(hl7Def, fieldName, MessageTypeHL7.DFT, pat, prov, proc, guar, apt, j + 1, eventType, pdfDescription, pdfDataString, MessageStructureHL7.DFT_P03, seg.Name); } seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].OrdinalPos, fieldValue); } } msgHl7.Segments.Add(seg); } } return(msgHl7); }
///<summary>Sends null values in for objects not required. GenerateField will return an empty string if a field requires an object and that object is null.</summary> public static string GenerateFieldADT(HL7Def def,string fieldName,Patient pat,Provider prov,Patient guar,int sequenceNum,EventTypeHL7 eventType,SegmentNameHL7 segName) { return GenerateField(def,fieldName,MessageTypeHL7.ADT,pat,prov,null,guar,null,sequenceNum,eventType,null,null,MessageStructureHL7.ADT_A01,segName); }
///<summary>Returns null if there is no HL7Def enabled or if there is no outbound DFT defined for the enabled HL7Def.</summary> public static MessageHL7 GenerateDFT(List<Procedure> listProcs,EventTypeHL7 eventType,Patient pat,Patient guar,long aptNum,string pdfDescription,string pdfDataString) { //In \\SERVERFILES\storage\OPEN DENTAL\Programmers Documents\Standards (X12, ADA, etc)\HL7\Version2.6\V26_CH02_Control_M4_JAN2007.doc //On page 28, there is a Message Construction Pseudocode as well as a flowchart which might help. MessageHL7 msgHl7=new MessageHL7(MessageTypeHL7.DFT); HL7Def hl7Def=HL7Defs.GetOneDeepEnabled(); if(hl7Def==null) { return null; } //find a DFT message in the def HL7DefMessage hl7DefMessage=null; for(int i=0;i<hl7Def.hl7DefMessages.Count;i++) { if(hl7Def.hl7DefMessages[i].MessageType==MessageTypeHL7.DFT && hl7Def.hl7DefMessages[i].InOrOut==InOutHL7.Outgoing) { hl7DefMessage=hl7Def.hl7DefMessages[i]; //continue; break; } } if(hl7DefMessage==null) {//DFT message type is not defined so do nothing and return return null; } if(PrefC.GetBool(PrefName.ShowFeaturePatientClone)) { Patient patClone; Patient patNonClone; List<Patient> listAmbiguousMatches; Patients.GetCloneAndNonClone(pat,out patClone,out patNonClone,out listAmbiguousMatches); if(patNonClone!=null) { pat=patNonClone; } } Provider prov=Providers.GetProv(Patients.GetProvNum(pat)); Appointment apt=Appointments.GetOneApt(aptNum); List<PatPlan> listPatPlans=PatPlans.Refresh(pat.PatNum); for(int i=0;i<hl7DefMessage.hl7DefSegments.Count;i++) { int repeatCount=1; if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.FT1) { repeatCount=listProcs.Count; } else if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.IN1) { repeatCount=listPatPlans.Count; } //for example, countRepeat can be zero in the case where we are only sending a PDF of the TP to eCW, and no procs. //or the patient does not have any current insplans for IN1 segments for(int j=0;j<repeatCount;j++) {//FT1 is optional and can repeat so add as many FT1's as procs in procList, IN1 is optional and can repeat as well, repeat for the number of patplans in patplanList if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.FT1 && listProcs.Count>j) { prov=Providers.GetProv(listProcs[j].ProvNum); } Procedure proc=null; if(listProcs.Count>j) {//procList could be an empty list proc=listProcs[j]; } PatPlan patPlanCur=null; InsPlan insPlanCur=null; InsSub insSubCur=null; Carrier carrierCur=null; Patient subscriber=null; if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.IN1) { patPlanCur=listPatPlans[j]; insSubCur=InsSubs.GetOne(patPlanCur.InsSubNum); insPlanCur=InsPlans.RefreshOne(insSubCur.PlanNum); carrierCur=Carriers.GetCarrier(insPlanCur.CarrierNum); subscriber=Patients.GetPat(insSubCur.Subscriber); } SegmentHL7 seg=new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName); seg.SetField(0,hl7DefMessage.hl7DefSegments[i].SegmentName.ToString()); for(int f=0;f<hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count;f++) { string fieldName=hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].FieldName; if(fieldName=="") {//If fixed text instead of field name just add text to segment seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].OrdinalPos,hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].FixedText); } else { string fieldValue=""; if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.IN1) { fieldValue=FieldConstructor.GenerateFieldIN1(hl7Def,fieldName,j+1,patPlanCur,insSubCur,insPlanCur,carrierCur,listPatPlans.Count,subscriber); } else { fieldValue=FieldConstructor.GenerateField(hl7Def,fieldName,MessageTypeHL7.DFT,pat,prov,proc,guar,apt,j+1,eventType, pdfDescription,pdfDataString,MessageStructureHL7.DFT_P03,seg.Name); } seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].OrdinalPos,fieldValue); } } msgHl7.Segments.Add(seg); } } return msgHl7; }
///<summary>apt, guar, proc, prov, pdfDescription, pdfDataString, patplanCur, inssubCur, insplanCur, carrierCur, and patSub can be null and will return an empty string if a field requires that object</summary> public static string GenerateField(HL7Def def,string fieldName,MessageTypeHL7 msgType,Patient pat,Provider prov,Procedure proc,Patient guar,Appointment apt,int sequenceNum,EventTypeHL7 eventType,string pdfDescription,string pdfDataString,MessageStructureHL7 msgStructure,SegmentNameHL7 segName) { string retval=""; if(def.InternalType==HL7InternalType.eCWFull || def.InternalType==HL7InternalType.eCWTight || def.InternalType==HL7InternalType.eCWStandalone) { _isEcwDef=true; } //big long list of fieldnames that we support switch(fieldName) { #region Appointment case "apt.AptDateTime": if(apt==null) { return ""; } return gDTM(apt.AptDateTime,14); case "apt.AptNum": if(apt==null) { return ""; } if(_isEcwDef) { return apt.AptNum.ToString(); } //We will use AptNum, with the OIDRoot for an appt object (set in oidinternal), and ID Type 'HL7' OIDInternal aptOid=OIDInternals.GetForType(IdentifierType.Appointment); string aptOidRoot=""; if(aptOid!=null) { aptOidRoot=aptOid.IDRoot; } //For PV1 segments, the data type is a CX, which has the AptNum, check digit, check digit scheme, assigning authority - &universalID&universalIDType, IDType //We will use the check digit scheme M11, their appt OID with "HL7" as the type for assigning authority, and the ID type is VN - Visit Number //Example: |1234^3^M11^&2.16.840.1.113883.3.4337.1486.6566.6&HL7^VN| if(segName==SegmentNameHL7.PV1) { string strCheckDigit=MessageParser.M11CheckDigit(apt.AptNum.ToString()).ToString(); string strCheckDigitScheme="M11"; if(strCheckDigit=="-1") { strCheckDigit=""; strCheckDigitScheme=""; } return gConcat(def.ComponentSeparator,apt.AptNum.ToString(),strCheckDigit,strCheckDigitScheme,gConcat(def.SubcomponentSeparator,"",aptOidRoot,"HL7"),"VN"); } //For segments other than PV1 (currently SCH or ARQ segments) the data type is EI //Example: |1234^^2.16.840.1.113883.3.4337.1486.6566.6^HL7| return gConcat(def.ComponentSeparator,apt.AptNum.ToString(),"",aptOidRoot,"HL7"); case "apt.aptStatus": if(apt==null) { return ""; } if(apt.AptStatus==ApptStatus.Complete) { return "Complete"; } if(apt.AptStatus==ApptStatus.UnschedList || apt.AptStatus==ApptStatus.Broken) { return "Cancelled"; } if(eventType==EventTypeHL7.S17) {//S17 is event type for outbound SIU messages when we delete an appointment return "Deleted"; } //apt.AptStatus==ApptStatus.Scheduled or apt.AptStatus==ApptStatus.ASAP or other status that triggers an SCH segment return "Booked"; case "apt.confirmStatus": if(apt==null) { return ""; } //Example: |^Appointment Confirmed| return gConcat(def.ComponentSeparator,"",DefC.GetName(DefCat.ApptConfirmed,apt.Confirmed));//this will return an empty string if apt.Confirmed is 0 or invalid case "apt.endAptDateTime": if(apt==null) { return ""; } return gDTM(apt.AptDateTime.AddMinutes(5*apt.Pattern.Length),14); case "apt.externalAptID": //EntityID^NamespaceID^UniversalID^UniversalIDType //Example: |12345^^OtherSoftware.Root^| if(apt==null) { return ""; } List<OIDExternal> listAptOidsExt=OIDExternals.GetByInternalIDAndType(apt.AptNum,IdentifierType.Appointment); if(listAptOidsExt.Count==0) { return ""; } return gConcat(def.ComponentSeparator,listAptOidsExt[0].IDExternal,"",listAptOidsExt[0].rootExternal,""); case "apt.location": //Point of Care^Room^^Facility^^Person Location Type //Example: ClinicDescript^OpName^^&PracticeTitle^^C (C for clinic) //use operatory and clinic from appt if(apt==null) { return ""; } string aptClinicDescript=Clinics.GetDesc(apt.ClinicNum); Operatory opCur=Operatories.GetOperatory(apt.Op); string opName=""; if(opCur!=null) { opName=opCur.OpName; } string practiceName=PrefC.GetString(PrefName.PracticeTitle); return gConcat(def.ComponentSeparator,aptClinicDescript,opName,"",def.SubcomponentSeparator+practiceName,"","C");//all of these could be empty strings and it works fine case "apt.length": //Example: 60^min&&ANS+, ANS+ is the name of the coding system if(apt==null) { return ""; } return gConcat(def.ComponentSeparator,(5*apt.Pattern.Length).ToString(),gConcat(def.SubcomponentSeparator,"min","","ANS+")); case "apt.Note": //As in the address note field (see PID.11) we will send '\.br\' (where the '\' is the defined escape char, \ by default) to signal a new line. if(apt==null) { return ""; } return gNewLines(def.EscapeCharacter,apt.Note); case "apt.operatory": if(apt==null) { return ""; } opCur=Operatories.GetOperatory(apt.Op); if(opCur==null) { return ""; } return opCur.OpName; case "apt.type": //Suggested values are Normal - Routine schedule request type, Tentative, or Complete - Request to add a completed appt //We will send Normal for all appointment statuses except complete. if(apt==null) { return ""; } if(apt.AptStatus==ApptStatus.Complete) { return "Complete"; } return "Normal"; case "apt.userOD": //The OD user who created/modified the appointment if(apt==null) { return ""; } //SRR messages are generated from the service in response to SRM messages, therefore we do not have a user logged in. if(msgType==MessageTypeHL7.SRR) { return "OpenDentalHL7"; } if(Security.CurUser!=null) { return Security.CurUser.UserName; } return ""; #endregion Appointment case "dateTime.Now": return gDTM(DateTime.Now,14); case "eventType": return eventType.ToString(); #region Guarantor case "guar.addressCityStateZip": if(guar==null) { return ""; } retval=gConcat(def.ComponentSeparator,guar.Address,guar.Address2,guar.City,guar.State,guar.Zip); if(!_isEcwDef) { //Example: 123 Main St^Apt 1^Dallas^OR^97338^^^^^^^^^^^^^^^Emergency Contact: Mom Test1\.br\Mother\.br\(503)623-3072 retval=gConcat(def.ComponentSeparator,retval,"","","","","","","","","","","","","","",gNewLines(def.EscapeCharacter,guar.AddrNote)); } return retval; case "guar.birthdateTime": if(guar==null) { return ""; } return gDTM(guar.Birthdate,8); case "guar.Gender": if(guar==null) { return ""; } return gIS(guar); case "guar.HmPhone": if(guar==null) { return ""; } string hmPh=gXTN(guar.HmPhone,10); string cPh=gXTN(guar.WirelessPhone,10); if(_isEcwDef) { return hmPh; } //PRN stands for Primary Residence Number, equipment type: PH is Telephone, CP is Cell Phone, Internet is Internet Address (email) //Example: ^PRN^PH^^^503^3635432~^PRN^Internet^[email protected]~^PRN^CP^^^503^6895555 if(hmPh!="") { retval=gConcat(def.ComponentSeparator,"","PRN","PH","","",hmPh.Substring(0,3),hmPh.Substring(3));//hmPh guaranteed to be 10 digits if not blank } if(cPh!="") { if(retval!="") { retval+=def.RepetitionSeparator; } retval+=gConcat(def.ComponentSeparator,"","PRN","CP","","",cPh.Substring(0,3),cPh.Substring(3));//cPh guaranteed to be 10 digits if not blank } if(guar.Email!="") { if(retval!="") { retval+=def.RepetitionSeparator; } retval+=gConcat(def.ComponentSeparator,"","PRN","Internet",guar.Email); } return retval; case "guar.nameLFM": if(guar==null) { return ""; } return gConcat(def.ComponentSeparator,guar.LName,guar.FName,guar.MiddleI); case "guar.PatNum": if(guar==null) { return ""; } return guar.PatNum.ToString(); case "guar.SSN": if(guar==null) { return ""; } return guar.SSN; case "guar.WkPhone": if(guar==null) { return ""; } string wkPh=gXTN(guar.WkPhone,10); if(_isEcwDef) { return wkPh; } //WPN stands for Work Number, equipment type: PH is Telephone //Example: ^WPN^PH^^^503^3635432 if(wkPh=="") { return ""; } return gConcat(def.ComponentSeparator,"","WPN","PH","","",wkPh.Substring(0,3),wkPh.Substring(3));//wkPh guaranteed to be 10 digits if not blank case "guarIdList": if(guar==null) { return ""; } //Example: |1234^3^M11^&2.16.840.1.113883.3.4337.1486.6566.2&HL7^PI~7684^8^M11^&Other.Software.OID&^PI| OIDInternal guarOid=OIDInternals.GetForType(IdentifierType.Patient); string guarOidRoot=""; if(guarOid!=null) { guarOidRoot=guarOid.IDRoot; } string guarIdCheckDigitStr=MessageParser.M11CheckDigit(guar.PatNum.ToString()).ToString(); retval=gConcat(def.ComponentSeparator,guar.PatNum.ToString(),guarIdCheckDigitStr,"M11",def.SubcomponentSeparator+guarOidRoot+def.SubcomponentSeparator+"HL7","PI"); List<OIDExternal> listGuarOidsExt=OIDExternals.GetByInternalIDAndType(guar.PatNum,IdentifierType.Patient); for(int i=0;i<listGuarOidsExt.Count;i++) { guarIdCheckDigitStr=MessageParser.M11CheckDigit(listGuarOidsExt[i].IDExternal).ToString(); if(guarIdCheckDigitStr=="-1") {//could not get a check digit from the external ID, could contain characters that are not numbers retval+=def.RepetitionSeparator+gConcat(def.ComponentSeparator,listGuarOidsExt[i].IDExternal,"","", def.SubcomponentSeparator+listGuarOidsExt[i].rootExternal+def.SubcomponentSeparator,"PI"); continue; } retval+=def.RepetitionSeparator+gConcat(def.ComponentSeparator,listGuarOidsExt[i].IDExternal,guarIdCheckDigitStr,"M11", def.SubcomponentSeparator+listGuarOidsExt[i].rootExternal+def.SubcomponentSeparator,"PI"); } return retval; #endregion Guarantor case "messageControlId": return Guid.NewGuid().ToString("N"); case "messageType": return gConcat(def.ComponentSeparator,msgType.ToString(),eventType.ToString(),msgStructure.ToString()); #region Patient case "pat.addressCityStateZip": retval=gConcat(def.ComponentSeparator,pat.Address,pat.Address2,pat.City,pat.State,pat.Zip); if(!_isEcwDef) { //Example: 123 Main St^Apt 1^Dallas^OR^97338^^^^^^^^^^^^^^^Emergency Contact: Mom Test1\.br\Mother\.br\(503)623-3072 retval=gConcat(def.ComponentSeparator,retval,"","","","","","","","","","","","","","",gNewLines(def.EscapeCharacter,pat.AddrNote)); } return retval; case "pat.birthdateTime": return gDTM(pat.Birthdate,8); case "pat.ChartNumber": return pat.ChartNumber; case "pat.Gender": return gIS(pat); case "pat.HmPhone": hmPh=gXTN(pat.HmPhone,10); cPh=gXTN(pat.WirelessPhone,10); if(_isEcwDef) { return hmPh; } //PRN stands for Primary Residence Number, equipment type: PH is Telephone, CP is Cell Phone, Internet is Internet Address (email) //Example: ^PRN^PH^^^503^3635432~^PRN^Internet^[email protected]~^PRN^CP^^^503^6895555 if(hmPh!="") { retval=gConcat(def.ComponentSeparator,"","PRN","PH","","",hmPh.Substring(0,3),hmPh.Substring(3));//hmPh guaranteed to be 10 digits if not blank } if(cPh!="") { if(retval!="") { retval+=def.RepetitionSeparator; } retval+=gConcat(def.ComponentSeparator,"","PRN","CP","","",cPh.Substring(0,3),cPh.Substring(3));//cPh guaranteed to be 10 digits if not blank } if(pat.Email!="") { if(retval!="") { retval+=def.RepetitionSeparator; } retval+=gConcat(def.ComponentSeparator,"","PRN","Internet",pat.Email); } return retval; case "pat.location": //Point of Care^Room^^Facility^^Person Location Type //Example: ClinicDescript^OpName^^&PracticeTitle^^C (C for clinic) if(pat.ClinicNum==0) { return ""; } string patClinicDescript=Clinics.GetDesc(pat.ClinicNum); practiceName=PrefC.GetString(PrefName.PracticeTitle); return gConcat(def.ComponentSeparator,patClinicDescript,"","",def.SubcomponentSeparator+practiceName,"","C"); case "pat.nameLFM": return gConcat(def.ComponentSeparator,pat.LName,pat.FName,pat.MiddleI); case "pat.PatNum": return pat.PatNum.ToString(); case "pat.Position": if(_isEcwDef) { return gPos(pat); } return gPos(pat).Substring(0,1);//S-Single, M-Married, D-Divorced, W-Widowed case "pat.Race": if(_isEcwDef) { return gRaceOld(pat); } return gRace(pat,def); case "pat.site": //Example: |West Salem Elementary^^^^^S| ('S' for site) if(pat.SiteNum==0) { return ""; } string patSiteDescript=Sites.GetDescription(pat.SiteNum); if(patSiteDescript=="") { return ""; } return gConcat(def.ComponentSeparator,patSiteDescript,"","","","","","S"); case "pat.SSN": return pat.SSN; case "pat.WkPhone": if(_isEcwDef) { return gXTN(pat.WkPhone,10); } //WPN stands for Work Number, equipment type: PH is Telephone //Example: ^WPN^PH^^^503^3635432 wkPh=gXTN(pat.WkPhone,10); if(wkPh=="") { return ""; } return gConcat(def.ComponentSeparator,"","WPN","PH","","",wkPh.Substring(0,3),wkPh.Substring(3));//wkPh guaranteed to be 10 digits if not blank case "pat.Urgency": //We will send one of the following values retrieved from the patient.Urgency field for treatment urgency: 0-Unknown, 1-NoProblems, 2-NeedsCare, 3-Urgent return ((int)pat.Urgency).ToString(); case "patientIds": //Example: |1234^3^M11^&2.16.840.1.113883.3.4337.1486.6566.2&HL7^PI~7684^8^M11^&Other.Software.OID&^PI| OIDInternal patOid=OIDInternals.GetForType(IdentifierType.Patient); string patOidRoot=""; if(patOid!=null) { patOidRoot=patOid.IDRoot; } string patIdCheckDigitStr=MessageParser.M11CheckDigit(pat.PatNum.ToString()).ToString(); retval=gConcat(def.ComponentSeparator,pat.PatNum.ToString(),patIdCheckDigitStr,"M11",def.SubcomponentSeparator+patOidRoot+def.SubcomponentSeparator+"HL7","PI"); List<OIDExternal> listPatOidsExt=OIDExternals.GetByInternalIDAndType(pat.PatNum,IdentifierType.Patient); for(int i=0;i<listPatOidsExt.Count;i++) { patIdCheckDigitStr=MessageParser.M11CheckDigit(listPatOidsExt[i].IDExternal).ToString(); if(patIdCheckDigitStr=="-1") {//could not get a check digit from the external ID, could contain characters that are not numbers retval+=def.RepetitionSeparator+gConcat(def.ComponentSeparator,listPatOidsExt[i].IDExternal,"","", def.SubcomponentSeparator+listPatOidsExt[i].rootExternal+def.SubcomponentSeparator,"PI"); continue; } retval+=def.RepetitionSeparator+gConcat(def.ComponentSeparator,listPatOidsExt[i].IDExternal,patIdCheckDigitStr,"M11", def.SubcomponentSeparator+listPatOidsExt[i].rootExternal+def.SubcomponentSeparator,"PI"); } return retval; #endregion Patient case "pdfDescription": if(pdfDescription==null) { return ""; } return pdfDescription; case "pdfDataAsBase64": if(pdfDataString==null) { return ""; } else { return pdfDataString; } #region Procedure case "proc.DiagnosticCode": if(proc==null) { return ""; } List<string> listDiagCodes=new List<string>(); if(proc.DiagnosticCode!=null && proc.DiagnosticCode!="") { listDiagCodes.Add(proc.DiagnosticCode); } if(proc.DiagnosticCode2!=null && proc.DiagnosticCode2!="") { listDiagCodes.Add(proc.DiagnosticCode2); } if(proc.DiagnosticCode3!=null && proc.DiagnosticCode3!="") { listDiagCodes.Add(proc.DiagnosticCode3); } if(proc.DiagnosticCode4!=null && proc.DiagnosticCode4!="") { listDiagCodes.Add(proc.DiagnosticCode4); } for(int i=0;i<listDiagCodes.Count;i++) { if(retval!="") { retval+=def.RepetitionSeparator; } ICD9 icd9Cur=ICD9s.GetByCode(listDiagCodes[i]); if(icd9Cur==null) {//not a valid ICD9 code or not in the ICD9 table, just stick in the code they have in OD retval+=listDiagCodes[i]; continue; } retval+=gConcat(def.ComponentSeparator,listDiagCodes[i],icd9Cur.Description,"I9C","","","","31"); } return retval; case "proc.location": //Point of Care^Room^^Facility^^Person Location Type //Example: ClinicDescript^OpName^^&PracticeTitle^^C (C for clinic) if(proc==null || (proc.ClinicNum==0 && pat.ClinicNum==0)) {//if proc is null and both pat.ClinicNum and proc.ClinicNum are 0, return empty string return ""; } string procClinicDescript=Clinics.GetDesc(proc.ClinicNum);//could be blank if proc.ClinicNum is invalid if(procClinicDescript=="") { procClinicDescript=Clinics.GetDesc(pat.ClinicNum);//could be blank if pat.ClinicNum is invalid } string procOpName=""; if(apt!=null) { Operatory procOp=Operatories.GetOperatory(apt.Op); if(procOp!=null) { procOpName=procOp.OpName; } } practiceName=PrefC.GetString(PrefName.PracticeTitle); return gConcat(def.ComponentSeparator,procClinicDescript,procOpName,"",def.SubcomponentSeparator+practiceName,"","C"); case "proc.procDateTime": if(proc==null) { return ""; } return gDTM(proc.ProcDate,8); case "proc.ProcFee": if(proc==null) { return ""; } return proc.ProcFee.ToString("F2"); case "proc.ProcNum": if(proc==null) { return ""; } return proc.ProcNum.ToString(); case "proc.toothSurfRange": if(proc==null) { return ""; } if(_isEcwDef) { return gTreatArea(def.ComponentSeparator,proc,def.IsQuadAsToothNum); } else { return gTreatArea(def.SubcomponentSeparator,proc,def.IsQuadAsToothNum); } case "proccode.ProcCode": if(proc==null) { return ""; } if(_isEcwDef) { return gProcCodeOld(proc); } //ProcNum^Descript^CD2^^^^2014^^LaymanTerm //Example: D0150^comprehensive oral evaluation - new or established patient^CD2^^^^2014^^Comprehensive Exam return gProcCode(proc,def); #endregion Procedure #region Provider case "prov.provIdNameLFM": if(prov==null) { return ""; } if(_isEcwDef) { return gConcat(def.ComponentSeparator,prov.EcwID,prov.LName,prov.FName,prov.MI); } //Will return all provider IDs in the oidexternals table linked to this provider as repetitions //For an AIG, the provider name is one component in the form LName, FName MI and the fourth component is the provider abbreviation //For a PV1 or AIP, the provider name is separated into three components like LName^FName^MI and the sixth component is the provider abbreviation //AIG Example: |2.16.840.1.113883.3.4337.1486.6566.3.1^Abbott, Sarah L, DMD^^DrAbbott~OtherSoftware.Root.Provider.ProvID^Abbott, Sarah L, DMD^^DrAbbott| //PV1 or AIP Example: 2.16.840.1.113883.3.4337.1486.6566.3.1^Abbott^Sarah^L^DMD^DrAbbott~OtherSoftware.Root.Provider.ProvID^Abbott^Sarah^L^DMD^DrAbbott List<OIDExternal> listProvOidExt=OIDExternals.GetByInternalIDAndType(prov.ProvNum,IdentifierType.Provider); string provName=""; if(segName==SegmentNameHL7.AIG) { provName=prov.LName+", "+prov.FName+" "+prov.MI+", "+prov.Suffix; } else { provName=gConcat(def.ComponentSeparator,prov.LName,prov.FName,prov.MI,prov.Suffix); } retval=gConcat(def.ComponentSeparator,OIDInternals.GetForType(IdentifierType.Provider).IDRoot+"."+prov.ProvNum,provName,prov.Abbr); for(int i=0;i<listProvOidExt.Count;i++) { retval+=def.RepetitionSeparator+gConcat(def.ComponentSeparator,listProvOidExt[i].rootExternal+"."+listProvOidExt[i].IDExternal,provName,prov.Abbr); } return retval; case "prov.provType": if(prov==null) { return ""; } if(apt==null) { if(prov.IsSecondary) { return "H"; } return "D"; } //if we have an appt, return 'D' if prov is the dentist and 'H' if prov is the hygienist, regardless of whether they are marked secondary or not if(prov.ProvNum==apt.ProvHyg) { return "H"; } return "D";//default to 'D' - dentist #endregion Provider case "segmentAction": //This is currently only supported for SIU and SRR messages in the RSG, AIL, and AIP segments //A-Add/Insert, D-Delete, U-Update, X-No Change //SIU.S12 - Create Appt, S13 - Appt Rescheduling, S14 - Appt Modification, S15 - Appt Cancellation, S17 - Appt Deletion //SRR.S03 - Request Appointment Modification, S04 - Request Appointment Cancellation if(msgType==MessageTypeHL7.SIU && eventType==EventTypeHL7.S12) { return "A"; } if(msgType==MessageTypeHL7.SRR //all SRR messages are for updating existing appts, 'U' || (msgType==MessageTypeHL7.SIU && (eventType==EventTypeHL7.S13 || eventType==EventTypeHL7.S14 || eventType==EventTypeHL7.S15))) //SIU's with event type S13, S14, or S15 are for updating existing appts { return "U"; } if(msgType==MessageTypeHL7.SIU && eventType==EventTypeHL7.S17) { return "D"; } return "";//if not an SIU or SRR or if it is not one of these event types, return empty string case "sendingApp": //HD data type, Namespace ID^UniversalID^UniversalIDType //UniversalID=oidinternal.IDRoot for IDType of Root, UniversalIDType=HL7 //If no value in oidinternal table, then revert to 'OD' OIDInternal oidRoot=OIDInternals.GetForType(IdentifierType.Root); if(oidRoot==null) { return "OD"; } return gConcat(def.ComponentSeparator,"",oidRoot.IDRoot,"HL7"); case "separators^~\\&": return gSep(def); case "sequenceNum": return sequenceNum.ToString(); default: return ""; } }
///<summary>Returns null if there is no HL7Def enabled or if there is no outbound SIU defined for the enabled HL7Def.</summary> public static MessageHL7 GenerateSIU(Patient pat,Patient guar,EventTypeHL7 eventType,Appointment apt) { HL7Def hl7Def=HL7Defs.GetOneDeepEnabled(); if(hl7Def==null) { return null; } //find an outbound SIU message in the def HL7DefMessage hl7DefMessage=null; for(int i=0;i<hl7Def.hl7DefMessages.Count;i++) { if(hl7Def.hl7DefMessages[i].MessageType==MessageTypeHL7.SIU && hl7Def.hl7DefMessages[i].InOrOut==InOutHL7.Outgoing) { hl7DefMessage=hl7Def.hl7DefMessages[i]; //continue; break; } } if(hl7DefMessage==null) {//SIU message type is not defined so do nothing and return return null; } if(apt==null) {//SIU messages must have an appointment return null; } if(PrefC.GetBool(PrefName.ShowFeaturePatientClone)) { Patient patClone; Patient patNonClone; List<Patient> listAmbiguousMatches; Patients.GetCloneAndNonClone(pat,out patClone,out patNonClone,out listAmbiguousMatches); if(patNonClone!=null) { pat=patNonClone; } } MessageHL7 messageHL7=new MessageHL7(MessageTypeHL7.SIU); Provider prov=Providers.GetProv(apt.ProvNum); for(int i=0;i<hl7DefMessage.hl7DefSegments.Count;i++) { int repeatCount=1; //AIP segment can repeat, once for the dentist on the appt and once for the hygienist if(hl7DefMessage.hl7DefSegments[i].SegmentName==SegmentNameHL7.AIP && apt.ProvHyg>0) { repeatCount=2; } for(int j=0;j<repeatCount;j++) {//AIP will be repeated if there is a dentist and a hygienist on the appt if(j>0) { prov=Providers.GetProv(apt.ProvHyg); if(prov==null) { break;//shouldn't happen, apt.ProvHyg would have to be set to an invalid ProvNum on the appt, just in case } } SegmentHL7 seg=new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName); seg.SetField(0,hl7DefMessage.hl7DefSegments[i].SegmentName.ToString()); for(int k=0;k<hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count;k++) { string fieldName=hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FieldName; if(fieldName=="") {//If fixed text instead of field name just add text to segment seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos,hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].FixedText); } else { string fieldValue=FieldConstructor.GenerateFieldSIU(hl7Def,fieldName,pat,prov,guar,apt,j+1,eventType,seg.Name); seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[k].OrdinalPos,fieldValue); } } messageHL7.Segments.Add(seg); } } return messageHL7; }