示例#1
0
        ///<summary>Determines if the Task is in the Clinic.</summary>
        private bool IsTaskInClinic(Task task, Clinic clinic)
        {
            bool retVal = false;

            switch (task.ObjectType)
            {
            case TaskObjectType.Appointment:
                Appointment appt = Appointments.GetOneApt(task.KeyNum);
                //Is Appointment's clinic in the same clinic as passed in clinic?
                //0 clinic also allowed.
                if (appt.ClinicNum == 0 || appt.ClinicNum == clinic.ClinicNum)
                {
                    retVal = true;
                }
                break;

            case TaskObjectType.Patient:
                Patient pat = Patients.GetPat(task.KeyNum);
                if (pat.ClinicNum == 0 || pat.ClinicNum == clinic.ClinicNum)
                {
                    retVal = true;
                }
                break;

            case TaskObjectType.None:
                retVal = true;
                break;
            }
            return(retVal);
        }
示例#2
0
        ///<summary>The other overload should be called when the action is Deleted so that the appt's fields will be recorded.</summary>
        public static void CreateHistoryEntry(long apptNum, HistAppointmentAction action)
        {
            //No need for additional DB check when appt was already deleted.
            Appointment appt = (action == HistAppointmentAction.Deleted?null:Appointments.GetOneApt(apptNum));

            CreateHistoryEntry(appt, action, apptNum);
        }
示例#3
0
 ///<summary></summary>
 protected override void Dispose(bool disposing)
 {
     if (disposing)            //managed resources
     {
         components?.Dispose();
         //get rid of temp appts on pinboard. =jordan I don't see any docs on why this is here. Doesn't seem quite right, but it works.
         for (int i = 0; i < ListPinBoardItems.Count; i++)
         {
             if (PIn.Int(ListPinBoardItems[i].DataRowAppt["AptStatus"].ToString()) != (int)ApptStatus.UnschedList)
             {
                 continue;
             }
             if (PIn.DateT(ListPinBoardItems[i].DataRowAppt["AptDateTime"].ToString()).Year > 1880)
             {
                 continue;
             }
             Appointment appt = null;
             try{
                 appt = Appointments.GetOneApt(ListPinBoardItems[i].AptNum);
             }
             catch {
                 break;                        //db connection no longer present.
             }
             if (appt == null)
             {
                 continue;
             }
             if (appt.AptDateTime.Year > 1880)                   //date was updated since put on the pinboard
             {
                 continue;
             }
             Appointments.Delete(appt.AptNum, true);
             if (Security.CurUser == null)                  // E.g. clicking Log Off invalidates the user.
             {
                 continue;
             }
             //Make a security log if we still have a valid user logged in.
             string logText = Lan.g(this, "Deleted from pinboard while closing Open Dental") + ": ";
             if (appt.AptDateTime.Year > 1880)
             {
                 logText += appt.AptDateTime.ToString() + ", ";
             }
             logText += appt.ProcDescript;
             SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit, appt.PatNum, logText);
         }
     }
     base.Dispose(disposing);
 }
示例#4
0
        ///<summary>Gets the data necessary from the database to run the appointment search logic.</summary>
        public static ApptSearchData GetDataForSearch(long aptNum, DateTime dateAfter, DateTime dateBefore, List <long> listProvNums, List <long> listOpNums
                                                      , List <long> listClinicNums, long blockoutType)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <ApptSearchData>(MethodBase.GetCurrentMethod(), aptNum, dateAfter, dateBefore, listProvNums, listOpNums, listClinicNums
                                                       , blockoutType));
            }
            ApptSearchData data = new ApptSearchData();

            data.DateEvaluating   = dateAfter.AddDays(1);
            data.AppointmentToAdd = Appointments.GetOneApt(aptNum);
            data.ListSchedules    = Schedules.GetSchedulesForAppointmentSearch(data.DateEvaluating, dateBefore, listClinicNums, listOpNums
                                                                               , listProvNums, blockoutType);
            //Get all appointments that exist in the operaotries we will be searching to find an opening, not just for provider we're looking for
            //so we can get conflicts when multiple provs work in a single operaotry.
            data.ListAppointments = Appointments.GetForPeriodList(data.DateEvaluating, dateBefore, listOpNums, listClinicNums);
            data.ListSchedOps     = ScheduleOps.GetForSchedList(data.ListSchedules, listOpNums);     //ops filter for case when a prov is scheduled in multiple ops
            return(data);
        }
