Exemplo n.º 1
0
        private static string gRace(Patient pat)
        {
            switch (PatientRaces.GetPatientRaceOldFromPatientRaces(pat.PatNum))              //Uses the deprecated PatientRaceOld enum converted from PatientRaces.GetPatientRaceOldFromPatientRaces()
            {
            case PatientRaceOld.AmericanIndian:
                return("American Indian Or Alaska Native");

            case PatientRaceOld.Asian:
                return("Asian");

            case PatientRaceOld.HawaiiOrPacIsland:
                return("Native Hawaiian or Other Pacific");

            case PatientRaceOld.AfricanAmerican:
                return("Black or African American");

            case PatientRaceOld.White:
                return("White");

            case PatientRaceOld.HispanicLatino:
                return("Hispanic");

            case PatientRaceOld.Other:
                return("Other Race");

            default:
                return("Other Race");
            }
        }
Exemplo n.º 2
0
 ///<summary>Patient identification.</summary>
 private void PID(Patient pat)
 {
     seg = new SegmentHL7(SegmentNameHL7.PID);
     seg.SetField(0, "PID");
     seg.SetField(2, pat.PatNum.ToString());
     seg.SetField(3, pat.PatNum.ToString());
     seg.SetField(5, pat.LName, pat.FName);
     if (pat.Birthdate.Year > 1880)           //7: dob optional
     {
         seg.SetField(7, pat.Birthdate.ToString("yyyyMMdd"));
     }
     seg.SetField(8, ConvertGender(pat.Gender));
     seg.SetField(10, ConvertRace(PatientRaces.GetPatientRaceOldFromPatientRaces(pat.PatNum)));        //Converts entries from PatientRace table to deprecated PatientRaceOld for call.
     seg.SetField(11, pat.Address, pat.Address2, pat.City, pat.State, pat.Zip, "", "M");               //M is for mailing.
     seg.SetField(13, ConvertPhone(pat.HmPhone));
     seg.SetField(22, ConvertEthnicGroup(PatientRaces.GetPatientRaceOldFromPatientRaces(pat.PatNum))); //Converts entries from PatientRace table to deprecated PatientRaceOld for call.
     msg.Segments.Add(seg);
 }
Exemplo n.º 3
0
 ///<summary>Patient identification.</summary>
 private void PID(Patient pat)
 {
     seg = new SegmentHL7(SegmentNameHL7.PID);
     seg.SetField(0, "PID");
     seg.SetField(1, "1");
     seg.SetField(2, pat.ChartNumber);           //Account number.  eCW requires this to be the same # as came in on PID.4.
     seg.SetField(3, pat.PatNum.ToString());     //??what is this MRN?
     seg.SetField(5, pat.LName, pat.FName, pat.MiddleI);
     //we assume that dob is always valid because eCW should always pass us a dob.
     seg.SetField(7, pat.Birthdate.ToString("yyyyMMdd"));
     seg.SetField(8, ConvertGender(pat.Gender));
     seg.SetField(10, ConvertRace(PatientRaces.GetPatientRaceOldFromPatientRaces(pat.PatNum)));           //Passes in the deprecated PatientRaceOld enum retrieved from the PatientRace table.
     seg.SetField(11, pat.Address, pat.Address2, pat.City, pat.State, pat.Zip);
     seg.SetField(13, ConvertPhone(pat.HmPhone));
     seg.SetField(14, ConvertPhone(pat.WkPhone));
     seg.SetField(16, ConvertMaritalStatus(pat.Position));
     seg.SetField(19, pat.SSN);
     msg.Segments.Add(seg);
 }
Exemplo n.º 4
0
        ///<summary>PatNum will not be altered here.  The pat passed in must either have PatNum=0, or must have a PatNum matching the segment.  The reason that isStandalone is passed in is because if using tight integration mode (isStandalone=false), then we need to store the "alternate patient id" aka Account No. that comes in on PID.4 in the ChartNumber field so we can pass it back in PID.2 of the DFT charge message.  However, if not using tight integration (isStandalone=true), the ChartNumber field is already occupied by the eCW patient ID, and we do not want to overwrite it.</summary>
        public static void ProcessPID(Patient pat, SegmentHL7 seg, bool isStandalone)
        {
            long patNum = PIn.Long(seg.GetFieldFullText(2));

            //if(pat.PatNum==0) {
            //	pat.PatNum=patNum;
            //}
            //else
            if (!isStandalone &&         //in standalone, the patnums won't match, so don't check
                pat.PatNum != 0 && pat.PatNum != patNum)
            {
                throw new ApplicationException("Invalid patNum");
            }
            if (!isStandalone)             //when in tight integration mode
            {
                pat.ChartNumber = seg.GetFieldFullText(4);
            }
            pat.LName     = seg.GetFieldComponent(5, 0);
            pat.FName     = seg.GetFieldComponent(5, 1);
            pat.MiddleI   = seg.GetFieldComponent(5, 2);
            pat.Birthdate = DateParse(seg.GetFieldFullText(7));
            pat.Gender    = GenderParse(seg.GetFieldFullText(8));
            PatientRaceOld patientRaceOld = RaceParse(seg.GetFieldFullText(10));

            //Converts PatientRaceOld to new Patient Races, and adds them o the PatientRace table.
            PatientRaces.Reconcile(pat.PatNum, PatientRaces.GetPatRacesFromPatientRaceOld(patientRaceOld));
            pat.Address  = seg.GetFieldComponent(11, 0);
            pat.Address2 = seg.GetFieldComponent(11, 1);
            pat.City     = seg.GetFieldComponent(11, 2);
            pat.State    = seg.GetFieldComponent(11, 3);
            pat.Zip      = seg.GetFieldComponent(11, 4);
            pat.HmPhone  = PhoneParse(seg.GetFieldFullText(13));
            pat.WkPhone  = PhoneParse(seg.GetFieldFullText(14));
            pat.Position = MaritalStatusParse(seg.GetFieldFullText(16));
            //pat.ChartNumber=seg.GetFieldFullText(18);//this is wrong.  Would also break standalone mode
            pat.SSN = seg.GetFieldFullText(19);
            if (ProgramProperties.GetPropVal(ProgramName.eClinicalWorks, "FeeSchedulesSetManually") == "0")          //if !FeeSchedulesSetManually
            {
                pat.FeeSched = FeeScheduleParse(seg.GetFieldFullText(22));
            }
        }
