示例#1
0
 private void InitializeVariables(SegmentNameHL7 name, char[] delimiters)
 {
     _fullText   = "";
     Name        = name;
     _delimiters = delimiters;
     Fields      = new List <FieldHL7>();
     //remember that the "field quantity" is one more than the last index, because 0-based.
     //All fields are initially added with just one component
     //This can all probably be removed now since we add fields dynamically as needed:
     //if(name==SegmentNameHL7.MSA) {
     //	AddFields(3);
     //}
     //if(name==SegmentNameHL7.MSH) {
     //	AddFields(12);
     //}
     //if(name==SegmentNameHL7.EVN) {
     //	AddFields(4);
     //}
     //if(name==SegmentNameHL7.PID) {
     //	AddFields(23);
     //}
     //if(name==SegmentNameHL7.PV1) {
     //	AddFields(51);
     //}
     //if(name==SegmentNameHL7.FT1) {
     //	AddFields(27);
     //}
     //if(name==SegmentNameHL7.DG1) {
     //	AddFields(5);
     //}
     //if(name==SegmentNameHL7.ZX1) {
     //	AddFields(6);
     //}
 }
示例#2
0
文件: SegmentHL7.cs 项目: mnisl/OD
		private void InitializeVariables(SegmentNameHL7 name,char[] delimiters) {
			_fullText="";
			Name=name;
			_delimiters=delimiters;
			Fields=new List<FieldHL7>();
			//remember that the "field quantity" is one more than the last index, because 0-based.
			//All fields are initially added with just one component
			//This can all probably be removed now since we add fields dynamically as needed:
			//if(name==SegmentNameHL7.MSA) {
			//	AddFields(3);
			//}
			//if(name==SegmentNameHL7.MSH) {
			//	AddFields(12);
			//}
			//if(name==SegmentNameHL7.EVN) {
			//	AddFields(4);
			//}
			//if(name==SegmentNameHL7.PID) {
			//	AddFields(23);
			//}
			//if(name==SegmentNameHL7.PV1) {
			//	AddFields(51);
			//}
			//if(name==SegmentNameHL7.FT1) {
			//	AddFields(27);
			//}
			//if(name==SegmentNameHL7.DG1) {
			//	AddFields(5);
			//}
			//if(name==SegmentNameHL7.ZX1) {
			//	AddFields(6);
			//}
		}
示例#3
0
		///<summary>Only use this constructor when generating a message instead of parsing a message.</summary>
		internal SegmentHL7(SegmentNameHL7 name) {
			fullText="";
			Name=name;
			Fields=new List<FieldHL7>();
			//remember that the "field quantity" is one more than the last index, because 0-based.
			//All fields are initially added with just one component
			//This can all probably be removed now since we add fields dynamically as needed:
			if(name==SegmentNameHL7.MSA) {
				AddFields(3);
			}
			if(name==SegmentNameHL7.MSH) {
				AddFields(12);
			}
			if(name==SegmentNameHL7.EVN) {
				AddFields(4);
			}
			if(name==SegmentNameHL7.PID) {
				AddFields(23);
			}
			if(name==SegmentNameHL7.PV1) {
				AddFields(51);
			}
			if(name==SegmentNameHL7.FT1) {
				AddFields(27);
			}
			if(name==SegmentNameHL7.DG1) {
				AddFields(5);
			}
			if(name==SegmentNameHL7.ZX1) {
				AddFields(6);
			}
			
		}
示例#4
0
		public void AddSegment(HL7DefSegment seg,int itemOrder,bool canRepeat,bool isOptional,SegmentNameHL7 segmentName,string note) {
			if(hl7DefSegments==null) {
				hl7DefSegments=new List<HL7DefSegment>();
			}
			seg.ItemOrder=itemOrder;
			seg.CanRepeat=canRepeat;
			seg.IsOptional=isOptional;
			seg.SegmentName=segmentName;
			seg.Note=note;
			this.hl7DefSegments.Add(seg);
		}
示例#5
0
		///<summary>If an optional segment is not present, it will return null.</summary>
		public SegmentHL7 GetSegment(SegmentNameHL7 segmentName,bool isRequired) {
			for(int i=0;i<Segments.Count;i++) {
				if(Segments[i].Name==segmentName) {
					return Segments[i];
				}
			}
			if(isRequired) {
				throw new ApplicationException(segmentName+" segment is missing.");
			}
			return null;
		}
示例#6
0
 ///<summary>If an optional segment is not present, this will return null.  If a required segment is missing, this will throw an exception.
 ///This should only be used for non-repeatable segments, and only those that would be in a message 0 or 1 time.  If a segment can be in the
 ///message more than one time, like a NTE note segment, then this will return the first one found every time and there could be many others.
 ///Use GetSegments if the segment can repeat.</summary>
 public SegmentHL7 GetSegment(SegmentNameHL7 segmentName, bool isRequired)
 {
     for (int i = 0; i < Segments.Count; i++)
     {
         if (Segments[i].Name == segmentName)
         {
             return(Segments[i]);
         }
     }
     if (isRequired)
     {
         throw new ApplicationException(segmentName + " segment is missing.");
     }
     return(null);
 }