示例#5
0
        public static void ProcessPV1(Patient pat, long aptNum, HL7DefSegment segDef, SegmentHL7 seg)
        {
            long provNum;
            int  provNumOrder = 0;

            for (int i = 0; i < segDef.hl7DefFields.Count; i++)
            {
                if (segDef.hl7DefFields[i].FieldName == "prov.provIdName" || segDef.hl7DefFields[i].FieldName == "prov.provIdNameLFM")
                {
                    provNumOrder = segDef.hl7DefFields[i].OrdinalPos;
                    break;
                }
            }
            if (provNumOrder == 0)           //No provIdName or provIdNameLFM field in this segment definition so do nothing with it
            {
                return;
            }
            provNum = FieldParser.ProvProcess(seg.Fields[provNumOrder]);
            if (provNum == 0)           //This segment didn't have a valid provider id in it to locate the provider (must have been blank) so do nothing
            {
                return;
            }
            Appointment apt = Appointments.GetOneApt(aptNum); //SCH segment was found and aptNum was retrieved, if no SCH segment for this message then 0

            if (apt == null)                                  //Just in case we can't find an apt with the aptNum from SCH segment
            {
                return;
            }
            Appointment aptOld = apt.Clone();
            Patient     patOld = pat.Copy();

            apt.ProvNum = provNum;
            pat.PriProv = provNum;
            Appointments.Update(apt, aptOld);
            Patients.Update(pat, patOld);
            return;
        }
示例#6
0
        ///<summary>Update Appointment.Confirmed. Returns true if update was allowed. Returns false if it was prevented.</summary>
        public static bool UpdateAppointmentConfirmationStatus(long aptNum, long confirmDefNum, string commaListOfExcludedDefNums)
        {
            Appointment aptCur = Appointments.GetOneApt(aptNum);

            if (aptCur == null)
            {
                return(false);
            }
            List <long> preventChangeFrom = commaListOfExcludedDefNums.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(long.Parse).ToList();

            if (preventChangeFrom.Contains(aptCur.Confirmed))              //This appointment is in a confirmation state that can no longer be updated.
            {
                return(false);
            }
            //Keep the update small.
            Appointment aptOld = aptCur.Copy();

            aptCur.Confirmed = confirmDefNum;
            Appointments.Update(aptCur, aptOld);           //Appointments S-Class handles Signalods
            SecurityLogs.MakeLogEntry(Permissions.ApptConfirmStatusEdit, aptCur.PatNum, "Appointment confirmation status changed from "
                                      + Defs.GetName(DefCat.ApptConfirmed, aptOld.Confirmed) + " to " + Defs.GetName(DefCat.ApptConfirmed, aptCur.Confirmed)
                                      + " due to an eConfirmation.", aptCur.AptNum, LogSources.AutoConfirmations, aptOld.DateTStamp);
            return(true);
        }
示例#7
0
        ///<summary>Determines if the Task is in the Clinic's region.</summary>
        private bool IsTaskInRegionAndUnrestricted(Task task, Userod user)
        {
            bool        retVal             = false;
            Clinic      clinic             = Clinics.GetClinic(user.ClinicNum);
            List <long> listUserClinicNums = Clinics.GetAllForUserod(user).Select(x => x.ClinicNum).ToList();

            switch (task.ObjectType)
            {
            case TaskObjectType.Appointment:
                Appointment appt       = Appointments.GetOneApt(task.KeyNum);
                Clinic      clinicAppt = Clinics.GetClinic(appt.ClinicNum);
                //Is Appointment's clinic in the same region as passed in clinic, and user has permission to view the clinicAppt?
                //0 Region also allowed.
                if (clinicAppt.Region == 0 || (clinicAppt.Region == clinic.Region && listUserClinicNums.Any(x => x == clinicAppt.ClinicNum)))
                {
                    retVal = true;
                }
                break;

            case TaskObjectType.Patient:
                Patient pat       = Patients.GetPat(task.KeyNum);
                Clinic  clinicPat = Clinics.GetClinic(pat.ClinicNum);
                //Is Appointment's clinic in the same region as passed in clinic, and user has permission to view the clinicPat?
                //0 Region also allowed.
                if (clinicPat.Region == 0 || (clinicPat.Region == clinic.Region && listUserClinicNums.Any(x => x == clinicPat.ClinicNum)))
                {
                    retVal = true;
                }
                break;

            case TaskObjectType.None:
                retVal = true;
                break;
            }
            return(retVal);
        }
