///<summary>Helper for GenerateCCD(). Exports Labs.</summary> private void GenerateCcdSectionResults(bool hasSectionResult) { _w.WriteComment(@" ===================================================================================================== Laboratory Test Results ====================================================================================================="); List<EhrLabResult> listLabResultFiltered; if(!hasSectionResult) { listLabResultFiltered=new List<EhrLabResult>(); } else { listLabResultFiltered=_listLabResultFiltered; } EhrLab labPanel; Start("component"); Start("section"); TemplateId("2.16.840.1.113883.10.20.22.2.3.1");//page 309 Results section with coded entries required. _w.WriteComment("Diagnostic Results section template"); StartAndEnd("code","code","30954-2","codeSystem",strCodeSystemLoinc,"codeSystemName",strCodeSystemNameLoinc,"displayName","Results"); _w.WriteElementString("title","Diagnostic Results"); Start("text");//The following text will be parsed as html with a style sheet to be human readable. if(listLabResultFiltered.Count>0 && hasSectionResult) { Start("table","width","100%","border","1"); Start("thead"); Start("tr"); _w.WriteElementString("th","LOINC Code"); _w.WriteElementString("th","Test"); _w.WriteElementString("th","Result"); _w.WriteElementString("th","Abnormal Flag"); _w.WriteElementString("th","Date Performed"); End("tr"); End("thead"); Start("tbody"); for(int i=0;i<listLabResultFiltered.Count;i++) { Loinc labLoinc=Loincs.GetByCode(listLabResultFiltered[i].ObservationIdentifierID); string value=""; switch(listLabResultFiltered[i].ValueType) { case EhrLaboratories.HL70125.CE: break; case EhrLaboratories.HL70125.CWE: break; case EhrLaboratories.HL70125.DT: break; case EhrLaboratories.HL70125.FT: break; case EhrLaboratories.HL70125.NM: value=listLabResultFiltered[i].ObservationValueNumeric.ToString(); break; case EhrLaboratories.HL70125.SN: break; case EhrLaboratories.HL70125.ST: break; case EhrLaboratories.HL70125.TM: break; case EhrLaboratories.HL70125.TS: break; case EhrLaboratories.HL70125.TX: break; } Start("tr"); _w.WriteElementString("td",listLabResultFiltered[i].ObservationIdentifierID);//LOINC Code if(labLoinc==null) { _w.WriteElementString("td",listLabResultFiltered[i].ObservationIdentifierText);//Test } else { _w.WriteElementString("td",labLoinc.NameShort);//Test } _w.WriteElementString("td",value+" "+listLabResultFiltered[i].UnitsID);//Result _w.WriteElementString("td",listLabResultFiltered[i].AbnormalFlags);//Abnormal Flag if(String.Compare(Regex.Match("input string",@"^\d{0,4}").Value.PadLeft(4,'0'),"1880")!=-1) { _w.WriteElementString("td","");//Test } else { _w.WriteElementString("td",listLabResultFiltered[i].ObservationDateTime); } End("tr"); } End("tbody"); End("table"); } else { _w.WriteString("None"); } End("text"); if(listLabResultFiltered.Count==0) {//If there are no entries in the filtered list, then we want to add a dummy entry since at least one is required. EhrLabResult labR=new EhrLabResult(); listLabResultFiltered.Add(labR); } for(int i=0;i<listLabResultFiltered.Count;i++) { if(listLabResultFiltered[i].EhrLabNum==0) { labPanel=new EhrLab(); } else { labPanel=EhrLabs.GetOne(listLabResultFiltered[i].EhrLabNum); } Loinc labLoinc=Loincs.GetByCode(listLabResultFiltered[i].ObservationIdentifierID); string value=""; switch(listLabResultFiltered[i].ValueType) { case EhrLaboratories.HL70125.CE: break; case EhrLaboratories.HL70125.CWE: break; case EhrLaboratories.HL70125.DT: break; case EhrLaboratories.HL70125.FT: break; case EhrLaboratories.HL70125.NM: value=listLabResultFiltered[i].ObservationValueNumeric.ToString(); break; case EhrLaboratories.HL70125.SN: break; case EhrLaboratories.HL70125.ST: break; case EhrLaboratories.HL70125.TM: break; case EhrLaboratories.HL70125.TS: break; case EhrLaboratories.HL70125.TX: break; } Start("entry","typeCode","DRIV"); Start("organizer","classCode","BATTERY","moodCode","EVN"); StartAndEnd("templateId","root","2.16.840.1.113883.10.20.22.4.1"); _w.WriteComment("Result organizer template"); Guid(); if(String.IsNullOrEmpty(labPanel.UsiID)) { StartAndEnd("code","nullFlavor","NA");//Null allowed for this code. } else { StartAndEnd("code","code",labPanel.UsiID,"codeSystem",strCodeSystemLoinc,"displayName",labPanel.UsiText);//Code systems allowed: LOINC, or other "local codes". } StartAndEnd("statusCode","code","completed");//page 532 Allowed values: aborted, active, cancelled, completed, held, suspended. Start("component"); Start("observation","classCode","OBS","moodCode","EVN"); TemplateId("2.16.840.1.113883.10.20.22.4.2"); _w.WriteComment("Result observation template"); Guid(); if(String.IsNullOrEmpty(listLabResultFiltered[i].ObservationIdentifierID)) { StartAndEnd("code","nullFlavor","UNK"); } else if(labLoinc==null) { StartAndEnd("code","code",listLabResultFiltered[i].ObservationIdentifierID,"displayName",listLabResultFiltered[i].ObservationIdentifierText,"codeSystem",strCodeSystemLoinc,"codeSystemName",strCodeSystemNameLoinc); } else { StartAndEnd("code","code",listLabResultFiltered[i].ObservationIdentifierID,"displayName",labLoinc.NameLongCommon,"codeSystem",strCodeSystemLoinc,"codeSystemName",strCodeSystemNameLoinc); } StartAndEnd("statusCode","code","completed");//Allowed values: aborted, active, cancelled, completed, held, or suspended. DateTime dateTimeEffective=DateTimeFromString(listLabResultFiltered[i].ObservationDateTime); if(dateTimeEffective.Year<1880) { StartAndEnd("effectiveTime","nullFlavor","UNK"); } else { StartAndEnd("effectiveTime","value",listLabResultFiltered[i].ObservationDateTime); } Start("value"); _w.WriteAttributeString("xsi","type",null,"PQ"); if(value==null || value=="") { Attribs("nullFlavor","UNK"); } else { Attribs("value",value,"unit",listLabResultFiltered[i].UnitsID); } End("value"); StartAndEnd("interpretationCode","code","N","codeSystem","2.16.840.1.113883.5.83"); Start("referenceRange"); Start("observationRange"); if(String.IsNullOrEmpty(listLabResultFiltered[i].referenceRange)) { StartAndEnd("text","nullFlavor","UNK"); } else { _w.WriteElementString("text",listLabResultFiltered[i].referenceRange); } End("observationRange"); End("referenceRange"); End("observation"); End("component"); End("organizer"); End("entry"); } End("section"); End("component"); }
///<summary></summary> public static void Update(EhrLab ehrLab) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(),ehrLab); return; } Crud.EhrLabCrud.Update(ehrLab); }
///<summary>Saves EhrLab to DB and all child elements. Note: this can be used to overwrite new data with old data when viewing old messages. ///Make sure you want to save all new data.</summary> public static EhrLab SaveToDB(EhrLab ehrLab) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { return Meth.GetObject<EhrLab>(MethodBase.GetCurrentMethod(),ehrLab); } //check for existing EhrLab by universal identifier. if(GetByGUID(ehrLab.PlacerOrderUniversalID,ehrLab.PlacerOrderNum)!=null) { ehrLab.EhrLabNum=GetByGUID(ehrLab.PlacerOrderUniversalID,ehrLab.PlacerOrderNum).EhrLabNum;//identified by placer order num... should be the case } else if(GetByGUID(ehrLab.FillerOrderUniversalID,ehrLab.FillerOrderNum)!=null) { ehrLab.EhrLabNum=GetByGUID(ehrLab.FillerOrderUniversalID,ehrLab.FillerOrderNum).EhrLabNum;//identified by the filler order num... rarely } //Insert or update everything if(ehrLab.EhrLabNum==0) {//new; Insert new EhrLab, Insert all new children ehrLab.EhrLabNum=Insert(ehrLab); } else {//existing; update EhrLab, Delete All children so new ones can be reinserted. Update(ehrLab); EhrLabNotes.DeleteForLab(ehrLab.EhrLabNum); EhrLabResults.DeleteForLab(ehrLab.EhrLabNum); EhrLabResultsCopyTos.DeleteForLab(ehrLab.EhrLabNum); EhrLabClinicalInfos.DeleteForLab(ehrLab.EhrLabNum); EhrLabSpecimens.DeleteForLab(ehrLab.EhrLabNum); } //Insert new child elements for(int i=0;i<ehrLab.ListEhrLabNotes.Count;i++) {//must be before lab results. ehrLab.ListEhrLabNotes[i].EhrLabNum=ehrLab.EhrLabNum; ehrLab.ListEhrLabNotes[i].EhrLabNoteNum=EhrLabNotes.Insert(ehrLab.ListEhrLabNotes[i]); } for(int i=0;i<ehrLab.ListEhrLabResults.Count;i++) { ehrLab.ListEhrLabResults[i].EhrLabNum=ehrLab.EhrLabNum; ehrLab.ListEhrLabResults[i]=EhrLabResults.InsertItem(ehrLab.ListEhrLabResults[i]);//insert/return entire object so that child objects are also updated. } for(int i=0;i<ehrLab.ListEhrLabResultsCopyTo.Count;i++) { ehrLab.ListEhrLabResultsCopyTo[i].EhrLabNum=ehrLab.EhrLabNum; ehrLab.ListEhrLabResultsCopyTo[i].EhrLabResultsCopyToNum=EhrLabResultsCopyTos.Insert(ehrLab.ListEhrLabResultsCopyTo[i]); } for(int i=0;i<ehrLab.ListEhrLabSpecimens.Count;i++) { ehrLab.ListEhrLabSpecimens[i].EhrLabNum=ehrLab.EhrLabNum; ehrLab.ListEhrLabSpecimens[i]=EhrLabSpecimens.InsertItem(ehrLab.ListEhrLabSpecimens[i]);//Insert item to return the whole object. } for(int i=0;i<ehrLab.ListRelevantClinicalInformations.Count;i++) { ehrLab.ListRelevantClinicalInformations[i].EhrLabNum=ehrLab.EhrLabNum; ehrLab.ListRelevantClinicalInformations[i].EhrLabClinicalInfoNum=EhrLabClinicalInfos.Insert(ehrLab.ListRelevantClinicalInformations[i]); } return ehrLab; }
///<summary></summary> public static long Insert(EhrLab ehrLab) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { ehrLab.EhrLabNum=Meth.GetLong(MethodBase.GetCurrentMethod(),ehrLab); return ehrLab.EhrLabNum; } return Crud.EhrLabCrud.Insert(ehrLab); }
///<summary>Surround with Try/Catch. Processes an HL7 message into an EHRLab object.</summary> public static List<EhrLab> ProcessHl7Message(string message, Patient patCur, bool isImport){ //Patient patcur; string PIDSegment="";//used to store the PID segment and attached to each lab order generated by this message. List<EhrLab> listRetVal=new List<EhrLab>(); EhrLab ehrLabCur=new EhrLab(); if(!message.StartsWith("MSH")){ //cannnot parse message without message header at the very least throw new Exception("MSH segment not found."); } string[] segments=message.Split(new string[] { "\r\n" },StringSplitOptions.None); string[] fields; string noteSegment="";//used to attach notes to the right objects. for(int s=0;s<segments.Length;s++) { string segment=segments[s]; fields=segment.Split('|'); switch(fields[0]) {//Segment Identifier. case "MSH": if(fields[8]!="ORU^R01^ORU_R01") { throw new Exception("MSH.9 contained wrong value. \""+fields[8]+"\" was found, \"ORU^R01^ORU_R01\" was expected."); } if(fields[11]!="2.5.1") { throw new Exception("MSH.12 shows message version \""+fields[11]+"\", only version \"2.5.1\" is currently supported."); } containsRequiredSegmentsHelper(message); //validate required segments here, after we have verified this is an ORU_R01 message if(fields[20].Split('~').Length==0) { throw new Exception("MSH.21 does not contain any values, the LRI_GU_RU_Profile value \"2.16.840.1.113883.9.17\" is expected."); } for(int i=0;i<fields[20].Split('~').Length;i++) { if(i==fields[20].Split('~').Length) { throw new Exception("MSH.21 ("+i+") indicates sender's message does not conform to LRI_GU_RU_Profile \"2.16.840.1.113883.9.17\""); } if(fields[20].Split('~')[i]=="2.16.840.1.113883.9.17") { break;//found expected value. } } break; //case "SFT": //Software Segment // break; case "PID": PIDSegment=segment; noteSegment="PID"; for(int i=0;i<fields[3].Split('~').Length;i++) { if(patCur==null) { patCur=Patients.GetByGUID(fields[3].Split('~')[i].Split('^')[0], //ID Number fields[3].Split('~')[i].Split('^')[3].Split('&')[1]); //Assigning Authority ID } if(patCur!=null) { ehrLabCur.PatNum=patCur.PatNum; } else { ehrLabCur.PatNum=0; //if(i==fields[3].Split('~').Length) {//we have checked all patient ID's and none of them were a valid patnum in our DB. // throw new Exception("PID.3 does not contain a known patient ID.");//we should have an option to manually associate lab results with a patient record, in the UI layer. //} } } //all other PID segments are informative, PID.3 is the only one we need to process. break; //case "PD1": //patient demographics // break; //case "NK1": //Next of Kin/Associated Parties // break; //case "PV1": //Patient Visit // break; //case "PV2": //Patient Visit addiotional information // break; case "ORC": //Each new ORC segment designates a new EhrLabOrder attached to the same patient. if(ehrLabCur.PlacerOrderNum!=null || ehrLabCur.FillerOrderNum!=null) {//these fields are filled by the ORC segment, if they are blank, this is the first ORC segment encountered. listRetVal.Add(ehrLabCur); ehrLabCur=new EhrLab(); ehrLabCur.PatNum=listRetVal[0].PatNum; } ehrLabCur.OriginalPIDSegment=PIDSegment;//may not match actual PatNum/Patient information. try { ehrLabCur.OrderControlCode=(HL70119)Enum.Parse(typeof(HL70119),fields[1]); } catch { throw new Exception("ORC.1 does not contain a valid Order Control Code (HL70119 value set)."); } //Placer Order Num if(fields[2].Length!=0) {//optional field, length may be 0 if field was ommitted. ehrLabCur.PlacerOrderNum =fields[2].Split('^')[0]; ehrLabCur.PlacerOrderNamespace =fields[2].Split('^')[1]; ehrLabCur.PlacerOrderUniversalID =fields[2].Split('^')[2]; ehrLabCur.PlacerOrderUniversalIDType =fields[2].Split('^')[3]; } //Filler Order Num ehrLabCur.FillerOrderNum =fields[3].Split('^')[0]; ehrLabCur.FillerOrderNamespace =fields[3].Split('^')[1]; ehrLabCur.FillerOrderUniversalID =fields[3].Split('^')[2]; ehrLabCur.FillerOrderUniversalIDType =fields[3].Split('^')[3]; //Filler Group Num if(fields[4].Length!=0) { ehrLabCur.PlacerGroupNum =fields[4].Split('^')[0]; ehrLabCur.PlacerGroupNamespace =fields[4].Split('^')[1]; ehrLabCur.PlacerGroupUniversalID =fields[4].Split('^')[2]; ehrLabCur.PlacerGroupUniversalIDType =fields[4].Split('^')[3]; } //Ordering Provider ehrLabCur.OrderingProviderID =fields[12].Split('^')[0]; ehrLabCur.OrderingProviderLName =fields[12].Split('^')[1]; ehrLabCur.OrderingProviderFName =fields[12].Split('^')[2]; ehrLabCur.OrderingProviderMiddleNames =fields[12].Split('^')[3]; ehrLabCur.OrderingProviderSuffix =fields[12].Split('^')[4]; ehrLabCur.OrderingProviderPrefix =fields[12].Split('^')[5]; ehrLabCur.OrderingProviderAssigningAuthorityNamespaceID =fields[12].Split('^')[8].Split('&')[0]; ehrLabCur.OrderingProviderAssigningAuthorityUniversalID =fields[12].Split('^')[8].Split('&')[1]; ehrLabCur.OrderingProviderAssigningAuthorityIDType =fields[12].Split('^')[8].Split('&')[2]; try { ehrLabCur.OrderingProviderNameTypeCode=(HL70200)Enum.Parse(typeof(HL70200),fields[12].Split('^')[9]); } catch { throw new Exception("ORC.12.10 does not contain a valid Name Type Code (HL70200 value set)."); } try { ehrLabCur.OrderingProviderIdentifierTypeCode =(HL70203)Enum.Parse(typeof(HL70203),fields[12].Split('^')[12]); } catch { throw new Exception("ORC.12.13 does not contain a valid Identifier Type Code (HL70203 value set)."); } break; case "OBR": noteSegment="OBR"; ehrLabCur.SetIdOBR=PIn.Long(fields[1]); if(isImport) { ehrLabCur.ListEhrLabNotes=new List<EhrLabNote>(); ehrLabCur.ListEhrLabResults=new List<EhrLabResult>(); } //OBR order num should always be identical to OCR order number//Not true. if(ehrLabCur.FillerOrderNum!=fields[3].Split('^')[0]) { throw new Exception("Filler order numbers in OCR.3 and OBR.3 segments do not match."); } //Universal Service ID ehrLabCur.UsiID = fields[4].Split('^')[0]; ehrLabCur.UsiText = fields[4].Split('^')[1]; try { ehrLabCur.UsiCodeSystemName = fields[4].Split('^')[2]; } catch { } try { ehrLabCur.UsiIDAlt = fields[4].Split('^')[3]; } catch { } try { ehrLabCur.UsiTextAlt = fields[4].Split('^')[4]; } catch { } try { ehrLabCur.UsiCodeSystemNameAlt = fields[4].Split('^')[5]; } catch { } try { ehrLabCur.UsiTextOriginal = fields[4].Split('^')[6]; } catch { } //Observation Date Time ehrLabCur.ObservationDateTimeStart =fields[7]; if(fields[8].Length!=0) { ehrLabCur.ObservationDateTimeEnd =fields[8]; } try { ehrLabCur.SpecimenActionCode =(HL70065)Enum.Parse(typeof(HL70065),fields[11]); } catch { } if(isImport) { ehrLabCur.ListRelevantClinicalInformations=new List<EhrLabClinicalInfo>(); } for(int i=0;i<fields[13].Split('~').Length;i++) { if(fields[13].Length==0) { break;//nothing to process } string tempClinInfo=fields[13].Split('~')[i]; EhrLabClinicalInfo ehrLabClinicalInfo=new EhrLabClinicalInfo(); ehrLabClinicalInfo.ClinicalInfoID =tempClinInfo.Split('^')[0]; try { ehrLabClinicalInfo.ClinicalInfoText =tempClinInfo.Split('^')[1]; } catch { } try { ehrLabClinicalInfo.ClinicalInfoCodeSystemName =tempClinInfo.Split('^')[2]; } catch { } try { ehrLabClinicalInfo.ClinicalInfoIDAlt =tempClinInfo.Split('^')[3]; } catch { } try { ehrLabClinicalInfo.ClinicalInfoTextAlt =tempClinInfo.Split('^')[4]; } catch { } try { ehrLabClinicalInfo.ClinicalInfoCodeSystemNameAlt =tempClinInfo.Split('^')[5]; } catch { } try { ehrLabClinicalInfo.ClinicalInfoTextOriginal =tempClinInfo.Split('^')[6]; } catch { } ehrLabCur.ListRelevantClinicalInformations.Add(ehrLabClinicalInfo); } //OBR 16; Ordering Provider same as OCR. //not validating or checking at this time. ehrLabCur.ResultDateTime=fields[22]; if(fields.Length<=25) { break; }//likely that fields beyond this are left out. try { ehrLabCur.ResultStatus =(HL70123)Enum.Parse(typeof(HL70123),fields[25]); } catch { } //Parent Result if(fields.Length<=26) { break; }//likely that fields beyond this are left out. ehrLabCur.ParentObservationID =fields[26].Split('^')[0].Split('&')[0]; try { ehrLabCur.ParentObservationText =fields[26].Split('^')[0].Split('&')[1]; } catch { } try { ehrLabCur.ParentObservationCodeSystemName =fields[26].Split('^')[0].Split('&')[2]; } catch { } try { ehrLabCur.ParentObservationIDAlt =fields[26].Split('^')[0].Split('&')[3]; } catch { } try { ehrLabCur.ParentObservationTextAlt =fields[26].Split('^')[0].Split('&')[4]; } catch { } try { ehrLabCur.ParentObservationCodeSystemNameAlt =fields[26].Split('^')[0].Split('&')[5]; } catch { } try { ehrLabCur.ParentObservationTextOriginal =fields[26].Split('^')[0].Split('&')[6]; } catch { } try { ehrLabCur.ParentObservationSubID =fields[26].Split('^')[1]; } catch { } //Results Copy To if(isImport) { ehrLabCur.ListEhrLabResultsCopyTo=new List<EhrLabResultsCopyTo>(); } if(fields.Length<28) { break; }//likely that fields beyond this are left out. for(int i=0;i<fields[28].Split('~').Length;i++) { EhrLabResultsCopyTo tempRCT=new EhrLabResultsCopyTo(); string stringRCT=fields[28].Split('~')[i]; if(stringRCT.Length==0) { continue;//usually only if nothing was sent, but also if an empty field was sent. } tempRCT.CopyToID =stringRCT.Split('^')[0]; tempRCT.CopyToLName =stringRCT.Split('^')[1]; tempRCT.CopyToFName =stringRCT.Split('^')[2]; tempRCT.CopyToMiddleNames =stringRCT.Split('^')[3]; tempRCT.CopyToSuffix =stringRCT.Split('^')[4]; tempRCT.CopyToPrefix =stringRCT.Split('^')[5]; tempRCT.CopyToAssigningAuthorityUniversalID =stringRCT.Split('^')[8].Split('&')[0]; tempRCT.CopyToAssigningAuthorityNamespaceID =stringRCT.Split('^')[8].Split('&')[1]; tempRCT.CopyToAssigningAuthorityIDType =stringRCT.Split('^')[8].Split('&')[2]; try { tempRCT.CopyToNameTypeCode=(HL70200)Enum.Parse(typeof(HL70200),stringRCT.Split('^')[9]); } catch { throw new Exception("ORC.12.10 does not contain a valid Name Type Code (HL70200 value set)."); } try { ehrLabCur.OrderingProviderIdentifierTypeCode =(HL70203)Enum.Parse(typeof(HL70203),stringRCT.Split('^')[12]); } catch { throw new Exception("ORC.12.13 does not contain a valid Identifier Type Code (HL70203 value set)."); } ehrLabCur.ListEhrLabResultsCopyTo.Add(tempRCT); } //Parent Lab if(fields.Length<29) { break; }//likely that fields beyond this are left out. ehrLabCur.ParentPlacerOrderNum =fields[29].Split('^')[0].Split('&')[0]; try { ehrLabCur.ParentPlacerOrderNamespace =fields[29].Split('^')[0].Split('&')[1]; } catch { } try { ehrLabCur.ParentPlacerOrderUniversalID =fields[29].Split('^')[0].Split('&')[2]; } catch { } try { ehrLabCur.ParentPlacerOrderUniversalIDType =fields[29].Split('^')[0].Split('&')[3]; } catch { } try { ehrLabCur.ParentFillerOrderNum =fields[29].Split('^')[1].Split('&')[0]; } catch { } try { ehrLabCur.ParentFillerOrderNamespace =fields[29].Split('^')[1].Split('&')[1]; } catch { } try { ehrLabCur.ParentFillerOrderUniversalID =fields[29].Split('^')[1].Split('&')[2]; } catch { } try { ehrLabCur.ParentFillerOrderUniversalIDType =fields[29].Split('^')[1].Split('&')[3]; } catch { } if(fields.Length<31) { break;//next segment. all additional fields were omitted from this one. } if(fields.Length<49) { break; }//likely that fields beyond this are left out. //result Handling ehrLabCur.ListEhrLabResultsHandlingF =fields[49].Contains("F"); ehrLabCur.ListEhrLabResultsHandlingN =fields[49].Contains("N"); break; case "NTE": //Each not can contain any number of comments, these comments will be carrot delimited. That will be handled later in the UI. Just store this NTE Segment in an EHRLabNote EhrLabNote ehrNote=new EhrLabNote(); //todo:No SetIDNTE? ehrNote.Comments=fields[3]; switch(noteSegment) { case "OBX": //Attach note to observation. ehrLabCur.ListEhrLabResults[ehrLabCur.ListEhrLabResults.Count-1].ListEhrLabResultNotes.Add(ehrNote); break; case "PID": case "OBR": default: //if PID, OBR, or Other just attach note to the lab. ehrLabCur.ListEhrLabNotes.Add(ehrNote); break; } break; case "TQ1": ehrLabCur.TQ1SetId=PIn.Long(fields[1]); ehrLabCur.TQ1DateTimeStart=fields[7]; ehrLabCur.TQ1DateTimeEnd=fields[8]; break; //case "TQ2": //Timing/Quantity Order Sequence // break; //case "CTD": //Contact Data // break; case "OBX": noteSegment="OBX"; //if(ehrLabCur.ListEhrLabResults==null) { // ehrLabCur.ListEhrLabResults=new List<EhrLabResult>(); //} EhrLabResult labResult=new EhrLabResult(); labResult.SetIdOBX=PIn.Long(fields[1]); try { labResult.ValueType=(HL70125)Enum.Parse(typeof(HL70125),fields[2]); } catch { } //Lab Result Observation Identifier (LOINC) labResult.ObservationIdentifierID =fields[3].Split('^')[0]; try { labResult.ObservationIdentifierText =fields[3].Split('^')[1]; } catch { } try { labResult.ObservationIdentifierCodeSystemName =fields[3].Split('^')[2]; } catch { } try { labResult.ObservationIdentifierIDAlt =fields[3].Split('^')[3]; } catch { } try { labResult.ObservationIdentifierTextAlt =fields[3].Split('^')[4]; } catch { } try { labResult.ObservationIdentifierCodeSystemNameAlt =fields[3].Split('^')[5]; } catch { } if(fields[3].Split('^').Length>6) { labResult.ObservationIdentifierTextOriginal =fields[3].Split('^')[6]; } labResult.ObservationIdentifierSub=fields[4]; //Observation Value switch(labResult.ValueType) { case HL70125.CE: case HL70125.CWE: labResult.ObservationValueCodedElementID =fields[5].Split('^')[0]; try { labResult.ObservationValueCodedElementText =fields[5].Split('^')[1]; } catch { } try { labResult.ObservationValueCodedElementCodeSystemName =fields[5].Split('^')[2]; } catch { } try { labResult.ObservationValueCodedElementIDAlt =fields[5].Split('^')[3]; } catch { } try { labResult.ObservationValueCodedElementTextAlt =fields[5].Split('^')[4]; } catch { } try { labResult.ObservationValueCodedElementCodeSystemNameAlt =fields[5].Split('^')[5]; } catch { } if(labResult.ValueType==HL70125.CWE) { labResult.ObservationValueCodedElementTextOriginal=fields[5].Split('^')[6]; } break; case HL70125.DT: case HL70125.TS: labResult.ObservationValueDateTime=fields[5]; break; case HL70125.FT://formatted text case HL70125.ST://string case HL70125.TX://text labResult.ObservationValueText=fields[5]; break; case HL70125.NM: //data may contain positive or negative sign. Below, the sign is handled first, and then multiplied by PIn.Double(val) labResult.ObservationValueNumeric= (fields[5].Contains("-")?-1f:1f) * PIn.Double(fields[5].Trim('+').Trim('-')); break; case HL70125.SN: labResult.ObservationValueComparator = fields[5].Split('^')[0]; try { labResult.ObservationValueNumber1 =PIn.Double(fields[5].Split('^')[1]); } catch { }//optional, may be a null reference try { labResult.ObservationValueSeparatorOrSuffix = fields[5].Split('^')[2]; } catch { }//optional, may be a null reference try { labResult.ObservationValueNumber2 =PIn.Double(fields[5].Split('^')[3]); } catch { }//optional, may be a null reference break; case HL70125.TM: labResult.ObservationValueTime=PIn.Time(fields[5]); break; } //Units if(fields[6].Length!=0) { labResult.UnitsID =fields[6].Split('^')[0]; labResult.UnitsText =fields[6].Split('^')[1]; try { labResult.UnitsCodeSystemName =fields[6].Split('^')[2]; } catch { } try { labResult.UnitsIDAlt =fields[6].Split('^')[3]; } catch { } try { labResult.UnitsTextAlt =fields[6].Split('^')[4]; } catch { } try { labResult.UnitsCodeSystemNameAlt =fields[6].Split('^')[5]; } catch { } try { labResult.UnitsTextOriginal =fields[6].Split('^')[6]; } catch { } } labResult.referenceRange=fields[7]; labResult.AbnormalFlags=fields[8].Replace('~',',');//TODO: may need additional formatting/testing try { labResult.ObservationResultStatus =(HL70085)Enum.Parse(typeof(HL70085),fields[11]); } catch { } labResult.ObservationDateTime=fields[14]; labResult.AnalysisDateTime=fields[19]; //performing organization Name (with additional info) labResult.PerformingOrganizationName=fields[23].Split('^')[0]; labResult.PerformingOrganizationNameAssigningAuthorityNamespaceId =fields[23].Split('^')[5].Split('&')[0]; labResult.PerformingOrganizationNameAssigningAuthorityUniversalId =fields[23].Split('^')[5].Split('&')[1]; labResult.PerformingOrganizationNameAssigningAuthorityUniversalIdType =fields[23].Split('^')[5].Split('&')[2]; try { labResult.PerformingOrganizationIdentifierTypeCode =(HL70203)Enum.Parse(typeof(HL70203),fields[23].Split('^')[7]); } catch { } labResult.PerformingOrganizationIdentifier=fields[23].Split('^')[9]; //Performing Organization Address labResult.PerformingOrganizationAddressStreet =fields[24].Split('^')[0].Split('&')[0]; try { labResult.PerformingOrganizationAddressOtherDesignation =fields[24].Split('^')[1]; } catch { } try { labResult.PerformingOrganizationAddressCity =fields[24].Split('^')[2]; } catch { } try { labResult.PerformingOrganizationAddressStateOrProvince =(USPSAlphaStateCode)Enum.Parse(typeof(USPSAlphaStateCode),fields[24].Split('^')[3]); } catch { } try { labResult.PerformingOrganizationAddressZipOrPostalCode =fields[24].Split('^')[4]; } catch { } try { labResult.PerformingOrganizationAddressCountryCode =fields[24].Split('^')[5]; } catch { } try { labResult.PerformingOrganizationAddressAddressType =(HL70190)Enum.Parse(typeof(HL70190),fields[24].Split('^')[6]); } catch { } try { labResult.PerformingOrganizationAddressCountyOrParishCode =fields[24].Split('^')[7]; } catch { } //Performing Organization Medical Director if(fields.Length<=25) { break;//next segment. this one is finished. } labResult.MedicalDirectorID =fields[25].Split('^')[0]; try { labResult.MedicalDirectorFName =fields[25].Split('^')[1]; } catch { } try { labResult.MedicalDirectorLName =fields[25].Split('^')[2]; } catch { } try { labResult.MedicalDirectorMiddleNames =fields[25].Split('^')[3]; } catch { } try { labResult.MedicalDirectorSuffix =fields[25].Split('^')[4]; } catch { } try { labResult.MedicalDirectorPrefix =fields[25].Split('^')[5]; } catch { } try { labResult.MedicalDirectorAssigningAuthorityNamespaceID =fields[25].Split('^')[8].Split('&')[0]; } catch { } try { labResult.MedicalDirectorAssigningAuthorityUniversalID =fields[25].Split('^')[8].Split('&')[1]; } catch { } try { labResult.MedicalDirectorAssigningAuthorityIDType =fields[25].Split('^')[8].Split('&')[2]; } catch { } try { labResult.MedicalDirectorNameTypeCode =(HL70200)Enum.Parse(typeof(HL70200),fields[25].Split('^')[9]); } catch { } try { labResult.MedicalDirectorIdentifierTypeCode =(HL70203)Enum.Parse(typeof(HL70203),fields[25].Split('^')[12]); } catch { } ehrLabCur.ListEhrLabResults.Add(labResult); break; //case "FTI": //Financial Transaction // break; //case "CTI": //Clinical Trial Identification // break; case "SPM": //if(retVal.ListEhrLabSpecimin==null) { // retVal.ListEhrLabSpecimin=new List<EhrLabSpecimen>(); //} EhrLabSpecimen ehrLabSpecimen=new EhrLabSpecimen(); ehrLabSpecimen.SetIdSPM=PIn.Long(fields[1]); //Specimen Type ehrLabSpecimen.SpecimenTypeID = fields[4].Split('^')[0]; try { ehrLabSpecimen.SpecimenTypeText = fields[4].Split('^')[1]; } catch { } try { ehrLabSpecimen.SpecimenTypeCodeSystemName = fields[4].Split('^')[2]; } catch { } try { ehrLabSpecimen.SpecimenTypeIDAlt = fields[4].Split('^')[3]; } catch { } try { ehrLabSpecimen.SpecimenTypeTextAlt = fields[4].Split('^')[4]; } catch { } try { ehrLabSpecimen.SpecimenTypeCodeSystemNameAlt = fields[4].Split('^')[5]; } catch { } try { ehrLabSpecimen.SpecimenTypeTextOriginal = fields[4].Split('^')[6]; } catch { } //TODO:? check to see if either triplet contained a valid code. //Collection Date Time ehrLabSpecimen.CollectionDateTimeStart =fields[17].Split('^')[0]; try { ehrLabSpecimen.CollectionDateTimeEnd =fields[17].Split('^')[1]; } catch { } if(fields.Length<19) { ehrLabCur.ListEhrLabSpecimens.Add(ehrLabSpecimen); break;//next segment. This one has no more fields } //if(ehrLabSpecimen.ListEhrLabSpecimenRejectReason==null) { // ehrLabSpecimen.ListEhrLabSpecimenRejectReason=new List<EhrLabSpecimenRejectReason>(); //} //Reject Reason for(int i=0;i<fields[21].Split('~').Length;i++) { if(fields[21].Length==0) { break;//nothing in this field } EhrLabSpecimenRejectReason ehrLabRR=new EhrLabSpecimenRejectReason(); ehrLabRR.SpecimenRejectReasonID =fields[21].Split('~')[i].Split('^')[0]; try { ehrLabRR.SpecimenRejectReasonText =fields[21].Split('~')[i].Split('^')[1]; } catch { } try { ehrLabRR.SpecimenRejectReasonCodeSystemName =fields[21].Split('~')[i].Split('^')[2]; } catch { } try { ehrLabRR.SpecimenRejectReasonIDAlt =fields[21].Split('~')[i].Split('^')[3]; } catch { } try { ehrLabRR.SpecimenRejectReasonTextAlt =fields[21].Split('~')[i].Split('^')[4]; } catch { } try { ehrLabRR.SpecimenRejectReasonCodeSystemNameAlt =fields[21].Split('~')[i].Split('^')[5]; } catch { } try { ehrLabRR.SpecimenRejectReasonTextOriginal =fields[21].Split('~')[i].Split('^')[6]; } catch { } //TODO:? check to see if either triplet contained a valid code. ehrLabSpecimen.ListEhrLabSpecimenRejectReason.Add(ehrLabRR); } //Specimen Condition for(int i=0;i<fields[24].Split('~').Length;i++) { if(fields[24].Length==0) { break;//nothing in this field } EhrLabSpecimenCondition ehrLabSC=new EhrLabSpecimenCondition(); ehrLabSC.SpecimenConditionID =fields[24].Split('~')[i].Split('^')[0]; try { ehrLabSC.SpecimenConditionText =fields[24].Split('~')[i].Split('^')[1]; } catch { } try { ehrLabSC.SpecimenConditionCodeSystemName =fields[24].Split('~')[i].Split('^')[2]; } catch { } try { ehrLabSC.SpecimenConditionIDAlt =fields[24].Split('~')[i].Split('^')[3]; } catch { } try { ehrLabSC.SpecimenConditionTextAlt =fields[24].Split('~')[i].Split('^')[4]; } catch { } try { ehrLabSC.SpecimenConditionCodeSystemNameAlt =fields[24].Split('~')[i].Split('^')[5]; } catch { } try { ehrLabSC.SpecimenConditionTextOriginal =fields[24].Split('~')[i].Split('^')[6]; } catch { } ehrLabSpecimen.ListEhrLabSpecimenCondition.Add(ehrLabSC); } ehrLabCur.ListEhrLabSpecimens.Add(ehrLabSpecimen); break; default: //to catch unsupported or malformed segments. break; }//end switch }//end foreach segment //TODO:Message has been processed into an EHR Lab... Now we can do other things if we want to... listRetVal.Add(ehrLabCur);//other labs may have already been added to retval in the code above. return listRetVal; }