Exemplo n.º 5
0
        ///<summary>Patient Identifier segment.  Required.  Guide page 40.</summary>
        private void PID()
        {
            _seg = new SegmentHL7(SegmentNameHL7.PID);
            _seg.SetField(0, "PID");
            _seg.SetField(1, "1");           //PID-1 Set ID - PID.  Optional.  Cardinality [0..1].  Must be "1" for the first occurrence.  Not sure why there would ever be more than one.
            //PID-2 Patient ID.  No longer used.
            //PID-3 Patient Identifier List.  Required (length up to 478).  Cardinality [1..*].  Type CX.
            _seg.SetField(3,
                          _pat.PatNum.ToString(), //PID-3.1 ID Number.  Required (length 1..15).
                          "",                     //PID-3.2 Check Digit.  Optional (length 1..1).
                          "",                     //PID-3.3 Check Digit Scheme.  No longer used.
                          "Open Dental",          //PID-3.4 Assigning Authority.  Required (1..227).  Value set HL70363.
                          "MR"                    //PID-3.5 Identifier Type Code.  Required (length 2..5).  Value set HL70203.  MR=medical record number.
                                                  //PID-3.6 Assigning Facility.  Optional (length 1..227).
                                                  //PID-3.7 Effective Date.  No longer used.
                                                  //PID-3.8 Expiration Date.  No longer used.
                                                  //PID-3.9 Assigning Jurisdiction.  No longer used.
                                                  //PID-3.10 Assigning Facility.  No longer used.
                          );
            if (_pat.SSN.Trim() != "")
            {
                _seg.RepeatField(3,
                                 _pat.SSN.Trim(), //PID-3.1 ID Number.  Required (length 1..15).
                                 "",              //PID-3.2 Check Digit.  Optional (length 1..1).
                                 "",              //PID-3.3 Check Digit Scheme.  No longer used.
                                 "Open Dental",   //PID-3.4 Assigning Authority.  Required (length 1..227).  Value set HL70363.
                                 "SS"             //PID-3.5 Identifier Type Code.  Required (length 2..5).  Value set HL70203.  SS=Social Security Number.
                                                  //PID-3.6 Assigning Facility.  Optional (length 1..227).
                                                  //PID-3.7 Effective Date.  No longer used.
                                                  //PID-3.8 Expiration Date.  No longer used.
                                                  //PID-3.9 Assigning Jurisdiction.  No longer used.
                                                  //PID-3.10 Assigning Facility.  No longer used.
                                 );
            }
            //PID-4 Alternate Patient ID.  No longer used.
            //PID-5 Patient Name.  Required (length up to 294).  Cardinality [1..*].  Type XPN.  The first repetition must contain the legal name.
            WriteXPN(5, _pat.FName, _pat.LName, _pat.MiddleI, "L");
            //PID-6 Mother's Maiden Name.  No longer used.
            //PID-7 Date/Time of Birth.  Optional.  Cardinality [0..1].
            if (_pat.Birthdate.Year > 1880)
            {
                _seg.SetField(7, _pat.Birthdate.ToString("yyyyMMdd"));
            }
            WriteGender(8, _pat.Gender);           //PID-8 Administrative Sex.  Required if known.  Cardinality [0..1].  Value set HL70001.
            //PID-9 Patient Alias.  No longer used.
            //PID-10 Race.  Required if known.  Cardinality [0..*].  Value set HL70005.  Each race definition must be type CE.
            List <PatientRace> listPatientRaces     = PatientRaces.GetForPatient(_pat.PatNum);
            List <PatientRace> listPatRacesFiltered = new List <PatientRace>();
            bool isHispanicOrLatino = false;

            for (int i = 0; i < listPatientRaces.Count; i++)
            {
                if (listPatientRaces[i].IsEthnicity)
                {
                    if (listPatientRaces[i].CdcrecCode == "2186-5")                   //Not hispanic
                    //Nothing to do. Flag is set to false by default.
                    {
                    }
                    else if (listPatientRaces[i].CdcrecCode != PatientRace.DECLINE_SPECIFY_ETHNICITY_CODE)
                    {
                        isHispanicOrLatino = true;                      //All other ethnicities are Hispanic
                    }
                }
                else
                {
                    if (listPatientRaces[i].CdcrecCode == PatientRace.DECLINE_SPECIFY_RACE_CODE)
                    {
                        listPatRacesFiltered.Clear();
                        break;
                    }
                    listPatRacesFiltered.Add(listPatientRaces[i]);
                }
            }
            for (int i = 0; i < listPatRacesFiltered.Count; i++)
            {
                string strRaceCode = listPatRacesFiltered[i].CdcrecCode;
                string strRaceName = listPatRacesFiltered[i].Description;
                _seg.SetOrRepeatField(10,
                                      strRaceCode, //PID-10.1 Identifier.  Required (length 1..50).
                                      strRaceName, //PID-10.2  Text.  Required if known (length 1..999). Human readable text that is not further used.
                                      "CDCREC"     //PID-10.3 Name of Coding System.  Required (length 1..20).
                                                   //PID-10.4 Alternate Identifier.  Required if known (length 1..50).
                                                   //PID-10.5 Alternate Text.  Required if known (length 1..999).
                                                   //PID-10.6 Name of Alternate Coding system.  Required if PID-10.4 is not blank.
                                      );
            }
            //PID-11 Patient Address.  Required if known (length up to 513).  Cardinality [0..*].  Type XAD.
            WriteXAD(11, _pat.Address, _pat.Address2, _pat.City, _pat.State, _pat.Zip);
            //PID-12 County Code.  No longer used.
            //PID-13 Phone Number - Home.  No longer used.
            //PID-14 Phone Number - Business.  No longer used.
            //PID-15 Primary Language.  No longer used.
            //PID-16 Marital Status.  No longer used.
            //PID-17 Religion.  No longer used.
            //PID-18 Patient Account Number.  Optional.  However, we already sent this above.  Why do they have another field for this data?
            //PID-19 SSN Number - Patient.  No longer used.  We send SSN in PID-3.
            //PID-20 Driver's License Number - Patient.  No longer used.
            //PID-21 Mother's Identifier.  No longer used.
            //PID-22 Ethnic Group.  Required if known (length up to 478).  Cardinality [0..1].  Value set HL70189 (guide page 201).  Type CE.
            if (listPatRacesFiltered.Count > 0)           //The user specified a race and ethnicity and did not select the decline to specify option.
            {
                if (isHispanicOrLatino)
                {
                    WriteCE(22, "2135-2", "Hispanic or Latino", "CDCREC");
                }
                else                  //Not hispanic or latino.
                {
                    WriteCE(22, "2186-5", "not Hispanic or Latino", "CDCREC");
                }
            }
            //PID-23 Birth Place.  No longer used.
            //PID-24 Multiple Birth Indicator.  No longer used.
            //PID-25 Birth Order.  No longer used.
            //PID-26 Citizenship.  No longer used.
            //PID-27 Veterans Military Status.  No longer used.
            //PID-28 Nationality.  No longer used.
            //PID-29 Patient Death Date and Time.  Required if PID-30 is set to "Y" (length 12..26).  Cardinaility [0..1].
            if (_pat.DateTimeDeceased.Year > 1880)
            {
                _seg.SetField(29, _pat.DateTimeDeceased.ToString("yyyyMMddhhmmss"));
            }
            //PID-30 Patient Death Indicator.  Required if known.  Cardinaility [0..1].  Value set HL70136.
            if (_pat.DateTimeDeceased.Year > 1880)
            {
                _seg.SetField(30, "Y");
            }
            //PID-31 Identity Unknown.  No longer used.
            //PID-32 Identity Reliability Code.  No longer used.
            //PID-33 Last Update Date/Time.  Optional.  Cardinaility [0..1].
            //PID-34 Last Update Facility.  Optional.  Cardinaility [0..1].
            //PID-35 Species Code.  No longer used.
            //PID-36 Breed Code.  No longer used.
            //PID-37 Strain.  No longer used.
            //PID-38 Production Class Code.  No longer used.
            //PID-39 Tribal Citizenship.  No longer used.
            _msg.Segments.Add(_seg);
        }