示例#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);
            }
        }
示例#9
0
        ///<summary>Returns AptNum of the incoming appointment.</summary>
        public static long ProcessSCH(Patient pat, HL7DefSegment segDef, SegmentHL7 seg)
        {
            string   aptNote   = "";
            double   aptLength = 0;
            long     aptNum    = 0;
            DateTime aptStart  = DateTime.MinValue;
            DateTime aptStop   = DateTime.MinValue;

            for (int i = 0; i < segDef.hl7DefFields.Count; i++)
            {
                int ordinalPos = segDef.hl7DefFields[i].OrdinalPos;
                switch (segDef.hl7DefFields[i].FieldName)
                {
                case "apt.AptNum":
                    aptNum = PIn.Long(seg.GetFieldComponent(ordinalPos));
                    continue;

                case "apt.lengthStartEnd":
                    aptLength = FieldParser.SecondsToMinutes(seg.GetFieldComponent(ordinalPos, 2));
                    aptStart  = FieldParser.DateTimeParse(seg.GetFieldComponent(ordinalPos, 3));
                    aptStop   = FieldParser.DateTimeParse(seg.GetFieldComponent(ordinalPos, 4));
                    continue;

                case "apt.Note":
                    aptNote = seg.GetFieldComponent(ordinalPos);
                    continue;

                default:
                    continue;
                }
            }
            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.Clone();
            }
            if (apt.PatNum != pat.PatNum)           //we can't process this message because wrong patnum.
            {
                throw new Exception("Appointment does not match patient: " + pat.FName + " " + pat.LName + ", apt.PatNum: " + apt.PatNum.ToString() + ", pat.PatNum: " + pat.PatNum.ToString());
            }
            apt.Note = aptNote;
            string pattern;

            //If aptStop is MinValue we know that stop time was not sent or was not in the correct format so try to use the duration field.
            if (aptStop == DateTime.MinValue && aptLength != 0)         //Stop time is optional.  If not included we will use the duration field to calculate pattern.
            {
                pattern = FieldParser.ProcessPattern(aptStart, aptStart.AddMinutes(aptLength));
            }
            else              //We received a good stop time or stop time is MinValue but we don't have a good aptLength so ProcessPattern will return the apt length or the default 5 minutes
            {
                pattern = FieldParser.ProcessPattern(aptStart, aptStop);
            }
            apt.AptDateTime = aptStart;
            apt.Pattern     = pattern;
            apt.ProvNum     = pat.PriProv;      //Set apt.ProvNum to the patient's primary provider.  This may change after processing the AIG or PV1 segments, but set here in case those segs are missing.
            if (pat.FName == "" || pat.LName == "")
            {
                throw new Exception("Appointment not processed due to missing patient first or last name. PatNum:" + pat.PatNum.ToString());
            }
            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);
            }
            HL7MsgCur.AptNum = apt.AptNum;
            HL7Msgs.Update(HL7MsgCur);
            return(aptNum);
        }