示例#7
0
        ///<summary>If an optional segment is not present, this will return an empty list.  If a required segment is missing, this will throw an exception.</summary>
        public List <SegmentHL7> GetSegments(SegmentNameHL7 segmentName, bool isRequired)
        {
            List <SegmentHL7> retVal = new List <SegmentHL7>();

            for (int i = 0; i < Segments.Count; i++)
            {
                if (Segments[i].Name != segmentName)
                {
                    continue;
                }
                retVal.Add(Segments[i]);
            }
            if (isRequired && retVal.Count == 0)
            {
                throw new ApplicationException(segmentName + " segment is missing.");
            }
            return(retVal);
        }
示例#8
0
 ///<summary>Only use this constructor when generating a message instead of parsing a message.</summary>
 internal SegmentHL7(SegmentNameHL7 name)
 {
     fullText = "";
     Name     = name;
     Fields   = new List <FieldHL7>();
     //remember that the "field quantity" is one more than the last index, because 0-based.
     //All fields are initially added with just one component
     //This can all probably be removed now since we add fields dynamically as needed:
     if (name == SegmentNameHL7.MSA)
     {
         AddFields(3);
     }
     if (name == SegmentNameHL7.MSH)
     {
         AddFields(12);
     }
     if (name == SegmentNameHL7.EVN)
     {
         AddFields(4);
     }
     if (name == SegmentNameHL7.PID)
     {
         AddFields(23);
     }
     if (name == SegmentNameHL7.PV1)
     {
         AddFields(51);
     }
     if (name == SegmentNameHL7.FT1)
     {
         AddFields(27);
     }
     if (name == SegmentNameHL7.DG1)
     {
         AddFields(5);
     }
     if (name == SegmentNameHL7.ZX1)
     {
         AddFields(6);
     }
 }
示例#9
0
		public void AddSegment(HL7DefSegment seg,int itemOrder,bool canRepeat,bool isOptional,SegmentNameHL7 segmentName) {
			AddSegment(seg,itemOrder,canRepeat,isOptional,segmentName,"");
		}
示例#10
0
		///<summary>listSegs will only contain more than one segment if the segment repeats.
		///prevSegName is only required when processing NTE segment(s) to determine which level NTE we are processing,
		///either a PID NTE, a OBR NTE, or a OBX NTE.</summary>
		public static void ProcessSeg(HL7DefMessage msgDef,List<SegmentHL7> listSegs,MessageHL7 msg,SegmentNameHL7 prevSegName=SegmentNameHL7.Unknown) {
			//if prevSegName=Unknown, segDefCur will be the first segDef with matching name
			HL7DefSegment segDefCur=GetSegDefByName(msgDef,listSegs[0].Name,prevSegName);
			switch(listSegs[0].Name) {
				case SegmentNameHL7.MSH://required segment
					if(segDefCur==null) {
						throw new Exception("Could not process the MedLab HL7 message.  "
							+"The message definition for this type of message did not contain a MSH segment definition.");
					}
					ProcessMSH(segDefCur,listSegs[0],msg);//listSegs will only contain one segment, the MSH segment
					return;
				case SegmentNameHL7.NK1://optional segment
					//NK1 is currently not processed
					if(segDefCur==null) {//do not process the NK1 segment if it's not defined
						return;
					}
					ProcessNK1(segDefCur,listSegs);//Currently does nothing
					return;
				case SegmentNameHL7.NTE://optional segment
					if(segDefCur==null) {//do not process the NTE segment if it's not defined
						return;
					}
					ProcessNTE(segDefCur,listSegs,msg);
					return;
				case SegmentNameHL7.OBR://required segment
					if(segDefCur==null) {
						throw new Exception("Could not process the MedLab HL7 message.  "
							+"The message definition for this type of message did not contain a OBR segment definition.");
					}
					ProcessOBR(segDefCur,listSegs[0],msg);
					return;
				case SegmentNameHL7.OBX://required segment
					if(segDefCur==null) {
						throw new Exception("Could not process the MedLab HL7 message.  "
							+"The message definition for this type of message did not contain a OBX segment definition.");
					}
					//instantiates a new MedLabResult object and sets the MedLabNum FK to the _medLabCur.MedLabNum
					ProcessOBX(segDefCur,listSegs[0]);//listSegs will only contain one OBX segment, not repeatable and not optional
					return;
				case SegmentNameHL7.ORC://required segment
					if(segDefCur==null) {
						throw new Exception("Could not process the MedLab HL7 message.  "
							+"The message definition for this type of message did not contain a ORC segment definition.");
					}
					ProcessORC(segDefCur,listSegs[0]);
					return;
				case SegmentNameHL7.PID://required segment
					if(segDefCur==null) {
						throw new Exception("Could not process the MedLab HL7 message.  "
							+"The message definition for this type of message did not contain a PID segment definition.");
					}
					ProcessPID(segDefCur,listSegs[0]);//listSegs will only contain one segment, the PID segment
					return;
				case SegmentNameHL7.SPM://optional segment
					if(segDefCur==null) {//do not process the SPM segment if it's not defined
						return;
					}
					ProcessSPM(segDefCur,listSegs);
					return;
				case SegmentNameHL7.ZEF://optional segment
					if(segDefCur==null) {//do not process the ZEF segment if it's not defined
						return;
					}
					if(_patCur==null) {
						return;//cannot store the pdf without a patient, need a patient to create an entry in the document table
					}
					ProcessZEF(segDefCur,listSegs);
					return;
				case SegmentNameHL7.ZPS://required segment
					if(segDefCur==null) {
						throw new Exception("Could not process the MedLab HL7 message.  "
							+"The message definition for this type of message did not contain a ZPS segment definition.");
					}
					ProcessZPS(segDefCur,listSegs,msg);
					return;
				default:
					return;
			}
		}