Exemplo n.º 6
0
        ///<summary>Uses a VB dll to launch.</summary>
        public static void SendData(Program ProgramCur, Patient pat)
        {
            string path = Programs.GetProgramPath(ProgramCur);

            if (pat == null)
            {
                MessageBox.Show("Please select a patient first.");
                return;
            }
            //js This was originally added on 9/2/09, probably due to race affecting ceph proportions.  But since we can't find any documentation, and since a customer is complaining, we are removing it for now.  If we add it back, we will document exactly why.
            //if(pat.Race==PatientRace.Unknown) {
            //  MessageBox.Show("Race must be entered first.");
            //  return;
            //}
            //Make sure the program is running
            if (Process.GetProcessesByName("DrCeph").Length == 0)
            {
                try{
                    ODFileUtils.ProcessStart(path);
                }
                catch {
                    MsgBox.Show("DrCeph", "Program path not set properly.");
                    return;
                }
                Thread.Sleep(TimeSpan.FromSeconds(4));
            }
            List <ProgramProperty> ForProgram = ProgramProperties.GetForProgram(ProgramCur.ProgramNum);;
            ProgramProperty        PPCur      = ProgramProperties.GetCur(ForProgram, "Enter 0 to use PatientNum, or 1 to use ChartNum");;
            string patID = "";

            if (PPCur.PropertyValue == "0")
            {
                patID = pat.PatNum.ToString();
            }
            else
            {
                patID = pat.ChartNumber;
            }
            try{
                PatientRaceOld   raceOld     = PatientRaces.GetPatientRaceOldFromPatientRaces(pat.PatNum);
                List <RefAttach> referalList = RefAttaches.Refresh(pat.PatNum);
                Provider         prov        = Providers.GetProv(Patients.GetProvNum(pat));
                string           provName    = prov.FName + " " + prov.MI + " " + prov.LName + " " + prov.Suffix;
                Family           fam         = Patients.GetFamily(pat.PatNum);
                Patient          guar        = fam.ListPats[0];
                string           relat       = "";
                if (guar.PatNum == pat.PatNum)
                {
                    relat = "Self";
                }
                else if (guar.Gender == PatientGender.Male && pat.Position == PatientPosition.Child)
                {
                    relat = "Father";
                }
                else if (guar.Gender == PatientGender.Female && pat.Position == PatientPosition.Child)
                {
                    relat = "Mother";
                }
                else
                {
                    relat = "Unknown";
                }
                VBbridges.DrCephNew.Launch(patID, pat.FName, pat.MiddleI, pat.LName, pat.Address, pat.Address2, pat.City,
                                           pat.State, pat.Zip, pat.HmPhone, pat.SSN, pat.Gender.ToString(), raceOld.ToString(), "", pat.Birthdate.ToString(),
                                           DateTime.Today.ToShortDateString(), RefAttachL.GetReferringDr(referalList), provName,
                                           guar.GetNameFL(), guar.Address, guar.Address2, guar.City, guar.State, guar.Zip, guar.HmPhone, relat);
            }
            catch {
                MessageBox.Show("DrCeph not responding.  It might not be installed properly.");
            }
        }
        private void butRun_Click(object sender, EventArgs e)
        {
            this.textLog.Text = "";
            string outFile = ODFileUtils.CombinePaths(textEligibilityFolder.Text, textEligibilityFile.Text);

            if (File.Exists(outFile))
            {
                if (MessageBox.Show("The file at " + outFile + " already exists. Overwrite?", "Overwrite File?",
                                    MessageBoxButtons.YesNo) != DialogResult.Yes)
                {
                    return;
                }
            }
            string outputText                   = "";
            string patientsIdNumberStr          = "SPID#";
            string householdGrossIncomeStr      = "Household Gross Income";
            string householdPercentOfPovertyStr = "Household % of Poverty";
            string statusStr = "Eligibility Status";
            string command   = "";

            //Locate the payment definition number for copayments of patients using the Arizona Primary Care program.
            command = "SELECT DefNum FROM definition WHERE Category=" + POut.Long((int)DefCat.PaymentTypes) + " AND IsHidden=0 AND LOWER(TRIM(ItemName))='noah'";
            DataTable copayDefNumTab = Reports.GetTable(command);

            if (copayDefNumTab.Rows.Count != 1)
            {
                MessageBox.Show("You must define exactly one payment type with the name 'NOAH' before running this report. " +
                                "This payment type must be used on payments made by Arizona Primary Care patients.");
                return;
            }
            long copayDefNum = PIn.Long(copayDefNumTab.Rows[0][0].ToString());

            //Get the list of all Arizona Primary Care patients, based on the patients which have an insurance carrier named 'noah'
            command = "SELECT DISTINCT p.PatNum FROM patplan pp,inssub,insplan i,patient p,carrier c " +
                      "WHERE p.PatNum=pp.PatNum AND inssub.InsSubNum=pp.InsSubNum AND inssub.PlanNum=i.PlanNum AND i.CarrierNum=c.CarrierNum " +
                      "AND LOWER(TRIM(c.CarrierName))='noah' AND " +
                      "(SELECT MAX(a.AptDateTime) FROM appointment a WHERE a.PatNum=p.PatNum AND a.AptStatus=" + ((int)ApptStatus.Complete) + ") BETWEEN " +
                      POut.Date(dateTimeFrom.Value) + " AND " + POut.Date(dateTimeTo.Value);
            DataTable primaryCarePatients = Reports.GetTable(command);

            for (int i = 0; i < primaryCarePatients.Rows.Count; i++)
            {
                string patNum = POut.Long(PIn.Long(primaryCarePatients.Rows[i][0].ToString()));
                command = "SELECT " +
                          "TRIM((SELECT f.FieldValue FROM patfield f WHERE f.PatNum=p.PatNum AND " +
                          "LOWER(f.FieldName)=LOWER('" + patientsIdNumberStr + "') " + DbHelper.LimitAnd(1) + ")) PCIN, " +             //Patient's Care ID Number
                          "TRIM((" + DbHelper.LimitOrderBy("SELECT cl.Description FROM appointment ap,clinic cl WHERE ap.PatNum=" + patNum + " AND " +
                                                           "ap.AptStatus=" + ((int)ApptStatus.Complete) + " AND ap.ClinicNum=cl.ClinicNum ORDER BY ap.AptDateTime DESC", 1) + ")) SiteIDNumber," +
                          "p.BirthDate," +
                          "CASE p.Position WHEN " + ((int)PatientPosition.Single) + " THEN 1 " +
                          "WHEN " + ((int)PatientPosition.Married) + " THEN 2 ELSE 3 END MaritalStatus," +                                                                                                              //Marital status
                                                                                                                                                                                                                        //"CASE p.Race WHEN "+((int)PatientRaceOld.Asian)+" THEN 'A' WHEN "+((int)PatientRaceOld.HispanicLatino)+" THEN 'H' "+
                                                                                                                                                                                                                        //  "WHEN "+((int)PatientRaceOld.HawaiiOrPacIsland)+" THEN 'P' WHEN "+((int)PatientRaceOld.AfricanAmerican)+" THEN 'B' "+
                                                                                                                                                                                                                        //  "WHEN "+((int)PatientRaceOld.AmericanIndian)+" THEN 'I' WHEN "+((int)PatientRaceOld.White)+" THEN 'W' ELSE 'O' END PatRace,"+
                          "CONCAT(CONCAT(TRIM(p.Address),' '),TRIM(p.Address2)) HouseholdAddress," +                                                                                                                    //Patient address
                          "p.City HouseholdCity," +                                                                                                                                                                     //Household residence city
                          "p.State HouseholdState," +                                                                                                                                                                   //Household residence state
                          "p.Zip HouseholdZip," +                                                                                                                                                                       //Household residence zip code
                          "TRIM((SELECT f.FieldValue FROM patfield f WHERE f.PatNum=p.PatNum AND " +
                          "LOWER(f.FieldName)=LOWER('" + householdGrossIncomeStr + "') " + DbHelper.LimitAnd(1) + ")) HGI, " +                                                                                          //Household gross income
                          "TRIM((SELECT f.FieldValue FROM patfield f WHERE f.PatNum=p.PatNum AND " +
                          "LOWER(f.FieldName)=LOWER('" + householdPercentOfPovertyStr + "') " + DbHelper.LimitAnd(1) + ")) HPP, " +                                                                                     //Household % of poverty
                          "(" + DbHelper.LimitOrderBy("SELECT a.AdjAmt FROM adjustment a WHERE a.PatNum=" + patNum + " AND a.AdjType=" +
                                                      copayDefNum + " ORDER BY AdjDate DESC", 1) + ") HSFS," +                                                                                                          //Household sliding fee scale
                          "(SELECT i.DateEffective FROM insplan i,inssub,patplan pp WHERE pp.PatNum=" + patNum + " AND inssub.InsSubNum=pp.InsSubNum AND inssub.PlanNum=i.PlanNum " + DbHelper.LimitAnd(1) + ") DES," + //Date of eligibility status
                          "TRIM((SELECT f.FieldValue FROM patfield f WHERE f.PatNum=p.PatNum AND " +
                          "LOWER(f.FieldName)=LOWER('" + statusStr + "') " + DbHelper.LimitAnd(1) + ")) CareStatus " +                                                                                                  //Status
                          "FROM patient p WHERE " +
                          "p.PatNum=" + patNum;
                DataTable primaryCareReportRow = Reports.GetTable(command);
                if (primaryCareReportRow.Rows.Count != 1)
                {
                    //Either the results are ambiguous or for some reason, the patient number listed in the patfield table
                    //does not actually exist. In either of these cases, it makes the most sense to just skip this patient
                    //and continue with the rest of the reporting.
                    continue;
                }
                string outputRow   = "";
                string rowErrors   = "";
                string rowWarnings = "";
                string pcin        = PIn.String(primaryCareReportRow.Rows[0]["PCIN"].ToString());
                if (pcin.Length < 9)
                {
                    rowErrors += "ERROR: Incorrectly formatted patient data for patient with patnum " + patNum +
                                 ". Patient ID Number '" + pcin + "' is not at least 9 characters long." + Environment.NewLine;
                }
                outputRow += pcin.PadLeft(15, '0');             //Patient's ID Number
                string siteId = primaryCareReportRow.Rows[0]["SiteIDNumber"].ToString();
                if (siteId == "null")
                {
                    siteId = "";
                }
                if (!Regex.IsMatch(siteId, "^.*_[0-9]{5}$"))
                {
                    rowErrors += "ERROR: The clinic description for the clinic associated with the last completed appointment " +
                                 "for the patient with a patnum of " + patNum + " must be the clinic name, follwed by a '_', followed by the 5-digit Site ID Number " +
                                 "for the clinic. i.e. ClinicName_12345. The current clinic description is '" + siteId + "'." + Environment.NewLine;
                }
                else
                {
                    siteId = siteId.Substring(siteId.Length - 5);
                }
                outputRow += siteId;
                outputRow += PIn.Date(primaryCareReportRow.Rows[0]["Birthdate"].ToString()).ToString("MMddyyyy");              //Patient's Date of Birth
                outputRow += POut.Long(PIn.Long(primaryCareReportRow.Rows[0]["MaritalStatus"].ToString()));
                //outputRow+=primaryCareReportRow.Rows[0]["PatRace"].ToString();
                //Gets the old patient race enum based on the PatientRace entries in the db and displays the corresponding letters.
                switch (PatientRaces.GetPatientRaceOldFromPatientRaces(PIn.Long(patNum)))
                {
                case PatientRaceOld.Asian:
                    outputRow += 'A';
                    break;

                case PatientRaceOld.HispanicLatino:
                    outputRow += 'H';
                    break;

                case PatientRaceOld.HawaiiOrPacIsland:
                    outputRow += 'P';
                    break;

                case PatientRaceOld.AfricanAmerican:
                    outputRow += 'B';
                    break;

                case PatientRaceOld.AmericanIndian:
                    outputRow += 'I';
                    break;

                case PatientRaceOld.White:
                    outputRow += 'W';
                    break;

                default:
                    outputRow += 'O';
                    break;
                }
                //Household residence address
                string householdAddress = POut.String(PIn.String(primaryCareReportRow.Rows[0]["HouseholdAddress"].ToString()));
                if (householdAddress.Length > 29)
                {
                    string newHouseholdAddress = householdAddress.Substring(0, 29);
                    rowWarnings += "WARNING: Address for patient with patnum of " + patNum + " was longer than 29 characters and " +
                                   "was truncated in the report ouput. Address was changed from '" +
                                   householdAddress + "' to '" + newHouseholdAddress + "'" + Environment.NewLine;
                    householdAddress = newHouseholdAddress;
                }
                outputRow += householdAddress.PadRight(29, ' ');
                //Household residence city
                string householdCity = POut.String(PIn.String(primaryCareReportRow.Rows[0]["HouseholdCity"].ToString()));
                if (householdCity.Length > 15)
                {
                    string newHouseholdCity = householdCity.Substring(0, 15);
                    rowWarnings += "WARNING: City name for patient with patnum of " + patNum + " was longer than 15 characters and " +
                                   "was truncated in the report ouput. City name was changed from '" +
                                   householdCity + "' to '" + newHouseholdCity + "'" + Environment.NewLine;
                    householdCity = newHouseholdCity;
                }
                outputRow += householdCity.PadRight(15, ' ');
                //Household residence state
                string householdState = POut.String(PIn.String(primaryCareReportRow.Rows[0]["HouseholdState"].ToString()));
                if (householdState.Length > 2)
                {
                    string newHouseholdState = householdState.Substring(0, 2);
                    rowWarnings += "WARNING: State abbreviation for patient with patnum of " + patNum + " was longer than 2 characters and " +
                                   "was truncated in the report ouput. State abbreviation was changed from '" +
                                   householdState + "' to '" + newHouseholdState + "'" + Environment.NewLine;
                    householdState = newHouseholdState;
                }
                outputRow += householdState.PadRight(2, ' ');
                //Household residence zip code
                string householdZip = POut.String(PIn.String(primaryCareReportRow.Rows[0]["HouseholdZip"].ToString()));
                if (householdZip.Length > 5)
                {
                    string newHouseholdZip = householdZip.Substring(0, 5);
                    rowWarnings += "WARNING: The zipcode for patient with patnum of " + patNum + " was longer than 5 characters and " +
                                   "was truncated in the report ouput. The zipcode was changed from '" +
                                   householdZip + "' to '" + newHouseholdZip + "'" + Environment.NewLine;
                    householdZip = newHouseholdZip;
                }
                outputRow += householdZip.PadRight(5, ' ');
                //Household gross income
                string householdGrossIncome = POut.String(PIn.String(primaryCareReportRow.Rows[0]["HGI"].ToString()));
                if (householdGrossIncome == "" || householdGrossIncome == "null")
                {
                    householdGrossIncome = "0";
                }
                //Remove any character that is not a digit or a decimal.
                string newHouseholdGrossIncome = Math.Round(Convert.ToDouble(Regex.Replace(householdGrossIncome, "[^0-9\\.]", "")), 0).ToString();
                if (householdGrossIncome != newHouseholdGrossIncome)
                {
                    rowWarnings += "WARNING: The household gross income for patient with patnum " + patNum + " contained invalid characters " +
                                   "and was changed in the output report from '" + householdGrossIncome + "' to '" + newHouseholdGrossIncome + "'." + Environment.NewLine;
                }
                householdGrossIncome = newHouseholdGrossIncome.PadLeft(7, '0');
                if (householdGrossIncome.Length > 7)
                {
                    rowErrors += "ERROR: Abnormally large household gross income of '" + householdGrossIncome +
                                 "' for patient with patnum of " + patNum + "." + Environment.NewLine;
                }
                outputRow += householdGrossIncome;
                //Household percent of poverty
                string householdPercentPoverty = POut.String(PIn.String(primaryCareReportRow.Rows[0]["HPP"].ToString()));
                if (householdPercentPoverty == "" || householdPercentPoverty == "null")
                {
                    householdPercentPoverty = "0";
                }
                string newHouseholdPercentPoverty = Regex.Replace(householdPercentPoverty, "[^0-9]", "");            //Remove anything that is not a digit.
                if (newHouseholdPercentPoverty != householdPercentPoverty)
                {
                    rowWarnings += "WARNING: Household percent poverty for the patient with a patnum of " + patNum +
                                   " had to be modified in the output report from '" + householdPercentPoverty + "' to '" + newHouseholdPercentPoverty +
                                   "' based on output requirements." + Environment.NewLine;
                }
                householdPercentPoverty = newHouseholdPercentPoverty.PadLeft(3, '0');
                if (householdPercentPoverty.Length > 3 || Convert.ToInt16(householdPercentPoverty) > 200)
                {
                    rowErrors += "ERROR: Household percent poverty must be between 0 and 200 percent, but is set to '" +
                                 householdPercentPoverty + "' for the patient with the patnum of " + patNum + Environment.NewLine;
                }
                outputRow += householdPercentPoverty;
                string householdSlidingFeeScale = POut.String(PIn.String(primaryCareReportRow.Rows[0]["HSFS"].ToString()));
                if (householdSlidingFeeScale.Length == 0)
                {
                    householdSlidingFeeScale = "0";
                }
                string newHouseholdSlidingFeeScale = Regex.Replace(householdSlidingFeeScale, "[^0-9]", "");
                if (newHouseholdSlidingFeeScale != householdSlidingFeeScale)
                {
                    rowWarnings += "WARNING: The household sliding fee scale (latest NOAH copay amount) for the patient with a patnum of " + patNum +
                                   " contains invalid characters and was changed from '" + householdSlidingFeeScale + "' to '" + newHouseholdSlidingFeeScale + "'." + Environment.NewLine;
                    householdSlidingFeeScale = newHouseholdSlidingFeeScale;
                }
                if (householdSlidingFeeScale.Length > 3 || Convert.ToInt16(householdSlidingFeeScale) > 100)
                {
                    rowWarnings += "WARNING: The household sliding fee scale (latest NOAH copay amount) for the patient with a patnum of " + patNum +
                                   " is '" + householdSlidingFeeScale + "', but will be reported as 100." + Environment.NewLine;
                    householdSlidingFeeScale = "100";
                }
                outputRow += householdSlidingFeeScale.PadLeft(3, '0');
                string   dateOfEligibilityStatusStr = primaryCareReportRow.Rows[0]["DES"].ToString();
                DateTime dateOfEligibilityStatus    = DateTime.MinValue;
                if (dateOfEligibilityStatusStr != "" && dateOfEligibilityStatusStr != "null")
                {
                    dateOfEligibilityStatus = PIn.Date(dateOfEligibilityStatusStr);
                }
                outputRow += dateOfEligibilityStatus.ToString("MMddyyyy");
                //Primary care status
                string primaryCareStatus = POut.String(PIn.String(primaryCareReportRow.Rows[0]["CareStatus"].ToString())).ToUpper();
                if (primaryCareStatus != "A" && primaryCareStatus != "B" && primaryCareStatus != "C" && primaryCareStatus != "D")
                {
                    rowErrors += "ERROR: The primary care status of the patient with a patnum of " + patNum + " is set to '" + primaryCareStatus +
                                 "', but must be set to A, B, C or D. " + Environment.NewLine;
                }
                outputRow    += primaryCareStatus;
                textLog.Text += rowErrors + rowWarnings;
                if (rowErrors.Length > 0)
                {
                    continue;
                }
                outputText += outputRow + Environment.NewLine;            //Only add the row to the output file if it is properly formatted.
            }
            File.WriteAllText(outFile, outputText);
            MessageBox.Show("Done.");
        }