示例#10
0
        void menuItemProv_Click(object sender, EventArgs e)
        {
            Appointment apt = Appointments.GetOneApt(ListPinBoardItems[SelectedIndex].AptNum);

            if (apt == null)
            {
                ClearAt(SelectedIndex);
                MessageBox.Show("Appointment not found.");
                return;
            }
            Appointment oldApt  = apt.Copy();
            long        provNum = apt.ProvNum;

            if (apt.IsHygiene)
            {
                provNum = apt.ProvHyg;
            }
            FormProviderPick formPick = new FormProviderPick();

            formPick.SelectedProvNum = provNum;
            formPick.ShowDialog();
            if (formPick.DialogResult != DialogResult.OK)
            {
                return;
            }
            if (formPick.SelectedProvNum == provNum)
            {
                return;                //provider not changed.
            }
            if (apt.IsHygiene)
            {
                apt.ProvHyg = formPick.SelectedProvNum;
            }
            else
            {
                apt.ProvNum = formPick.SelectedProvNum;
            }
            #region Provider Term Date Check
            //Prevents appointments with providers that are past their term end date from being scheduled
            //Allows for unscheduled appointments to skip the check as it will check when they go to schedule.
            if (apt.AptStatus != ApptStatus.UnschedList)
            {
                string message = Providers.CheckApptProvidersTermDates(apt);
                if (message != "")
                {
                    MessageBox.Show(this, message);                   //translated in Providers S class method
                    return;
                }
            }
            #endregion Provider Term Date Check
            List <Procedure> procsForSingleApt = Procedures.GetProcsForSingle(apt.AptNum, false);
            if (MsgBox.Show(this, MsgBoxButtons.YesNo, "Change length for new provider?"))
            {
                List <long> codeNums = new List <long>();
                for (int p = 0; p < procsForSingleApt.Count; p++)
                {
                    codeNums.Add(procsForSingleApt[p].CodeNum);
                }
                string calcPattern = Appointments.CalculatePattern(apt.ProvNum, apt.ProvHyg, codeNums, true);
                if (apt.Pattern != calcPattern)
                {
                    if (!apt.TimeLocked || MsgBox.Show(this, MsgBoxButtons.YesNo, "Appointment length is locked.  Change length for new provider anyway?"))
                    {
                        apt.Pattern = calcPattern;
                    }
                }
            }
            Appointments.Update(apt, oldApt);
            ProcFeeHelper    procFeeHelper  = new ProcFeeHelper(apt.PatNum);
            bool             isUpdatingFees = false;
            List <Procedure> listProcsNew   = procsForSingleApt.Select(x => Procedures.UpdateProcInAppointment(apt, x.Copy())).ToList();
            if (procsForSingleApt.Exists(x => x.ProvNum != listProcsNew.FirstOrDefault(y => y.ProcNum == x.ProcNum).ProvNum))         //Either the primary or hygienist changed.
            {
                string promptText = "";
                isUpdatingFees = Procedures.ShouldFeesChange(listProcsNew, procsForSingleApt, ref promptText, procFeeHelper);
                if (isUpdatingFees)                 //Made it pass the pref check.
                {
                    if (promptText != "" && !MsgBox.Show(this, MsgBoxButtons.YesNo, promptText))
                    {
                        isUpdatingFees = false;
                    }
                }
            }
            Procedures.SetProvidersInAppointment(apt, procsForSingleApt, isUpdatingFees, procFeeHelper);
            OnModuleNeedsRefresh();
            //this will also trigger ContrAppt to send a new appt to the pinboard.
        }