示例#11
0
        public int SequenceNumIndex = 1;      //the index for the field of the sequence num for repeating segs, usually the 2nd field in the seg, but set in the def

        ///<summary>Only use this constructor when generating a message instead of parsing a message.  Uses the default message delimiters.</summary>
        internal SegmentHL7(SegmentNameHL7 name)
        {
            InitializeVariables(name, new char[] { '^', '~', '\\', '&' });        //default delimiters in this order:  component separator, repetition separator, escape character, subcomponent separator
        }
示例#12
0
 public void AddSegment(HL7DefSegment seg, int itemOrder, SegmentNameHL7 segmentName)
 {
     AddSegment(seg, itemOrder, false, false, segmentName, "");
 }
示例#13
0
 public void AddSegment(HL7DefSegment seg, int itemOrder, bool canRepeat, bool isOptional, SegmentNameHL7 segmentName)
 {
     AddSegment(seg, itemOrder, canRepeat, isOptional, segmentName, "");
 }
示例#14
0
 public void AddSegment(HL7DefSegment seg, int itemOrder, bool canRepeat, bool isOptional, SegmentNameHL7 segmentName, string note)
 {
     if (hl7DefSegments == null)
     {
         hl7DefSegments = new List <HL7DefSegment>();
     }
     seg.ItemOrder   = itemOrder;
     seg.CanRepeat   = canRepeat;
     seg.IsOptional  = isOptional;
     seg.SegmentName = segmentName;
     seg.Note        = note;
     this.hl7DefSegments.Add(seg);
 }
示例#15
0
 ///<summary>Only use this constructor when generating a message instead of parsing a message.  Uses the delimiters provided, retrieved from the enabled HL7 def if exists.</summary>
 internal SegmentHL7(SegmentNameHL7 name, char[] delimiters)
 {
     InitializeVariables(name, delimiters);
 }
示例#16
0
文件: SegmentHL7.cs 项目: mnisl/OD
		///<summary>Only use this constructor when generating a message instead of parsing a message.  Uses the delimiters provided, retrieved from the enabled HL7 def if exists.</summary>
		internal SegmentHL7(SegmentNameHL7 name,char[] delimiters) {
			InitializeVariables(name,delimiters);
		}
示例#17
0
		///<summary>Returns the segment definion based on the name supplied, and only if it follows the previous segment name supplied.  If prevSegName
		///is Unknown, we'll return the first match by segName only.  If a segment can appear in a message definition more than once and in multiple
		///locations, send in the preceding segment name.  For example, the NTE seg can follow the PID (or optional NK1), OBR, and OBX (or optional ZEF)
		///segments. Returns the definition that immediately follows the previous segment name given. If the segment def follows an optional
		///segment, the prevSegName could be any preceding segment up to and including the first preceding required segment. We'll decrement backward
		///through the segments looking for a predecessor with the prevSegName until we get to the first required (IsOptional=false) segment.</summary>
		public static HL7DefSegment GetSegDefByName(HL7DefMessage msgDef,SegmentNameHL7 segName,SegmentNameHL7 prevSegName) {
			HL7DefSegment segDef=null;
			for(int i=0;i<msgDef.hl7DefSegments.Count;i++) {//start with the second segment in the def since the first segment won't have a predecessor
				if(msgDef.hl7DefSegments[i].SegmentName!=segName) {
					continue;
				}
				//if prevSegName is Unkown, we don't care about the preceding segment so this segment must appear at most once in the message
				if(prevSegName==SegmentNameHL7.Unknown) {
					segDef=msgDef.hl7DefSegments[i];
					break;
				}
				//move backward in the list of segments looking for the nearest preceding, required segment
				for(int j=1;j<i+1;j++) {
					if(msgDef.hl7DefSegments[i-j].SegmentName==prevSegName) {
						segDef=msgDef.hl7DefSegments[i];
						break;
					}
					//if the nearest preceding, required (IsOptional=false) segment isn't prevSegName, this is not the repetition we're looking for, continue
					if(!msgDef.hl7DefSegments[i-j].IsOptional) {
						break;
					}
				}
				if(segDef!=null) {
					break;
				}
			}
			return segDef;
		}
