private void ButUpdateProvs_Click(object sender, EventArgs e) { if (IsNew) { MsgBox.Show(this, "Not for new operatories."); return; } //Check against cache. Instead of saving changes, make them get out and reopen. Safer and simpler. Operatory op = Operatories.GetOperatory(OpCur.OperatoryNum); if (op.OpName != textOpName.Text || op.Abbrev != textAbbrev.Text || op.IsHidden != checkIsHidden.Checked || op.ClinicNum != comboClinic.SelectedClinicNum || op.ProvDentist != comboProv.GetSelectedProvNum() || op.ProvHygienist != comboHyg.GetSelectedProvNum() || op.IsHygiene != checkIsHygiene.Checked || op.SetProspective != checkSetProspective.Checked || op.IsWebSched != checkIsWebSched.Checked) { MsgBox.Show(this, "Changes were detected above. Save all changes, get completely out of the operatories window, and then re-enter."); return; } if (!Security.IsAuthorized(Permissions.Setup) || !Security.IsAuthorized(Permissions.AppointmentEdit)) { return; } //Operatory operatory=Operatories.GetOperatory(contrApptPanel.OpNumClicked); if (Security.CurUser.ClinicIsRestricted && !Clinics.GetForUserod(Security.CurUser).Exists(x => x.ClinicNum == OpCur.ClinicNum)) { MsgBox.Show(this, "You are restricted from accessing the clinic belonging to the selected operatory. No changes will be made."); return; } if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "WARNING: We recommend backing up your database before running this tool. " + "This tool may take a very long time to run and should be run after hours. " + "In addition, this tool could potentially change hundreds of appointments. " + "The changes made by this tool can only be manually reversed. " + "Are you sure you want to continue?")) { return; } SecurityLogs.MakeLogEntry(Permissions.Setup, 0, Lan.g(this, "Update Provs on Future Appts tool run on operatory ") + OpCur.Abbrev + "."); List <Appointment> listAppts = Appointments.GetAppointmentsForOpsByPeriod(new List <long>() { OpCur.OperatoryNum }, DateTime.Now); //no end date, so all future List <Appointment> listApptsOld = new List <Appointment>(); foreach (Appointment appt in listAppts) { listApptsOld.Add(appt.Copy()); } ContrApptRef.MoveAppointments(listAppts, listApptsOld, OpCur); MsgBox.Show(this, "Done"); }
///<summary>When looking at a daily appointment module and the current appointment view is has 'OnlyScheduleProvs' turned on, this method will dynamically add additional operatories to visOps for providers that are scheduled to work.</summary> public static void AddOpsForScheduledProvs(bool isWeekly, List <Schedule> dailySched, ApptView apptViewCur, ref List <Operatory> visOps) { //if this appt view has the option to show only scheduled providers and this is daily view. //Remember that there is no intelligence in weekly view for this option, and it behaves just like it always did. if (ApptViews.IsNoneView(apptViewCur) || dailySched == null || visOps == null || !apptViewCur.OnlyScheduledProvs || isWeekly) { return; } //intelligently decide what ops to show. It's based on the schedule for the day. //visOps will be totally empty right now because it looped out of the above section of code. List <long> listSchedOps; bool opAdded; int indexOp; List <Operatory> listOpsShort = Operatories.GetDeepCopy(true); List <long> listApptViewOpNums = ApptViewItems.GetOpsForView(apptViewCur.ApptViewNum); for (int i = 0; i < listOpsShort.Count; i++) //loop through all ops for all views (except the hidden ones, of course) //If this operatory was not one of the selected Ops from the Appt View Edit window, skip it. { if (!listApptViewOpNums.Contains(listOpsShort[i].OperatoryNum)) { continue; } //find any applicable sched for the op opAdded = false; for (int s = 0; s < dailySched.Count; s++) { if (dailySched[s].SchedType != ScheduleType.Provider) { continue; } if (dailySched[s].StartTime == new TimeSpan(0)) //skip if block starts at midnight. { continue; } if (dailySched[s].StartTime == dailySched[s].StopTime) //skip if block has no length. { continue; } if (apptViewCur.OnlySchedAfterTime > new TimeSpan(0, 0, 0)) { if (dailySched[s].StartTime < apptViewCur.OnlySchedAfterTime || dailySched[s].StopTime < apptViewCur.OnlySchedAfterTime) { continue; } } if (apptViewCur.OnlySchedBeforeTime > new TimeSpan(0, 0, 0)) { if (dailySched[s].StartTime > apptViewCur.OnlySchedBeforeTime || dailySched[s].StopTime > apptViewCur.OnlySchedBeforeTime) { continue; } } //this 'sched' must apply to this situation. //listSchedOps is the ops for this 'sched'. listSchedOps = dailySched[s].Ops; //Add all the ops for this 'sched' to the list of visible ops for (int p = 0; p < listSchedOps.Count; p++) { //Filter the ops if the clinic option was set for the appt view. if (apptViewCur.ClinicNum > 0 && apptViewCur.ClinicNum != Operatories.GetOperatory(listSchedOps[p]).ClinicNum) { continue; } if (listSchedOps[p] == listOpsShort[i].OperatoryNum) { Operatory op = listOpsShort[i]; indexOp = Operatories.GetOrder(listSchedOps[p]); if (indexOp != -1 && !visOps.Contains(op)) //prevents adding duplicate ops { visOps.Add(op); opAdded = true; break; } } } //If the provider is not scheduled to any op(s), add their default op(s). if (listOpsShort[i].ProvDentist == dailySched[s].ProvNum && listSchedOps.Count == 0) //only if the sched does not specify any ops //Only add the op if the clinic option was not set in the appt view or if the op is assigned to that clinic. { if (apptViewCur.ClinicNum == 0 || apptViewCur.ClinicNum == listOpsShort[i].ClinicNum) { indexOp = Operatories.GetOrder(listOpsShort[i].OperatoryNum); if (indexOp != -1 && !visOps.Contains(listOpsShort[i])) { visOps.Add(listOpsShort[i]); opAdded = true; } } } if (opAdded) { break; //break out of the loop of schedules. Continue with the next op. } } } //Remove any duplicates before return. visOps = visOps.GroupBy(x => x.OperatoryNum).Select(x => x.First()).ToList(); }
///<summary>Offers to use unscheduled appt. Shows ApptEdit window. Sets Prospective, if necessary. Fires Automation triggers. ListAptNumsSelected will contain the AptNum of the new appointment.</summary> public void MakeAppointment() { //Check to see if the patient has any unscheduled appointments and inform the user. List <Appointment> listUnschedAppts = Appointments.GetUnschedApptsForPat(_patCur.PatNum); //Per Nathan, pinboard appointments will not be considered unscheduled for this logic. listUnschedAppts.RemoveAll(x => x.AptNum.In(_listPinboardApptNums)); FormApptEdit formApptEdit = null; long aptNum = 0; bool isSchedulingUnscheduled = false; if (listUnschedAppts.Count > 0 && MsgBox.Show(this, MsgBoxButtons.YesNo, "This patient has an unscheduled appointment, would you like to use an existing unscheduled appointment?")) { if (listUnschedAppts.Count == 1) { aptNum = listUnschedAppts[0].AptNum; } else //Multiple unscheduled appointments, let the user pick which one to use. { FormUnschedListPatient formUnschedListPatient = new FormUnschedListPatient(_patCur); if (formUnschedListPatient.ShowDialog() != DialogResult.OK) { return; } //Use the appointment the user selected. aptNum = formUnschedListPatient.SelectedAppt.AptNum; } isSchedulingUnscheduled = true; } formApptEdit = new FormApptEdit(aptNum, patNum: _patCur.PatNum, useApptDrawingSettings: IsInitialDoubleClick, patient: _patCur, dateTNew: DateTNew, opNumNew: OpNumNew); formApptEdit.IsNew = (aptNum == 0); formApptEdit.IsSchedulingUnscheduledAppt = isSchedulingUnscheduled; formApptEdit.ShowDialog(); if (formApptEdit.DialogResult != DialogResult.OK) { return; } Appointment aptCur = formApptEdit.GetAppointmentCur(); if (IsInitialDoubleClick) { if (isSchedulingUnscheduled) //User double clicked in Appointment Module, intending to schedule appointment at a specific time/op/etc. { Appointment aptOld = aptCur.Copy(); aptCur.AptDateTime = DateTimeClicked; aptCur.Op = OpNumClicked; if (_patCur != null && _patCur.AskToArriveEarly > 0) { aptCur.DateTimeAskedToArrive = aptCur.AptDateTime.AddMinutes(-_patCur.AskToArriveEarly); } aptCur = Appointments.AssignFieldsForOperatory(aptCur); aptCur.AptStatus = ApptStatus.Scheduled; Appointments.Update(aptCur, aptOld); } //Change PatStatus to Prospective or from Prospective. Operatory opCur = Operatories.GetOperatory(aptCur.Op); if (opCur != null) { if (opCur.SetProspective && _patCur.PatStatus != PatientStatus.Prospective) //Don't need to prompt if patient is already prospective. { if (MsgBox.Show(this, MsgBoxButtons.OKCancel, "Patient's status will be set to Prospective.")) { Patient patOld = _patCur.Copy(); _patCur.PatStatus = PatientStatus.Prospective; Patients.Update(_patCur, patOld); } } else if (!opCur.SetProspective && _patCur.PatStatus == PatientStatus.Prospective) { if (MsgBox.Show(this, MsgBoxButtons.OKCancel, "Patient's status will change from Prospective to Patient.")) { Patient patOld = _patCur.Copy(); _patCur.PatStatus = PatientStatus.Patient; Patients.Update(_patCur, patOld); } } } } ListAptNumsSelected.Add(aptCur.AptNum); if (IsInitialDoubleClick) { _otherResult = OtherResult.CreateNew; } else { _otherResult = OtherResult.NewToPinBoard; } if (aptCur.IsNewPatient) { AutomationL.Trigger(AutomationTrigger.CreateApptNewPat, null, aptCur.PatNum, aptCur.AptNum); } AutomationL.Trigger(AutomationTrigger.CreateAppt, null, aptCur.PatNum, aptCur.AptNum); DialogResult = DialogResult.OK; }
private void butNew_Click(object sender, System.EventArgs e) { Appointment AptCur = new Appointment(); AptCur.PatNum = PatCur.PatNum; if (PatCur.DateFirstVisit.Year < 1880 && !Procedures.AreAnyComplete(PatCur.PatNum)) //this only runs if firstVisit blank { AptCur.IsNewPatient = true; } AptCur.Pattern = "/X/"; if (PatCur.PriProv == 0) { AptCur.ProvNum = PIn.PInt(((Pref)PrefB.HList["PracticeDefaultProv"]).ValueString); } else { AptCur.ProvNum = PatCur.PriProv; } AptCur.ProvHyg = PatCur.SecProv; AptCur.AptStatus = ApptStatus.Scheduled; AptCur.ClinicNum = PatCur.ClinicNum; if (InitialClick) //initially double clicked on appt module { DateTime d; if (ContrApptSheet.IsWeeklyView) { d = ContrAppt.WeekStartDate.AddDays(ContrAppt.SheetClickedonDay); } else { d = Appointments.DateSelected; } int minutes = (int)(ContrAppt.SheetClickedonMin / ContrApptSheet.MinPerIncr) * ContrApptSheet.MinPerIncr; AptCur.AptDateTime = new DateTime(d.Year, d.Month, d.Day , ContrAppt.SheetClickedonHour, minutes, 0); AptCur.Op = ContrAppt.SheetClickedonOp; Operatory curOp = Operatories.GetOperatory(AptCur.Op); if (curOp.ProvDentist != 0) { AptCur.ProvNum = curOp.ProvDentist; } AptCur.ProvHyg = curOp.ProvHygienist; AptCur.IsHygiene = curOp.IsHygiene; AptCur.ClinicNum = curOp.ClinicNum; try { Appointments.InsertOrUpdate(AptCur, null, true); } catch (ApplicationException ex) { MessageBox.Show(ex.Message); } } else { //new appt will be placed on pinboard instead of specific time } try{ Appointments.InsertOrUpdate(AptCur, null, true); } catch (ApplicationException ex) { MessageBox.Show(ex.Message); return; } FormApptEdit FormApptEdit2 = new FormApptEdit(AptCur.AptNum); FormApptEdit2.IsNew = true; FormApptEdit2.ShowDialog(); if (FormApptEdit2.DialogResult != DialogResult.OK) { return; } AptSelected = AptCur.AptNum; if (InitialClick) { oResult = OtherResult.CreateNew; } else { oResult = OtherResult.NewToPinBoard; } DialogResult = DialogResult.OK; }
///<summary>Gets (list)ForCurView, ApptDrawing.VisOps, ApptDrawing.VisProvs, and ApptRows. Also sets TwoRows. Works even if supply -1 to indicate no apptview is selected. Pass in null for the dailySched if this is a weekly view or if in FormApptViewEdit.</summary> public static void GetForCurView(ApptView av, bool isWeekly, List <Schedule> dailySched) { ApptViewCur = av; ForCurView = new List <ApptViewItem>(); ApptDrawing.VisProvs = new List <Provider>(); ApptDrawing.VisOps = new List <Operatory>(); ApptRows = new List <ApptViewItem>(); int index; //If there are no appointment views set up (therefore, none selected), then use a hard-coded default view. if (ApptViewCur == null) { //MessageBox.Show("apptcategorynum:"+ApptCategories.Cur.ApptCategoryNum.ToString()); //make visible ops exactly the same as the short ops list (all except hidden) for (int i = 0; i < OperatoryC.ListShort.Count; i++) { ApptDrawing.VisOps.Add(OperatoryC.ListShort[i]); } //make visible provs exactly the same as the prov list (all except hidden) for (int i = 0; i < ProviderC.ListShort.Count; i++) { ApptDrawing.VisProvs.Add(ProviderC.ListShort[i]); } //Hard coded elements showing ApptRows.Add(new ApptViewItem("PatientName", 0, Color.Black)); ApptRows.Add(new ApptViewItem("ASAP", 1, Color.DarkRed)); ApptRows.Add(new ApptViewItem("MedUrgNote", 2, Color.DarkRed)); ApptRows.Add(new ApptViewItem("PremedFlag", 3, Color.DarkRed)); ApptRows.Add(new ApptViewItem("Lab", 4, Color.DarkRed)); ApptRows.Add(new ApptViewItem("Procs", 5, Color.Black)); ApptRows.Add(new ApptViewItem("Note", 6, Color.Black)); ApptDrawing.RowsPerIncr = 1; } //An appointment view is selected, so add provs and ops from the view to our lists of indexes. else { for (int i = 0; i < ApptViewItemC.List.Length; i++) { if (ApptViewItemC.List[i].ApptViewNum == ApptViewCur.ApptViewNum) { ForCurView.Add(ApptViewItemC.List[i]); if (ApptViewItemC.List[i].OpNum > 0) //op { if (ApptViewCur.OnlyScheduledProvs && !isWeekly) { continue; //handled below } index = Operatories.GetOrder(ApptViewItemC.List[i].OpNum); if (index != -1) { ApptDrawing.VisOps.Add(OperatoryC.ListShort[index]); } } else if (ApptViewItemC.List[i].ProvNum > 0) //prov { index = Providers.GetIndex(ApptViewItemC.List[i].ProvNum); if (index != -1) { ApptDrawing.VisProvs.Add(ProviderC.ListShort[index]); } } else //element or apptfielddef { ApptRows.Add(ApptViewItemC.List[i]); } } } ApptDrawing.RowsPerIncr = ApptViewCur.RowsPerIncr; } //if this appt view has the option to show only scheduled providers and this is daily view. //Remember that there is no intelligence in weekly view for this option, and it behaves just like it always did. if (ApptViewCur != null && ApptViewCur.OnlyScheduledProvs && !isWeekly) { //intelligently decide what ops to show. It's based on the schedule for the day. //VisOps will be totally empty right now because it looped out of the above section of code. List <long> listSchedOps; bool opAdded; int indexOp; for (int i = 0; i < OperatoryC.ListShort.Count; i++) //loop through all ops for all views (except the hidden ones, of course) //find any applicable sched for the op { opAdded = false; for (int s = 0; s < dailySched.Count; s++) { if (dailySched[s].SchedType != ScheduleType.Provider) { continue; } if (dailySched[s].StartTime == new TimeSpan(0)) //skip if block starts at midnight. { continue; } if (dailySched[s].StartTime == dailySched[s].StopTime) //skip if block has no length. { continue; } if (ApptViewCur.OnlySchedAfterTime > new TimeSpan(0, 0, 0)) { if (dailySched[s].StartTime < ApptViewCur.OnlySchedAfterTime || dailySched[s].StopTime < ApptViewCur.OnlySchedAfterTime) { continue; } } if (ApptViewCur.OnlySchedBeforeTime > new TimeSpan(0, 0, 0)) { if (dailySched[s].StartTime > ApptViewCur.OnlySchedBeforeTime || dailySched[s].StopTime > ApptViewCur.OnlySchedBeforeTime) { continue; } } //this 'sched' must apply to this situation. //listSchedOps is the ops for this 'sched'. listSchedOps = dailySched[s].Ops; //Add all the ops for this 'sched' to the list of visible ops for (int p = 0; p < listSchedOps.Count; p++) { //Filter the ops if the clinic option was set for the appt view. if (ApptViewCur.ClinicNum > 0 && ApptViewCur.ClinicNum != Operatories.GetOperatory(listSchedOps[p]).ClinicNum) { continue; } if (listSchedOps[p] == OperatoryC.ListShort[i].OperatoryNum) { Operatory op = OperatoryC.ListShort[i]; indexOp = Operatories.GetOrder(listSchedOps[p]); if (indexOp != -1 && !ApptDrawing.VisOps.Contains(op)) //prevents adding duplicate ops { ApptDrawing.VisOps.Add(op); opAdded = true; break; } } } //If the provider is not scheduled to any op(s), add their default op(s). if (OperatoryC.ListShort[i].ProvDentist == dailySched[s].ProvNum && listSchedOps.Count == 0) //only if the sched does not specify any ops //Only add the op if the clinic option was not set in the appt view or if the op is assigned to that clinic. { if (ApptViewCur.ClinicNum == 0 || ApptViewCur.ClinicNum == OperatoryC.ListShort[i].ClinicNum) { indexOp = Operatories.GetOrder(OperatoryC.ListShort[i].OperatoryNum); if (indexOp != -1 && !ApptDrawing.VisOps.Contains(OperatoryC.ListShort[i])) { ApptDrawing.VisOps.Add(OperatoryC.ListShort[i]); opAdded = true; } } } if (opAdded) { break; //break out of the loop of schedules. Continue with the next op. } } } } ApptDrawing.VisOps.Sort(CompareOps); ApptDrawing.VisProvs.Sort(CompareProvs); }
private void FillGrid() { //do not refresh from db SchedList.Sort(CompareSchedule); graphScheduleDay.SetSchedules(SchedList); gridMain.BeginUpdate(); gridMain.Columns.Clear(); ODGridColumn col = new ODGridColumn(Lan.g("TableSchedDay", "Provider"), 100); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableSchedDay", "Employee"), 100); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableSchedDay", "Start Time"), 80); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableSchedDay", "Stop Time"), 80); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableSchedDay", "Ops"), 150); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableSchedDay", "Note"), 100); gridMain.Columns.Add(col); gridMain.Rows.Clear(); ODGridRow row; string note; string opdesc; //string opstr; //string[] oparray; for (int i = 0; i < SchedList.Count; i++) { row = new ODGridRow(); //Prov if (SchedList[i].ProvNum != 0) { row.Cells.Add(Providers.GetAbbr(SchedList[i].ProvNum)); } else { row.Cells.Add(""); } //Employee if (SchedList[i].EmployeeNum == 0) { row.Cells.Add(""); } else { row.Cells.Add(Employees.GetEmp(SchedList[i].EmployeeNum).FName); } //times if (SchedList[i].StartTime == TimeSpan.Zero && SchedList[i].StopTime == TimeSpan.Zero) //SchedList[i].SchedType==ScheduleType.Practice){ { row.Cells.Add(""); row.Cells.Add(""); } else { row.Cells.Add(SchedList[i].StartTime.ToShortTimeString()); row.Cells.Add(SchedList[i].StopTime.ToShortTimeString()); } //ops opdesc = ""; for (int o = 0; o < SchedList[i].Ops.Count; o++) { Operatory op = Operatories.GetOperatory(SchedList[i].Ops[o]); if (op.IsHidden) //Skip hidden operatories because it just confuses users. { continue; } if (opdesc != "") { opdesc += ","; } opdesc += op.Abbrev; } row.Cells.Add(opdesc); //note note = ""; if (SchedList[i].Status == SchedStatus.Holiday) { note += Lan.g(this, "Holiday: "); } note += SchedList[i].Note; row.Cells.Add(note); gridMain.Rows.Add(row); } gridMain.EndUpdate(); }