示例#11
0
        ///<summary>Returns null if there is no DFT defined for the enabled HL7Def.</summary>
        public static MessageHL7 GenerateDFT(List <Procedure> procList, EventTypeHL7 eventType, Patient pat, Patient guar, long aptNum, string pdfDescription, string pdfDataString)   //add event (A04 etc) parameters later if needed
        //In \\SERVERFILES\storage\OPEN DENTAL\Programmers Documents\Standards (X12, ADA, etc)\HL7\Version2.6\V26_CH02_Control_M4_JAN2007.doc
        //On page 28, there is a Message Construction Pseudocode as well as a flowchart which might help.
        {
            Provider    prov       = Providers.GetProv(Patients.GetProvNum(pat));
            Appointment apt        = Appointments.GetOneApt(aptNum);
            MessageHL7  messageHL7 = new MessageHL7(MessageTypeHL7.DFT);
            HL7Def      hl7Def     = HL7Defs.GetOneDeepEnabled();

            if (hl7Def == null)
            {
                return(null);
            }
            //find a DFT message in the def
            HL7DefMessage hl7DefMessage = null;

            for (int i = 0; i < hl7Def.hl7DefMessages.Count; i++)
            {
                if (hl7Def.hl7DefMessages[i].MessageType == MessageTypeHL7.DFT)
                {
                    hl7DefMessage = hl7Def.hl7DefMessages[i];
                    //continue;
                    break;
                }
            }
            if (hl7DefMessage == null)           //DFT message type is not defined so do nothing and return
            {
                return(null);
            }
            for (int s = 0; s < hl7DefMessage.hl7DefSegments.Count; s++)
            {
                int countRepeat = 1;
                if (hl7DefMessage.hl7DefSegments[s].SegmentName == SegmentNameHL7.FT1)
                {
                    countRepeat = procList.Count;
                }
                //for example, countRepeat can be zero in the case where we are only sending a PDF of the TP to eCW, and no procs.
                for (int repeat = 0; repeat < countRepeat; repeat++)           //FT1 is optional and can repeat so add as many FT1's as procs in procList
                //if(hl7DefMessage.hl7DefSegments[s].SegmentName==SegmentNameHL7.FT1) {
                {
                    if (hl7DefMessage.hl7DefSegments[s].SegmentName == SegmentNameHL7.FT1 && procList.Count > repeat)
                    {
                        prov = Providers.GetProv(procList[repeat].ProvNum);
                    }
                    SegmentHL7 seg = new SegmentHL7(hl7DefMessage.hl7DefSegments[s].SegmentName);
                    seg.SetField(0, hl7DefMessage.hl7DefSegments[s].SegmentName.ToString());
                    for (int f = 0; f < hl7DefMessage.hl7DefSegments[s].hl7DefFields.Count; f++)
                    {
                        string fieldName = hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].FieldName;
                        if (fieldName == "")                       //If fixed text instead of field name just add text to segment
                        {
                            seg.SetField(hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].OrdinalPos, hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].FixedText);
                        }
                        else
                        {
                            //seg.SetField(hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].OrdinalPos,
                            //FieldConstructor.GenerateDFT(hl7Def,fieldName,pat,prov,procList[repeat],guar,apt,repeat+1,eventType,pdfDescription,pdfDataString));
                            Procedure proc = null;
                            if (procList.Count > repeat)                           //procList could be an empty list
                            {
                                proc = procList[repeat];
                            }
                            seg.SetField(hl7DefMessage.hl7DefSegments[s].hl7DefFields[f].OrdinalPos,
                                         FieldConstructor.GenerateDFT(hl7Def, fieldName, pat, prov, proc, guar, apt, repeat + 1, eventType, pdfDescription, pdfDataString));
                        }
                    }
                    messageHL7.Segments.Add(seg);
                }
            }
            return(messageHL7);
        }