示例#18
0
		///<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);
		}
示例#19
0
		public void AddSegment(HL7DefSegment seg,int itemOrder,SegmentNameHL7 segmentName) {
			AddSegment(seg,itemOrder,false,false,segmentName,"");
		}
示例#20
0
        ///<summary>This field could be a CWE data type or a XCN data type, depending on if it came from an AIG segment, an AIP segment, or a PV1 segment.  The AIG segment would have this as a CWE data type in the format ProvID^LName, FName^^Abbr.  For the AIP and PV1 segments, the data type is XCN and the format would be ProvID^LName^FName^^^Abbr.  The ProvID is used first.  This will contain the root OID and ProvNum extension.  If it has the OD root OID for a provider, the number is assumed to be the OD ProvNum and used to find the provider.  If the root OID is not the OD root, it is used for on oidexternal table lookup.  If the provider is not found from the ID in either the provider table or the oidexternals table, then an attempt is made to find the provider by name and abbreviation.  This will return 0 if the field or segName are null or if no provider can be found.  A new provider will not be inserted with the information provided if not found by ProvID or name and abbr.  This field is repeatable, so we will check all repetitions for valid provider ID's or name/abbr combinations.</summary>
        public static long ProvParse(FieldHL7 field, SegmentNameHL7 segName, bool isVerbose)
        {
            long provNum = 0;
            List <OIDExternal> listOidExt = new List <OIDExternal>();

            if (field == null)
            {
                return(0);
            }
            #region Attempt to Get Provider From ProvIDs
            //Example of an ID using the hierarchic designation would be 2.16.840.1.113883.3.4337.1486.6566.3.1
            //Where 2.16.840.1.113883.3.4337.1486.6566 is the office oidroot, the .3 is to identify this as a provider
            //2.16.840.1.113883.3.4337.1486.6566.3 would be the office's oidinternal entry for IDType=Provider
            //The .1 is "."+ProvNum, where the ProvNum in this example is 1 and is considered the extension
            //We will strip off the ProvNum and if it is connected to the office's oidinternal entry for a provider, we will use it as the OD ProvNum
            //If it is attached to a different hierarchic root, we will try to find it in the oidexternals table linked to an OD ProvNum
            string [] provIdHierarch = field.GetComponentVal(0).Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
            string    strProvId      = "";
            string    strProvIdRoot  = "";
            if (provIdHierarch.Length > 1)           //must have a root and an ID
            {
                strProvId     = provIdHierarch[provIdHierarch.Length - 1];
                strProvIdRoot = field.GetComponentVal(0).Substring(0, field.GetComponentVal(0).Length - strProvId.Length - 1);         //-1 for the last "."
            }
            if (strProvId != "" && strProvIdRoot != "")
            {
                if (strProvIdRoot == OIDInternals.GetForType(IdentifierType.Provider).IDRoot)               //The office's root OID for a provider object, ProvId should be the OD ProvNum
                {
                    try {
                        if (Providers.GetProv(PIn.Long(strProvId)) != null)
                        {
                            provNum = PIn.Long(strProvId);                          //if component is empty string, provNum will be 0
                        }
                    }
                    catch (Exception ex) {
                        ex.DoNothing();
                        //PIn.Long failed to convert the component to a long, provNum will remain 0 and we will attempt to get by name and abbr below
                    }
                }
                else                  //there was a ProvID and a ProvID root, but the root is not the office's root OID for a provider object, check the oidexternals table
                {
                    OIDExternal oidExtProv = OIDExternals.GetByRootAndExtension(strProvIdRoot, strProvId);
                    if (oidExtProv == null)                   //add to the list of oid's to add to the oidexternal table if we find a provider
                    {
                        OIDExternal oidExtCur = new OIDExternal();
                        oidExtCur.IDType       = IdentifierType.Provider;
                        oidExtCur.rootExternal = strProvIdRoot;
                        oidExtCur.IDExternal   = strProvId;
                        //oidExtCur.IDInteral may not have been found yet
                        listOidExt.Add(oidExtCur);
                    }
                    if (oidExtProv != null && oidExtProv.IDType == IdentifierType.Provider)
                    {
                        //possibly some other validation of name match?
                        provNum = oidExtProv.IDInternal;
                    }
                }
            }
            for (int i = 0; i < field.ListRepeatFields.Count; i++)       //could be repetitions of this field with other IDs
            {
                strProvId      = "";
                strProvIdRoot  = "";
                provIdHierarch = field.ListRepeatFields[i].GetComponentVal(0).Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
                if (provIdHierarch.Length < 2)               //must be a root and an ID
                {
                    continue;
                }
                strProvId     = provIdHierarch[provIdHierarch.Length - 1];
                strProvIdRoot = field.ListRepeatFields[i].GetComponentVal(0).Substring(0, field.ListRepeatFields[i].GetComponentVal(0).Length - strProvId.Length - 1);         //-1 for the last "."
                if (strProvId == "" || strProvIdRoot == "")
                {
                    continue;
                }
                if (provNum == 0 && strProvIdRoot == OIDInternals.GetForType(IdentifierType.Provider).IDRoot)             //The office's root OID for a provider object, ProvId should be the OD ProvNum
                {
                    try {
                        if (Providers.GetProv(PIn.Long(strProvId)) != null)
                        {
                            provNum = PIn.Long(strProvId);                          //if component is empty string, provNum will be 0
                        }
                    }
                    catch (Exception ex) {
                        ex.DoNothing();
                        //PIn.Long failed to convert the component to a long, provNum will remain 0 and we will attempt to get by name and abbr below
                    }
                }
                else if (strProvIdRoot != OIDInternals.GetForType(IdentifierType.Provider).IDRoot)               //there was a ProvID and a ProvID root, but the root is not the office's root OID for a provider object, check the oidexternals table
                {
                    OIDExternal oidExtProv = OIDExternals.GetByRootAndExtension(strProvIdRoot, strProvId);
                    if (oidExtProv == null)                   //add to the list of oid's to add to the oidexternal table if we find a provider
                    {
                        OIDExternal oidExtCur = new OIDExternal();
                        oidExtCur.IDType       = IdentifierType.Provider;
                        oidExtCur.rootExternal = strProvIdRoot;
                        oidExtCur.IDExternal   = strProvId;
                        //oidExtCur.IDInteral may not have been found yet
                        listOidExt.Add(oidExtCur);
                    }
                    else
                    {
                        if (provNum == 0 && oidExtProv.IDType == IdentifierType.Provider)
                        {
                            //possibly some other validation of name match?
                            provNum = oidExtProv.IDInternal;
                        }
                    }
                }
            }
            if (provNum > 0)
            {
                string verboseMsg = "";
                for (int i = 0; i < listOidExt.Count; i++)
                {
                    listOidExt[i].IDInternal = provNum;
                    OIDExternals.Insert(listOidExt[i]);
                    verboseMsg += "\r\nProvNum: " + provNum.ToString() + ", External root: " + strProvIdRoot + ", External Provider ID: " + strProvId;
                }
                if (isVerbose)
                {
                    EventLog.WriteEntry("OpenDentHL7", "Added an external provider ID to the oidexternals table due to an incoming "
                                        + segName.ToString() + " segment." + verboseMsg + ".", EventLogEntryType.Information);
                }
                return(provNum);
            }
            #endregion Attempt to Get Provider From ProvIDs
            #region Attempt to Get Provider From Name and Abbr
            //Couldn't find the provider with the ProvNum provided, we will attempt to find by FName, LName, and Abbr
            string provLName = "";
            string provFName = "";
            string provAbbr  = "";
            if (segName == SegmentNameHL7.AIG)           //AIG is the data type CWE with format ProvNum^LName, FName^^Abbr
            //GetComponentVal will return an empty string if the index is greater than the number of the components for this field minus 1
            {
                string[] components = field.GetComponentVal(1).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (components.Length > 0)
                {
                    provLName = components[0].TrimEnd(',');
                }
                if (components.Length > 1)
                {
                    provFName = components[1];
                }
                provAbbr = field.GetComponentVal(3);
            }
            else if (segName == SegmentNameHL7.AIP || segName == SegmentNameHL7.PV1)         //AIP and PV1 are the data type XCN with the format ProvNum^LName^FName^^^Abbr
            {
                provLName = field.GetComponentVal(1);
                provFName = field.GetComponentVal(2);
                provAbbr  = field.GetComponentVal(5);
            }
            if (provAbbr != "")
            {
                List <Provider> listProvs = Providers.GetProvsByFLName(provLName, provFName);
                for (int i = 0; i < listProvs.Count; i++)
                {
                    if (listProvs[i].Abbr.ToLower() == provAbbr.ToLower())
                    {
                        //There should be only one provider with this Abbr, although we only warn them about the duplication and allow them to have more than one with the same Abbr.
                        //With the LName, FName, and Abbr we can be more certain we retrieve the correct provider.
                        provNum = listProvs[i].ProvNum;
                    }
                }
            }
            //provider not found by provID, or first name/abbr combination, try the name/abbr combos in the repetitions.
            for (int i = 0; i < field.ListRepeatFields.Count; i++)       //could be repetitions of this field with other IDs
            {
                if (provNum > 0)
                {
                    break;
                }
                provLName = "";
                provFName = "";
                provAbbr  = "";
                if (segName == SegmentNameHL7.AIG)
                {
                    string[] components = field.ListRepeatFields[i].GetComponentVal(1).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (components.Length > 0)
                    {
                        provLName = components[0].TrimEnd(',');
                    }
                    if (components.Length > 1)
                    {
                        provFName = components[1];
                    }
                    provAbbr = field.ListRepeatFields[i].GetComponentVal(3);
                }
                else if (segName == SegmentNameHL7.AIP || segName == SegmentNameHL7.PV1)             //AIP and PV1 are the data type XCN with the format ProvNum^LName^FName^^^Abbr
                {
                    provLName = field.ListRepeatFields[i].GetComponentVal(1);
                    provFName = field.ListRepeatFields[i].GetComponentVal(2);
                    provAbbr  = field.ListRepeatFields[i].GetComponentVal(5);
                }
                if (provAbbr == "")
                {
                    continue;                    //there has to be a LName, FName, and Abbr if we are trying to match without a ProvNum.  LName and FName empty string check happens in GetProvsByFLName
                }
                List <Provider> listProvs = Providers.GetProvsByFLName(provLName, provFName);
                for (int p = 0; p < listProvs.Count; p++)
                {
                    if (listProvs[p].Abbr.ToLower() == provAbbr.ToLower())
                    {
                        //There should be only one provider with this Abbr, although we only warn them about the duplication and allow them to have more than one with the same Abbr.
                        //With the LName, FName, and Abbr we can be more certain we retrieve the correct provider.
                        provNum = listProvs[p].ProvNum;
                        break;
                    }
                }
            }
            if (provNum > 0)
            {
                string verboseMsg = "";
                for (int i = 0; i < listOidExt.Count; i++)
                {
                    listOidExt[i].IDInternal = provNum;
                    OIDExternals.Insert(listOidExt[i]);
                    verboseMsg += "\r\nProvNum: " + provNum.ToString() + ", External root: " + strProvIdRoot + ", External Provider ID: " + strProvId;
                }
                if (isVerbose)
                {
                    EventLog.WriteEntry("OpenDentHL7", "Added an external provider ID to the oidexternals table due to an incoming "
                                        + segName.ToString() + " segment." + verboseMsg + ".", EventLogEntryType.Information);
                }
            }
            #endregion Attempt to Get Provider From Name and Abbr
            return(provNum);
        }