Exemplo n.º 8
0
        public static void ProcessMessage(MessageHL7 message, bool isVerboseLogging)
        {
            SegmentHL7 seg      = message.GetSegment(SegmentNameHL7.PID, true);
            long       patNum   = PIn.Long(seg.GetFieldFullText(2));
            Patient    pat      = Patients.GetPat(patNum);
            Patient    patOld   = null;
            bool       isNewPat = pat == null;

            if (isNewPat)
            {
                pat             = new Patient();
                pat.PatNum      = patNum;
                pat.Guarantor   = patNum;
                pat.PriProv     = PrefC.GetLong(PrefName.PracticeDefaultProv);
                pat.BillingType = PrefC.GetLong(PrefName.PracticeDefaultBillType);
            }
            else
            {
                patOld = pat.Copy();
            }
            List <PatientRace> listPatRaces = new List <PatientRace>();

            EcwSegmentPID.ProcessPID(pat, seg, false, listPatRaces);         //IsStandalone=false because should never make it this far.
            //PV1-patient visit---------------------------
            //seg=message.GetSegment(SegmentName.PV1,false);
            //if(seg!=null) {
            //	SegmentPID.ProcessPV1(pat,seg);
            //}
            //SCH- Schedule Activity Information
            seg = message.GetSegment(SegmentNameHL7.SCH, true);
            //The documentation is wrong.  SCH.01 is not the appointment ID, but is instead a sequence# (always 1)
            long        aptNum   = PIn.Long(seg.GetFieldFullText(2));
            Appointment apt      = Appointments.GetOneApt(aptNum);
            Appointment aptOld   = null;
            bool        isNewApt = apt == null;

            if (isNewApt)
            {
                apt           = new Appointment();
                apt.AptNum    = aptNum;
                apt.PatNum    = pat.PatNum;
                apt.AptStatus = ApptStatus.Scheduled;
            }
            else
            {
                aptOld = apt.Copy();
            }
            if (apt.PatNum != pat.PatNum)
            {
                EventLog.WriteEntry("OpenDentHL7", "Appointment does not match patient: " + pat.FName + " " + pat.LName
                                    + ", apt.PatNum:" + apt.PatNum.ToString() + ", pat.PatNum:" + pat.PatNum.ToString()
                                    , EventLogEntryType.Error);
                return;                //we can't process this message because wrong patnum.
            }
            apt.Note = seg.GetFieldFullText(7);
            //apt.Pattern=ProcessDuration(seg.GetFieldFullText(9));
            //9 and 10 are not actually available, in spite of the documentation.
            //11-We need start time and stop time
            apt.AptDateTime = DateTimeParse(seg.GetFieldComponent(11, 3));
            DateTime stopTime = DateTimeParse(seg.GetFieldComponent(11, 4));

            apt.Pattern = ProcessPattern(apt.AptDateTime, stopTime);
            apt.ProvNum = pat.PriProv;          //just in case there's not AIG segment.
            //AIG is optional, but looks like the only way to get provider for the appt-----------
            //PV1 seems to frequently be sent instead of AIG.
            SegmentHL7 segAIG = message.GetSegment(SegmentNameHL7.AIG, false);
            SegmentHL7 segPV  = message.GetSegment(SegmentNameHL7.PV1, false);

            if (segAIG != null)
            {
                long provNum = EcwSegmentPID.ProvProcess(segAIG.GetField(3));
                if (provNum != 0)
                {
                    apt.ProvNum = provNum;
                    pat.PriProv = provNum;
                }
            }
            else if (segPV != null)
            {
                long provNum = EcwSegmentPID.ProvProcess(segPV.GetField(7));
                if (provNum != 0)
                {
                    apt.ProvNum = provNum;
                    pat.PriProv = provNum;
                }
            }
            //AIL,AIP seem to be optional, and I'm going to ignore them for now.
            if (pat.FName == "" || pat.LName == "")
            {
                EventLog.WriteEntry("OpenDentHL7", "Appointment not processed due to missing patient first or last name. PatNum:" + pat.PatNum.ToString()
                                    , EventLogEntryType.Information);
                return;                //this will also skip the appt insert.
            }
            if (isNewPat)
            {
                if (isVerboseLogging)
                {
                    EventLog.WriteEntry("OpenDentHL7", "Inserted patient: " + pat.FName + " " + pat.LName + ", PatNum:" + pat.PatNum.ToString()
                                        , EventLogEntryType.Information);
                }
                Patients.Insert(pat, true);
                SecurityLogs.MakeLogEntry(Permissions.PatientCreate, pat.PatNum, "Created from HL7 for eCW.", LogSources.HL7);
            }
            else
            {
                if (isVerboseLogging)
                {
                    EventLog.WriteEntry("OpenDentHL7", "Updated patient: " + pat.FName + " " + pat.LName, EventLogEntryType.Information);
                }
                Patients.Update(pat, patOld);
            }
            //had to move this reconcile here since we might not have a PatNum for new patients until after the insert
            PatientRaces.Reconcile(pat.PatNum, listPatRaces);
            if (isNewApt)
            {
                if (isVerboseLogging)
                {
                    EventLog.WriteEntry("OpenDentHL7", "Inserted appointment for: " + pat.FName + " " + pat.LName, EventLogEntryType.Information);
                }
                Appointments.InsertIncludeAptNum(apt, true);
            }
            else
            {
                if (isVerboseLogging)
                {
                    EventLog.WriteEntry("OpenDentHL7", "Updated appointment for: " + pat.FName + " " + pat.LName, EventLogEntryType.Information);
                }
                Appointments.Update(apt, aptOld);
            }
        }