示例#12
0
        ///<summary>Returns null if there is no HL7Def enabled or if there is no outbound DFT defined for the enabled HL7Def.</summary>
        public static MessageHL7 GenerateDFT(List <Procedure> listProcs, EventTypeHL7 eventType, Patient pat, Patient guar, long aptNum, string pdfDescription, string pdfDataString)
        {
            //In \\SERVERFILES\storage\OPEN DENTAL\Programmers Documents\Standards (X12, ADA, etc)\HL7\Version2.6\V26_CH02_Control_M4_JAN2007.doc
            //On page 28, there is a Message Construction Pseudocode as well as a flowchart which might help.
            MessageHL7 msgHl7 = new MessageHL7(MessageTypeHL7.DFT);
            HL7Def     hl7Def = HL7Defs.GetOneDeepEnabled();

            if (hl7Def == null)
            {
                return(null);
            }
            //find a DFT message in the def
            HL7DefMessage hl7DefMessage = null;

            for (int i = 0; i < hl7Def.hl7DefMessages.Count; i++)
            {
                if (hl7Def.hl7DefMessages[i].MessageType == MessageTypeHL7.DFT && hl7Def.hl7DefMessages[i].InOrOut == InOutHL7.Outgoing)
                {
                    hl7DefMessage = hl7Def.hl7DefMessages[i];
                    //continue;
                    break;
                }
            }
            if (hl7DefMessage == null)           //DFT message type is not defined so do nothing and return
            {
                return(null);
            }
            if (PrefC.GetBool(PrefName.ShowFeaturePatientClone))
            {
                pat = Patients.GetOriginalPatientForClone(pat);
            }
            Provider       prov         = Providers.GetProv(Patients.GetProvNum(pat));
            Appointment    apt          = Appointments.GetOneApt(aptNum);
            List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum);

            for (int i = 0; i < hl7DefMessage.hl7DefSegments.Count; i++)
            {
                int repeatCount = 1;
                if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.FT1)
                {
                    repeatCount = listProcs.Count;
                }
                else if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1)
                {
                    repeatCount = listPatPlans.Count;
                }
                //for example, countRepeat can be zero in the case where we are only sending a PDF of the TP to eCW, and no procs.
                //or the patient does not have any current insplans for IN1 segments
                for (int j = 0; j < repeatCount; j++)           //FT1 is optional and can repeat so add as many FT1's as procs in procList, IN1 is optional and can repeat as well, repeat for the number of patplans in patplanList
                {
                    if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.FT1 && listProcs.Count > j)
                    {
                        prov = Providers.GetProv(listProcs[j].ProvNum);
                    }
                    Procedure proc = null;
                    if (listProcs.Count > j)                   //procList could be an empty list
                    {
                        proc = listProcs[j];
                    }
                    PatPlan patPlanCur = null;
                    InsPlan insPlanCur = null;
                    InsSub  insSubCur  = null;
                    Carrier carrierCur = null;
                    Patient subscriber = null;
                    if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1)
                    {
                        patPlanCur = listPatPlans[j];
                        insSubCur  = InsSubs.GetOne(patPlanCur.InsSubNum);
                        insPlanCur = InsPlans.RefreshOne(insSubCur.PlanNum);
                        carrierCur = Carriers.GetCarrier(insPlanCur.CarrierNum);
                        subscriber = Patients.GetPat(insSubCur.Subscriber);
                    }
                    SegmentHL7 seg = new SegmentHL7(hl7DefMessage.hl7DefSegments[i].SegmentName);
                    seg.SetField(0, hl7DefMessage.hl7DefSegments[i].SegmentName.ToString());
                    for (int f = 0; f < hl7DefMessage.hl7DefSegments[i].hl7DefFields.Count; f++)
                    {
                        string fieldName = hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].FieldName;
                        if (fieldName == "")                       //If fixed text instead of field name just add text to segment
                        {
                            seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].OrdinalPos, hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].FixedText);
                        }
                        else
                        {
                            string fieldValue = "";
                            if (hl7DefMessage.hl7DefSegments[i].SegmentName == SegmentNameHL7.IN1)
                            {
                                fieldValue = FieldConstructor.GenerateFieldIN1(hl7Def, fieldName, j + 1, patPlanCur, insSubCur, insPlanCur, carrierCur, listPatPlans.Count, subscriber);
                            }
                            else
                            {
                                fieldValue = FieldConstructor.GenerateField(hl7Def, fieldName, MessageTypeHL7.DFT, pat, prov, proc, guar, apt, j + 1, eventType,
                                                                            pdfDescription, pdfDataString, MessageStructureHL7.DFT_P03, seg.Name);
                            }
                            seg.SetField(hl7DefMessage.hl7DefSegments[i].hl7DefFields[f].OrdinalPos, fieldValue);
                        }
                    }
                    msgHl7.Segments.Add(seg);
                }
            }
            return(msgHl7);
        }