示例#21
0
文件: FieldParser.cs 项目: mnisl/OD
		///<summary>This field could be a CWE data type or a XCN data type, depending on if it came from an AIG segment, an AIP segment, or a PV1 segment.  The AIG segment would have this as a CWE data type in the format ProvID^LName, FName^^Abbr.  For the AIP and PV1 segments, the data type is XCN and the format would be ProvID^LName^FName^^^Abbr.  The ProvID is used first.  This will contain the root OID and ProvNum extension.  If it has the OD root OID for a provider, the number is assumed to be the OD ProvNum and used to find the provider.  If the root OID is not the OD root, it is used for on oidexternal table lookup.  If the provider is not found from the ID in either the provider table or the oidexternals table, then an attempt is made to find the provider by name and abbreviation.  This will return 0 if the field or segName are null or if no provider can be found.  A new provider will not be inserted with the information provided if not found by ProvID or name and abbr.  This field is repeatable, so we will check all repetitions for valid provider ID's or name/abbr combinations.</summary>
		public static long ProvParse(FieldHL7 field,SegmentNameHL7 segName,bool isVerbose) {
			long provNum=0;
			List<OIDExternal> listOidExt=new List<OIDExternal>();
			if(field==null) {
				return 0;
			}
			#region Attempt to Get Provider From ProvIDs
			//Example of an ID using the hierarchic designation would be 2.16.840.1.113883.3.4337.1486.6566.3.1
			//Where 2.16.840.1.113883.3.4337.1486.6566 is the office oidroot, the .3 is to identify this as a provider
			//2.16.840.1.113883.3.4337.1486.6566.3 would be the office's oidinternal entry for IDType=Provider
			//The .1 is "."+ProvNum, where the ProvNum in this example is 1 and is considered the extension
			//We will strip off the ProvNum and if it is connected to the office's oidinternal entry for a provider, we will use it as the OD ProvNum
			//If it is attached to a different hierarchic root, we will try to find it in the oidexternals table linked to an OD ProvNum
			string [] provIdHierarch=field.GetComponentVal(0).Split(new string[] {"."},StringSplitOptions.RemoveEmptyEntries);
			string strProvId="";
			string strProvIdRoot="";
			if(provIdHierarch.Length>1) {//must have a root and an ID
				strProvId=provIdHierarch[provIdHierarch.Length-1];
				strProvIdRoot=field.GetComponentVal(0).Substring(0,field.GetComponentVal(0).Length-strProvId.Length-1);//-1 for the last "."
			}
			if(strProvId!="" && strProvIdRoot!="") {
				if(strProvIdRoot==OIDInternals.GetForType(IdentifierType.Provider).IDRoot) {//The office's root OID for a provider object, ProvId should be the OD ProvNum
					try {
						if(Providers.GetProv(PIn.Long(strProvId))!=null) {
							provNum=PIn.Long(strProvId);//if component is empty string, provNum will be 0
						}
					}
					catch(Exception ex) {
						//PIn.Long failed to convert the component to a long, provNum will remain 0 and we will attempt to get by name and abbr below
					}
				}
				else {//there was a ProvID and a ProvID root, but the root is not the office's root OID for a provider object, check the oidexternals table
					OIDExternal oidExtProv=OIDExternals.GetByRootAndExtension(strProvIdRoot,strProvId);
					if(oidExtProv==null) {//add to the list of oid's to add to the oidexternal table if we find a provider
						OIDExternal oidExtCur=new OIDExternal();
						oidExtCur.IDType=IdentifierType.Provider;
						oidExtCur.rootExternal=strProvIdRoot;
						oidExtCur.IDExternal=strProvId;
						//oidExtCur.IDInteral may not have been found yet
						listOidExt.Add(oidExtCur);
					}
					if(oidExtProv!=null && oidExtProv.IDType==IdentifierType.Provider) {
						//possibly some other validation of name match?
						provNum=oidExtProv.IDInternal;
					}
				}
			}
			for(int i=0;i<field.ListRepeatFields.Count;i++) {//could be repetitions of this field with other IDs
				strProvId="";
				strProvIdRoot="";
				provIdHierarch=field.ListRepeatFields[i].GetComponentVal(0).Split(new string[] { "." },StringSplitOptions.RemoveEmptyEntries);
				if(provIdHierarch.Length<2) {//must be a root and an ID
					continue;
				}
				strProvId=provIdHierarch[provIdHierarch.Length-1];
				strProvIdRoot=field.ListRepeatFields[i].GetComponentVal(0).Substring(0,field.ListRepeatFields[i].GetComponentVal(0).Length-strProvId.Length-1);//-1 for the last "."
				if(strProvId=="" || strProvIdRoot=="") {
					continue;
				}
				if(provNum==0 && strProvIdRoot==OIDInternals.GetForType(IdentifierType.Provider).IDRoot) {//The office's root OID for a provider object, ProvId should be the OD ProvNum
					try {
						if(Providers.GetProv(PIn.Long(strProvId))!=null) {
							provNum=PIn.Long(strProvId);//if component is empty string, provNum will be 0
						}
					}
					catch(Exception ex) {
						//PIn.Long failed to convert the component to a long, provNum will remain 0 and we will attempt to get by name and abbr below
					}
				}
				else if(strProvIdRoot!=OIDInternals.GetForType(IdentifierType.Provider).IDRoot) {//there was a ProvID and a ProvID root, but the root is not the office's root OID for a provider object, check the oidexternals table
					OIDExternal oidExtProv=OIDExternals.GetByRootAndExtension(strProvIdRoot,strProvId);
					if(oidExtProv==null) {//add to the list of oid's to add to the oidexternal table if we find a provider
						OIDExternal oidExtCur=new OIDExternal();
						oidExtCur.IDType=IdentifierType.Provider;
						oidExtCur.rootExternal=strProvIdRoot;
						oidExtCur.IDExternal=strProvId;
						//oidExtCur.IDInteral may not have been found yet
						listOidExt.Add(oidExtCur);
					}
					else {
						if(provNum==0 && oidExtProv.IDType==IdentifierType.Provider) {
							//possibly some other validation of name match?
							provNum=oidExtProv.IDInternal;
						}
					}
				}
			}
			if(provNum>0) {
				string verboseMsg="";
				for(int i=0;i<listOidExt.Count;i++) {
					listOidExt[i].IDInternal=provNum;
					OIDExternals.Insert(listOidExt[i]);
					verboseMsg+="\r\nProvNum: "+provNum.ToString()+", External root: "+strProvIdRoot+", External Provider ID: "+strProvId;
				}
				if(isVerbose) {
					EventLog.WriteEntry("OpenDentHL7","Added an external provider ID to the oidexternals table due to an incoming "
						+segName.ToString()+" segment."+verboseMsg+".",EventLogEntryType.Information);
				}
				return provNum;
			}
			#endregion Attempt to Get Provider From ProvIDs
			#region Attempt to Get Provider From Name and Abbr
			//Couldn't find the provider with the ProvNum provided, we will attempt to find by FName, LName, and Abbr
			string provLName="";
			string provFName="";
			string provAbbr="";
			if(segName==SegmentNameHL7.AIG) {//AIG is the data type CWE with format ProvNum^LName, FName^^Abbr
				//GetComponentVal will return an empty string if the index is greater than the number of the components for this field minus 1
				string[] components=field.GetComponentVal(1).Split(new char[] {' '},StringSplitOptions.RemoveEmptyEntries);
				if(components.Length>0) {
					provLName=components[0].TrimEnd(',');
				}
				if(components.Length>1) {
					provFName=components[1];
				}
				provAbbr=field.GetComponentVal(3);
			}
			else if(segName==SegmentNameHL7.AIP || segName==SegmentNameHL7.PV1) {//AIP and PV1 are the data type XCN with the format ProvNum^LName^FName^^^Abbr
				provLName=field.GetComponentVal(1);
				provFName=field.GetComponentVal(2);
				provAbbr=field.GetComponentVal(5);
			}
			if(provAbbr!="") {
				List<Provider> listProvs=Providers.GetProvsByFLName(provLName,provFName);
				for(int i=0;i<listProvs.Count;i++) {
					if(listProvs[i].Abbr.ToLower()==provAbbr.ToLower()) {
						//There should be only one provider with this Abbr, although we only warn them about the duplication and allow them to have more than one with the same Abbr.
						//With the LName, FName, and Abbr we can be more certain we retrieve the correct provider.
						provNum=listProvs[i].ProvNum;
					}
				}
			}
			//provider not found by provID, or first name/abbr combination, try the name/abbr combos in the repetitions.
			for(int i=0;i<field.ListRepeatFields.Count;i++) {//could be repetitions of this field with other IDs
				if(provNum>0) {
					break;
				}
				provLName="";
				provFName="";
				provAbbr="";
				if(segName==SegmentNameHL7.AIG) {
					string[] components=field.ListRepeatFields[i].GetComponentVal(1).Split(new char[] { ' ' },StringSplitOptions.RemoveEmptyEntries);
					if(components.Length>0) {
						provLName=components[0].TrimEnd(',');
					}
					if(components.Length>1) {
						provFName=components[1];
					}
					provAbbr=field.ListRepeatFields[i].GetComponentVal(3);
				}
				else if(segName==SegmentNameHL7.AIP || segName==SegmentNameHL7.PV1) {//AIP and PV1 are the data type XCN with the format ProvNum^LName^FName^^^Abbr
					provLName=field.ListRepeatFields[i].GetComponentVal(1);
					provFName=field.ListRepeatFields[i].GetComponentVal(2);
					provAbbr=field.ListRepeatFields[i].GetComponentVal(5);
				}
				if(provAbbr=="") {
					continue;//there has to be a LName, FName, and Abbr if we are trying to match without a ProvNum.  LName and FName empty string check happens in GetProvsByFLName
				}
				List<Provider> listProvs=Providers.GetProvsByFLName(provLName,provFName);
				for(int p=0;p<listProvs.Count;p++) {
					if(listProvs[p].Abbr.ToLower()==provAbbr.ToLower()) {
						//There should be only one provider with this Abbr, although we only warn them about the duplication and allow them to have more than one with the same Abbr.
						//With the LName, FName, and Abbr we can be more certain we retrieve the correct provider.
						provNum=listProvs[p].ProvNum;
						break;
					}
				}
			}
			if(provNum>0) {
				string verboseMsg="";
				for(int i=0;i<listOidExt.Count;i++) {
					listOidExt[i].IDInternal=provNum;
					OIDExternals.Insert(listOidExt[i]);
					verboseMsg+="\r\nProvNum: "+provNum.ToString()+", External root: "+strProvIdRoot+", External Provider ID: "+strProvId;
				}
				if(isVerbose) {
					EventLog.WriteEntry("OpenDentHL7","Added an external provider ID to the oidexternals table due to an incoming "
						+segName.ToString()+" segment."+verboseMsg+".",EventLogEntryType.Information);
				}
			}
			#endregion Attempt to Get Provider From Name and Abbr
			return provNum;
		}