Exemplo n.º 9
0
        public static void ProcessMessage(MessageHL7 message, bool isStandalone, bool isVerboseLogging)
        {
            /*string triggerevent=message.Segments[0].GetFieldComponent(8,1);
             * switch(triggerevent) {
             *      case "A01"://Admit/Visit Information
             *
             *              break;
             *      case "A04"://New Patient Information
             *              ProcessNewPatient(message);
             *              break;
             *      case "A08"://Update Patient Information
             *
             *              break;
             *      case "A28"://Add Patient Information
             *
             *              break;
             *      case "A31"://Update Patient Information
             *
             *              break;
             * }*/
            //MSH-Ignore
            //EVN-Ignore
            //PID-------------------------------------
            SegmentHL7 seg    = message.GetSegment(SegmentNameHL7.PID, true);
            long       patNum = PIn.Long(seg.GetFieldFullText(2));
            Patient    pat    = null;

            if (isStandalone)
            {
                pat = Patients.GetPatByChartNumber(patNum.ToString());
                if (pat == null)
                {
                    //try to find the patient in question by using name and birthdate
                    string   lName        = seg.GetFieldComponent(5, 0);
                    string   fName        = seg.GetFieldComponent(5, 1);
                    DateTime birthdate    = EcwSegmentPID.DateParse(seg.GetFieldFullText(7));
                    long     patNumByName = Patients.GetPatNumByNameAndBirthday(lName, fName, birthdate);
                    if (patNumByName == 0)                   //patient does not exist in OD
                    //so pat will still be null, triggering creation of new patient further down.
                    {
                    }
                    else
                    {
                        pat             = Patients.GetPat(patNumByName);
                        pat.ChartNumber = patNum.ToString();                      //from now on, we will be able to find pat by chartNumber
                    }
                }
            }
            else
            {
                pat = Patients.GetPat(patNum);
            }
            Patient patOld   = null;
            bool    isNewPat = pat == null;

            if (isNewPat)
            {
                pat = new Patient();
                if (isStandalone)
                {
                    pat.ChartNumber = patNum.ToString();
                    //this line does not work if isStandalone, so moved to end
                    //pat.Guarantor=patNum;
                }
                else
                {
                    pat.PatNum    = patNum;
                    pat.Guarantor = patNum;
                }
                pat.PriProv     = PrefC.GetLong(PrefName.PracticeDefaultProv);
                pat.BillingType = PrefC.GetLong(PrefName.PracticeDefaultBillType);
            }
            else
            {
                patOld = pat.Copy();
            }
            List <PatientRace> listPatRaces = new List <PatientRace>();
            bool hasNoRaceInStandalone      = (isStandalone && (pat == null || pat.PatNum == 0));

            EcwSegmentPID.ProcessPID(pat, seg, isStandalone, listPatRaces);
            //PV1-patient visit---------------------------
            //seg=message.GetSegment(SegmentName.PV1,false);
            //if(seg!=null) {//this seg is optional
            //	SegmentPID.ProcessPV1(pat,seg);
            //}
            //PD1-additional patient demographics------------
            //seg=message.GetSegment(SegmentName.PD1,false);
            //if(seg!=null) {//this seg is optional
            //	ProcessPD1(pat,seg);
            //}
            //GT1-Guarantor-------------------------------------
            seg = message.GetSegment(SegmentNameHL7.GT1, true);
            EcwSegmentPID.ProcessGT1(pat, seg, isStandalone);
            //IN1-Insurance-------------------------------------
            //List<SegmentHL7> segments=message.GetSegments(SegmentName.IN1);
            //for(int i=0;i<segments.Count;i++) {
            //	ProcessIN1(pat,seg);
            //}
            if (pat.FName == "" || pat.LName == "")
            {
                EventLog.WriteEntry("OpenDentHL7", "Patient demographics not processed due to missing first or last name. PatNum:" + pat.PatNum.ToString()
                                    , EventLogEntryType.Information);
                return;
            }
            if (isNewPat)
            {
                if (isVerboseLogging)
                {
                    EventLog.WriteEntry("OpenDentHL7", "Inserted patient: " + pat.FName + " " + pat.LName, EventLogEntryType.Information);
                }
                pat.PatNum = Patients.Insert(pat, !isStandalone);             //use existing PK if not standalone, standalone will have PatNum=0, so set PatNum here
                SecurityLogs.MakeLogEntry(Permissions.PatientCreate, pat.PatNum, "Created from HL7 for eCW.", LogSources.HL7);
                if (hasNoRaceInStandalone)
                {
                    Patient patientRaceTemp = pat.Copy();                  //Make a deep copy so that we do not accidentally override something.
                    seg = message.GetSegment(SegmentNameHL7.PID, true);
                    //We have to process the PID again in order to correct the patient race.  Patient race(s) will automatically get inserted if needed.
                    EcwSegmentPID.ProcessPID(patientRaceTemp, seg, isStandalone, listPatRaces);
                }
                if (pat.Guarantor == 0)
                {
                    patOld        = pat.Copy();
                    pat.Guarantor = pat.PatNum;
                    Patients.Update(pat, patOld);
                }
            }
            else
            {
                if (isVerboseLogging)
                {
                    EventLog.WriteEntry("OpenDentHL7", "Updated patient: " + pat.FName + " " + pat.LName, EventLogEntryType.Information);
                }
                Patients.Update(pat, patOld);
            }
            //had to move this reconcile here since we might not have a PatNum for new patients until after the insert
            PatientRaces.Reconcile(pat.PatNum, listPatRaces);
        }