示例#13
0
        ///<summary>Calculates the time available to verify based on a variety of patient and appointment factors.
        ///Looks at Appointment date, appointment creation date, last verification date, next scheduled verification, insurance renewal
        ///</summary>
        public static InsVerify SetTimeAvailableForVerify(InsVerify insVer, PlanToVerify planType, int appointmentScheduledDays, int insBenefitEligibilityDays,
                                                          int patientEnrollmentDays)
        {
            //DateAppointmentScheduled-DateAppointmentCreated
            DateTime dateTimeLatestApptScheduling;
            //DateAppointmentScheduled-appointmentScheduledDays (default is 7)
            DateTime dateTimeUntilAppt;
            //DateTime the appointment takes place.
            DateTime dateTimeAppointment;
            //DateTime the patient was scheduled to be re-verified
            DateTime dateTimeScheduledReVerify;
            //DateTime verification last took place.  Will be 01/01/0001 if verification has never happened.
            DateTime dateTimeLastVerified;
            //DateTime the insurance renewal month rolls over.
            //The month the renewal takes place is stored in the database.  If the month is 0, then it is actually january.
            //It is the first day of the given month at midnight, or (Month#)/01/(year) @ 00:00AM.
            //Set to max val by default in case the PrefName.InsVerifyFutureDateBenefitYear=false.
            //Since max val is later in time than the appointment time, it will be ignored.
            DateTime dateBenifitRenewalNeeded = DateTime.MaxValue;

            #region Appointment Dates
            dateTimeAppointment = insVer.AppointmentDateTime;
            dateTimeUntilAppt   = insVer.AppointmentDateTime.AddDays(-appointmentScheduledDays);
            //Calculate when the appointment was put into it's current time slot.
            //This will be the earliest datetime where the scheduled appointment time is what it is now
            List <HistAppointment> listHistAppt = HistAppointments.GetForApt(insVer.AptNum);
            listHistAppt.RemoveAll(x => x.AptDateTime.Date != insVer.AppointmentDateTime.Date);
            listHistAppt = listHistAppt.Where(x => x.AptStatus == ApptStatus.Scheduled).OrderBy(x => x.AptDateTime).ToList();
            if (listHistAppt.Count > 0)
            {
                //If the appointment was moved to the current date after the (Apt.DateTime-appointmentScheduledDays),
                //we only had (Apt.DateTime-listHistAppt.First().HistDateTstamp) days instead of (appointmentScheduledDays)
                dateTimeLatestApptScheduling = listHistAppt.First().HistDateTStamp;
            }
            else
            {
                //Just in case there's no history for an appointment for some reason.
                //Shouldn't happen because a log entry is created when the appointment is created.
                //Use the date the appointment was created.  This is better than nothing and should never happen anyways.
                dateTimeLatestApptScheduling = Appointments.GetOneApt(insVer.AptNum).SecDateEntry;
            }
            #endregion Appointment Dates
            #region Insurance Verification
            dateTimeLastVerified = insVer.DateLastVerified;
            //Add defined number of days to date last verified to calculate when the next verification date should have started.
            if (planType == PlanToVerify.InsuranceBenefits)
            {
                if (insVer.DateLastVerified == DateTime.MinValue)               //If it's the min value, the insurance has never been verified.
                {
                    dateTimeScheduledReVerify = insVer.DateTimeEntry;
                }
                else
                {
                    dateTimeScheduledReVerify = insVer.DateLastVerified.AddDays(insBenefitEligibilityDays);
                }
            }
            else              //PlanToVerify.PatientEligibility
            {
                if (insVer.DateLastVerified == DateTime.MinValue)
                {
                    dateTimeScheduledReVerify = insVer.DateTimeEntry;
                }
                else
                {
                    dateTimeScheduledReVerify = insVer.DateLastVerified.AddDays(patientEnrollmentDays);
                }
            }
            #endregion insurance verification
            #region Benifit Renewal
            if (PrefC.GetBool(PrefName.InsVerifyFutureDateBenefitYear))
            {
                InsPlan insPlan = InsPlans.GetPlan(insVer.PlanNum, null);
                //Setup the month renew dates.  Need all 3 years in case the appointment verify window crosses over a year
                //e.g. Appt verify date: 12/30/2016 and Appt Date: 1/6/2017
                DateTime dateTimeOldestRenewal = new DateTime(DateTime.Now.Year - 1, Math.Max((byte)1, insPlan.MonthRenew), 1);
                DateTime dateTimeMiddleRenewal = new DateTime(DateTime.Now.Year, Math.Max((byte)1, insPlan.MonthRenew), 1);
                DateTime dateTimeNewestRenewal = new DateTime(DateTime.Now.Year + 1, Math.Max((byte)1, insPlan.MonthRenew), 1);
                //We want to find the date closest to the appointment date without going past it.
                if (dateTimeMiddleRenewal > dateTimeAppointment)
                {
                    dateBenifitRenewalNeeded = dateTimeOldestRenewal;
                }
                else
                {
                    if (dateTimeNewestRenewal > dateTimeAppointment)
                    {
                        dateBenifitRenewalNeeded = dateTimeMiddleRenewal;
                    }
                    else
                    {
                        dateBenifitRenewalNeeded = dateTimeNewestRenewal;
                    }
                }
            }
            #endregion Benifit Renewal
            DateTime dateTimeAbleToVerify = VerifyDateCalulation(dateTimeUntilAppt, dateTimeLatestApptScheduling, dateTimeScheduledReVerify, dateBenifitRenewalNeeded);
            insVer.HoursAvailableForVerification = insVer.AppointmentDateTime.Subtract(dateTimeAbleToVerify).TotalHours;
            return(insVer);
        }