示例#22
0
		///<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);
		}
示例#23
0
文件: SegmentHL7.cs 项目: mnisl/OD
		public int SequenceNumIndex=1;//the index for the field of the sequence num for repeating segs, usually the 2nd field in the seg, but set in the def

		///<summary>Only use this constructor when generating a message instead of parsing a message.  Uses the default message delimiters.</summary>
		internal SegmentHL7(SegmentNameHL7 name) {
			InitializeVariables(name,new char[] { '^','~','\\','&' });//default delimiters in this order:  component separator, repetition separator, escape character, subcomponent separator
		}
示例#24
0
		///<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 "";
			}
		}
示例#25
0
文件: MessageHL7.cs 项目: mnisl/OD
		///<summary>If an optional segment is not present, this will return an empty list.  If a required segment is missing, this will throw an exception.</summary>
		public List<SegmentHL7> GetSegments(SegmentNameHL7 segmentName,bool isRequired) {
			List<SegmentHL7> retVal=new List<SegmentHL7>();
			for(int i=0;i<Segments.Count;i++) {
				if(Segments[i].Name!=segmentName) {
					continue;
				}
				retVal.Add(Segments[i]);
			}
			if(isRequired && retVal.Count==0) {
				throw new ApplicationException(segmentName+" segment is missing.");
			}
			return retVal;
		}