Exemplo n.º 10
0
        //public static void ProcessPD1() {
        //	return;
        //}

        public static void ProcessPID(Patient pat, HL7DefSegment segDef, SegmentHL7 seg)
        {
            for (int i = 0; i < segDef.hl7DefFields.Count; i++)
            {
                int itemOrder = segDef.hl7DefFields[i].OrdinalPos;
                switch (segDef.hl7DefFields[i].FieldName)
                {
                case "pat.addressCityStateZip":
                    pat.Address  = seg.GetFieldComponent(itemOrder, 0);
                    pat.Address2 = seg.GetFieldComponent(itemOrder, 1);
                    pat.City     = seg.GetFieldComponent(itemOrder, 2);
                    pat.State    = seg.GetFieldComponent(itemOrder, 3);
                    pat.Zip      = seg.GetFieldComponent(itemOrder, 4);
                    continue;

                case "pat.birthdateTime":
                    pat.Birthdate = FieldParser.DateTimeParse(seg.GetFieldComponent(itemOrder));
                    continue;

                case "pat.ChartNumber":
                    pat.ChartNumber = seg.GetFieldComponent(itemOrder);
                    continue;

                case "pat.Gender":
                    pat.Gender = FieldParser.GenderParse(seg.GetFieldComponent(itemOrder));
                    continue;

                case "pat.HmPhone":
                    pat.HmPhone = FieldParser.PhoneParse(seg.GetFieldComponent(itemOrder));
                    continue;

                case "pat.nameLFM":
                    pat.LName   = seg.GetFieldComponent(itemOrder, 0);
                    pat.FName   = seg.GetFieldComponent(itemOrder, 1);
                    pat.MiddleI = seg.GetFieldComponent(itemOrder, 2);
                    continue;

                case "pat.PatNum":
                    if (pat.PatNum != 0 && pat.PatNum != PIn.Long(seg.GetFieldComponent(itemOrder)))
                    {
                        throw new Exception("Invalid PatNum");
                    }
                    continue;

                case "pat.Position":
                    pat.Position = FieldParser.MaritalStatusParse(seg.GetFieldComponent(itemOrder));
                    continue;

                case "pat.Race":
                    PatientRaceOld patientRaceOld = FieldParser.RaceParse(seg.GetFieldComponent(itemOrder));
                    //Converts deprecated PatientRaceOld enum to list of PatRaces, and adds them to the PatientRaces table for the patient.
                    PatientRaces.Reconcile(pat.PatNum, PatientRaces.GetPatRacesFromPatientRaceOld(patientRaceOld));
                    continue;

                case "pat.SSN":
                    pat.SSN = seg.GetFieldComponent(itemOrder);
                    continue;

                case "pat.WkPhone":
                    pat.WkPhone = FieldParser.PhoneParse(seg.GetFieldComponent(itemOrder));
                    continue;

                case "pat.FeeSched":
                    if (Programs.IsEnabled(ProgramName.eClinicalWorks) && ProgramProperties.GetPropVal(ProgramName.eClinicalWorks, "FeeSchedulesSetManually") == "1")
                    {
                        //if using eCW and FeeSchedulesSetManually
                        continue;                                //do not process fee sched field, manually set by user
                    }
                    else
                    {
                        pat.FeeSched = FieldParser.FeeScheduleParse(seg.GetFieldComponent(itemOrder));
                    }
                    continue;

                default:
                    continue;
                }
            }
            return;
        }