public void LoadTemplate(string subject, string bodyText, List <EmailAttach> attachments) { List <Appointment> listApts = Appointments.GetFutureSchedApts(PatNum); Appointment aptNext = null; if (listApts.Count > 0) { aptNext = listApts[0]; //next sched appt. If none, null. } Clinic clinic = Clinics.GetClinic(ClinicNum); Subject = subject; //patient information Subject = Patients.ReplacePatient(Subject, _patCur); //Next Scheduled Appointment Information Subject = Appointments.ReplaceAppointment(Subject, aptNext); //handles null nextApts. //Currently Logged in User Information Subject = FormMessageReplacements.ReplaceUser(Subject, Security.CurUser); //Clinic Information Subject = Clinics.ReplaceOffice(Subject, clinic); //Misc Information Subject = FormMessageReplacements.ReplaceMisc(Subject); BodyText = bodyText; //patient information BodyText = Patients.ReplacePatient(BodyText, _patCur); //Next Scheduled Appointment Information BodyText = Appointments.ReplaceAppointment(BodyText, aptNext); //handles null nextApts. //Currently Logged in User Information BodyText = FormMessageReplacements.ReplaceUser(BodyText, Security.CurUser); //Clinic Information BodyText = Clinics.ReplaceOffice(BodyText, clinic); //Misc Information BodyText = FormMessageReplacements.ReplaceMisc(BodyText); _emailMessage.Attachments.AddRange(attachments); FillAttachments(); _hasMessageChanged = false; }
private void comboStatus_SelectionChangeCommitted(object sender, System.EventArgs e) { if(grid.SelectedIndices.Length==0){ return;//because user could never initiate this action. } Appointment apt; Cursor=Cursors.WaitCursor; long[] selectedApts=new long[grid.SelectedIndices.Length]; for(int i=0;i<grid.SelectedIndices.Length;i++){ selectedApts[i]=PIn.Long(Table.Rows[grid.SelectedIndices[i]]["AptNum"].ToString()); } for(int i=0;i<grid.SelectedIndices.Length;i++){ apt=Appointments.GetOneApt(PIn.Long(Table.Rows[grid.SelectedIndices[i]]["AptNum"].ToString())); Appointment aptOld=apt.Clone(); int selectedI=comboStatus.SelectedIndex; apt.Confirmed=DefC.Short[(int)DefCat.ApptConfirmed][selectedI].DefNum; try{ Appointments.Update(apt,aptOld); } catch(ApplicationException ex){ Cursor=Cursors.Default; MessageBox.Show(ex.Message); return; } } FillMain(); //reselect all the apts for(int i=0;i<Table.Rows.Count;i++){ for(int j=0;j<selectedApts.Length;j++){ if(PIn.Long(Table.Rows[i]["AptNum"].ToString())==selectedApts[j]){ grid.SetSelected(i,true); } } } SetFamilyColors(); comboStatus.SelectedIndex=-1; Cursor=Cursors.Default; }
private void menuItemGoTo_Click(object sender, EventArgs e) { if (gridMain.GetSelectedIndex() == -1) { MsgBox.Show(this, "Please select a lab case first."); return; } DataRow row = gridMain.SelectedTag <DataRow>(); if (row["AptNum"].ToString() == "0") { MsgBox.Show(this, "There are no appointments for unattached lab cases."); return; } Appointment apt = Appointments.GetOneApt(PIn.Long(row["AptNum"].ToString())); if (apt.AptStatus == ApptStatus.UnschedList) { MsgBox.Show(this, "Cannot go to an unscheduled appointment"); return; } GoToAptNum = apt.AptNum; Close(); }
private void FillGrid() { this.Cursor = Cursors.WaitCursor; string order = ""; switch (comboOrder.SelectedIndex) { case 0: order = "status"; break; case 1: order = "alph"; break; case 2: order = "date"; break; } long provNum = 0; if (comboProv.SelectedIndex != 0) { provNum = ProviderC.ListShort[comboProv.SelectedIndex - 1].ProvNum; } long siteNum = 0; if (!PrefC.GetBool(PrefName.EasyHidePublicHealth) && comboSite.SelectedIndex != 0) { siteNum = SiteC.List[comboSite.SelectedIndex - 1].SiteNum; } long clinicNum = 0; if (comboClinic.SelectedIndex > 0) { clinicNum = Clinics.List[comboClinic.SelectedIndex - 1].ClinicNum; } bool showBrokenAppts; showBrokenAppts = checkBrokenAppts.Checked; ListUn = Appointments.RefreshUnsched(order, provNum, siteNum, showBrokenAppts, clinicNum); int scrollVal = grid.ScrollValue; grid.BeginUpdate(); grid.Columns.Clear(); ODGridColumn col = new ODGridColumn(Lan.g("TableUnsched", "Patient"), 140); grid.Columns.Add(col); col = new ODGridColumn(Lan.g("TableUnsched", "Date"), 65); grid.Columns.Add(col); col = new ODGridColumn(Lan.g("TableUnsched", "Status"), 110); grid.Columns.Add(col); col = new ODGridColumn(Lan.g("TableUnsched", "Prov"), 50); grid.Columns.Add(col); col = new ODGridColumn(Lan.g("TableUnsched", "Procedures"), 150); grid.Columns.Add(col); col = new ODGridColumn(Lan.g("TableUnsched", "Notes"), 200); grid.Columns.Add(col); grid.Rows.Clear(); ODGridRow row; for (int i = 0; i < ListUn.Length; i++) { row = new ODGridRow(); row.Cells.Add(patientNames[ListUn[i].PatNum]); if (ListUn[i].AptDateTime.Year < 1880) { row.Cells.Add(""); } else { row.Cells.Add(ListUn[i].AptDateTime.ToShortDateString()); } row.Cells.Add(DefC.GetName(DefCat.RecallUnschedStatus, ListUn[i].UnschedStatus)); row.Cells.Add(Providers.GetAbbr(ListUn[i].ProvNum)); row.Cells.Add(ListUn[i].ProcDescript); row.Cells.Add(ListUn[i].Note); grid.Rows.Add(row); } grid.EndUpdate(); grid.ScrollValue = scrollVal; Cursor = Cursors.Default; }
private void FillMain() { int parent; DateTime date; if (TreeHistory.Count > 0) //not on main trunk { parent = ((TaskList)TreeHistory[TreeHistory.Count - 1]).TaskListNum; date = DateTime.MinValue; } else //one of the main trunks { parent = 0; date = cal.SelectionStart; } RefreshMainLists(parent, date); if (TreeHistory.Count == 0 && //main trunk (tabContr.SelectedIndex == 2 || tabContr.SelectedIndex == 3 || tabContr.SelectedIndex == 4)) //any of the dated groups { //clear any lists which are derived from a repeating list and which do not have any itmes checked off bool changeMade = false; for (int i = 0; i < TaskListsList.Length; i++) { if (TaskListsList[i].FromNum == 0) //ignore because not derived from a repeating list { continue; } if (!AnyAreMarkedComplete(TaskListsList[i])) { DeleteEntireList(TaskListsList[i]); changeMade = true; } } //clear any tasks which are derived from a repeating tast and which are not checked off for (int i = 0; i < TasksList.Length; i++) { if (TasksList[i].FromNum == 0) { continue; } if (!TasksList[i].TaskStatus) { Tasks.Delete(TasksList[i]); changeMade = true; } } if (changeMade) { RefreshMainLists(parent, date); } //now add back any repeating lists and tasks that meet the criteria //Get lists of all repeating lists and tasks of one type. We will pick items from these two lists. TaskList[] repeatingLists = new TaskList[0]; Task[] repeatingTasks = new Task[0]; switch (tabContr.SelectedIndex) { case 2: repeatingLists = TaskLists.Refresh(-1, DateTime.MinValue, TaskDateType.Day, true); repeatingTasks = Tasks.Refresh(-1, DateTime.MinValue, TaskDateType.Day, true); break; case 3: repeatingLists = TaskLists.Refresh(-1, DateTime.MinValue, TaskDateType.Week, true); repeatingTasks = Tasks.Refresh(-1, DateTime.MinValue, TaskDateType.Week, true); break; case 4: repeatingLists = TaskLists.Refresh(-1, DateTime.MinValue, TaskDateType.Month, true); repeatingTasks = Tasks.Refresh(-1, DateTime.MinValue, TaskDateType.Month, true); break; } //loop through list and add back any that meet criteria. changeMade = false; bool alreadyExists; for (int i = 0; i < repeatingLists.Length; i++) { //if already exists, skip alreadyExists = false; for (int j = 0; j < TaskListsList.Length; j++) //loop through Main list { if (TaskListsList[j].FromNum == repeatingLists[i].TaskListNum) { alreadyExists = true; break; } } if (alreadyExists) { continue; } //otherwise, duplicate the list repeatingLists[i].DateTL = date; repeatingLists[i].FromNum = repeatingLists[i].TaskListNum; repeatingLists[i].IsRepeating = false; repeatingLists[i].Parent = 0; repeatingLists[i].ObjectType = 0; //user will have to set explicitly DuplicateExistingList(repeatingLists[i], true); changeMade = true; } for (int i = 0; i < repeatingTasks.Length; i++) { //if already exists, skip alreadyExists = false; for (int j = 0; j < TasksList.Length; j++) //loop through Main list { if (TasksList[j].FromNum == repeatingTasks[i].TaskNum) { alreadyExists = true; break; } } if (alreadyExists) { continue; } //otherwise, duplicate the task repeatingTasks[i].DateTask = date; repeatingTasks[i].FromNum = repeatingTasks[i].TaskNum; repeatingTasks[i].IsRepeating = false; repeatingTasks[i].TaskListNum = 0; Tasks.InsertOrUpdate(repeatingTasks[i], true); changeMade = true; } if (changeMade) { RefreshMainLists(parent, date); } } //if main trunk on dated group listMain.Items.Clear(); ListViewItem item; string dateStr = ""; for (int i = 0; i < TaskListsList.Length; i++) { dateStr = ""; if (TaskListsList[i].DateTL.Year > 1880 && tabContr.SelectedIndex == 0) //main { //dateStr=TaskListsList[i].DateTL.ToShortDateString()+" - "; if (TaskListsList[i].DateType == TaskDateType.Day) { dateStr = TaskListsList[i].DateTL.ToShortDateString() + " - "; } else if (TaskListsList[i].DateType == TaskDateType.Week) { dateStr = Lan.g(this, "Week of") + " " + TaskListsList[i].DateTL.ToShortDateString() + " - "; } else if (TaskListsList[i].DateType == TaskDateType.Month) { dateStr = TaskListsList[i].DateTL.ToString("MMMM") + " - "; } } item = new ListViewItem(dateStr + TaskListsList[i].Descript, 0); item.ToolTipText = item.Text; listMain.Items.Add(item); } string objDesc = ""; for (int i = 0; i < TasksList.Length; i++) { //checked=1, unchecked=2 dateStr = ""; if (tabContr.SelectedIndex == 0) //main { if (TasksList[i].DateTask.Year > 1880) { if (TasksList[i].DateType == TaskDateType.Day) { dateStr = TasksList[i].DateTask.ToShortDateString() + " - "; } else if (TasksList[i].DateType == TaskDateType.Week) { dateStr = Lan.g(this, "Week of") + " " + TasksList[i].DateTask.ToShortDateString() + " - "; } else if (TasksList[i].DateType == TaskDateType.Month) { dateStr = TasksList[i].DateTask.ToString("MMMM") + " - "; } } else if (TasksList[i].DateTimeEntry.Year > 1880) { dateStr = TasksList[i].DateTimeEntry.ToShortDateString() + " - "; } } objDesc = ""; if (TasksList[i].ObjectType == TaskObjectType.Patient) { if (TasksList[i].KeyNum != 0) { objDesc = Patients.GetPat(TasksList[i].KeyNum).GetNameLF() + " - "; } } else if (TasksList[i].ObjectType == TaskObjectType.Appointment) { if (TasksList[i].KeyNum != 0) { Appointment AptCur = Appointments.GetOneApt(TasksList[i].KeyNum); if (AptCur != null) { objDesc = Patients.GetPat(AptCur.PatNum).GetNameLF() + " " + AptCur.AptDateTime.ToString() + " " + AptCur.ProcDescript + " " + AptCur.Note + " - "; } } } if (TasksList[i].TaskStatus) //complete { item = new ListViewItem(dateStr + objDesc + TasksList[i].Descript, 1); } else { item = new ListViewItem(dateStr + objDesc + TasksList[i].Descript, 2); } item.ToolTipText = item.Text; listMain.Items.Add(item); } }
private void Delete_Click() { if (!Security.IsAuthorized(Permissions.AppointmentEdit)) { return; } if (grid.SelectedIndices.Length > 1) { if (!MsgBox.Show(MsgBoxButtons.OKCancel, "Delete all selected appointments permanently?")) { return; } } List <Appointment> listApptsWithNote = new List <Appointment>(); List <long> listSelectedAptNums = new List <long>(); foreach (int i in grid.SelectedIndices) { listSelectedAptNums.Add(_listUnschedApt[i].AptNum); if (!string.IsNullOrEmpty(_listUnschedApt[i].Note)) { listApptsWithNote.Add(_listUnschedApt[i]); } } if (listApptsWithNote.Count > 0) //There were notes in the appointment(s) we are about to delete and we must ask if they want to save them in a commlog. { string commlogMsg = ""; if (grid.SelectedIndices.Length == 1) { commlogMsg = Commlogs.GetDeleteApptCommlogMessage(listApptsWithNote[0].Note, listApptsWithNote[0].AptStatus); } else { commlogMsg = "One or more appointments have notes. Save appointment notes in CommLogs?"; } DialogResult result = MessageBox.Show(commlogMsg, "Question...", MessageBoxButtons.YesNoCancel); if (result == DialogResult.Cancel) { return; } else if (result == DialogResult.Yes) { foreach (Appointment apptCur in listApptsWithNote) { Commlog commlogCur = new Commlog(); commlogCur.PatNum = apptCur.PatNum; commlogCur.CommDateTime = DateTime.Now; commlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); commlogCur.Note = Lan.g(this, "Deleted Appt. & saved note") + ": "; if (apptCur.ProcDescript != "") { commlogCur.Note += apptCur.ProcDescript + ": "; } commlogCur.Note += apptCur.Note; commlogCur.UserNum = Security.CurUser.UserNum; //there is no dialog here because it is just a simple entry Commlogs.Insert(commlogCur); } } } Appointments.Delete(listSelectedAptNums); foreach (int i in grid.SelectedIndices) { SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit, _listUnschedApt[i].PatNum, Lan.g(this, "Appointment deleted from the Unscheduled list."), _listUnschedApt[i].AptNum, _listUnschedApt[i].DateTStamp); } FillGrid(); }
private void FormReqStudentEdit_Load(object sender, System.EventArgs e) { //There should only be two types of users who are allowed to get this far: //Students editing their own req, and users with setup perm. But we will double check. Provider provUser = Providers.GetProv(Security.CurUser.ProvNum); if (provUser != null && provUser.SchoolClassNum != 0) //A student is logged in //the student only has permission to view/attach/detach their own requirements { if (provUser.ProvNum != ReqCur.ProvNum) { //but this should never happen MsgBox.Show(this, "Students may only edit their own requirements."); butDelete.Enabled = false; butOK.Enabled = false; } else //the student matches { butDelete.Enabled = false; textDateCompleted.Enabled = false; butNow.Enabled = false; comboInstructor.Enabled = false; //a student is only allowed to change the patient and appointment. } } else //A student is not logged in { if (!Security.IsAuthorized(Permissions.Setup, DateTime.MinValue, true)) //suppress message { butDelete.Enabled = false; butOK.Enabled = false; } } textStudent.Text = Providers.GetLongDesc(ReqCur.ProvNum); textCourse.Text = SchoolCourses.GetDescript(ReqCur.SchoolCourseNum); textDescription.Text = ReqCur.Descript; if (ReqCur.DateCompleted.Year > 1880) { textDateCompleted.Text = ReqCur.DateCompleted.ToShortDateString(); } //if an apt is attached, then the same pat must be attached. Patient pat = Patients.GetPat(ReqCur.PatNum); if (pat != null) { textPatient.Text = pat.GetNameFL(); } Appointment apt = Appointments.GetOneApt(ReqCur.AptNum); if (apt != null) { if (apt.AptStatus == ApptStatus.UnschedList) { textAppointment.Text = Lan.g(this, "Unscheduled"); } else { textAppointment.Text = apt.AptDateTime.ToShortDateString() + " " + apt.AptDateTime.ToShortTimeString(); } textAppointment.Text += ", " + apt.ProcDescript; } comboInstructor.Items.Add(Lan.g(this, "None")); comboInstructor.SelectedIndex = 0; for (int i = 0; i < ProviderC.ListShort.Count; i++) { comboInstructor.Items.Add(ProviderC.ListShort[i].GetLongDesc()); if (ProviderC.ListShort[i].ProvNum == ReqCur.InstructorNum) { comboInstructor.SelectedIndex = i + 1; } } }
///<summary>Creates a single recall appointment. If it's from a double click, then it will end up on that spot in the Appts module. If not, it will end up on the pinboard with StringDateJumpTo as due date to jump to. ListAptNumsSelected will contain the AptNum of the new appointment.</summary> public void MakeRecallAppointment() { List <InsSub> listInsSubs = InsSubs.RefreshForFam(_famCur); List <InsPlan> listInsPlans = InsPlans.RefreshForSubList(listInsSubs); Appointment apt = null; DateTime dateTimeApt = DateTime.MinValue; if (this.IsInitialDoubleClick) { dateTimeApt = DateTimeClicked; } try{ apt = AppointmentL.CreateRecallApt(_patCur, listInsPlans, -1, listInsSubs, dateTimeApt); } catch (Exception ex) { MessageBox.Show(ex.Message); return; } DateTime datePrevious = apt.DateTStamp; ListAptNumsSelected.Add(apt.AptNum); if (IsInitialDoubleClick) { Appointment oldApt = apt.Copy(); if (_patCur.AskToArriveEarly > 0) { apt.DateTimeAskedToArrive = apt.AptDateTime.AddMinutes(-_patCur.AskToArriveEarly); MessageBox.Show(Lan.g(this, "Ask patient to arrive") + " " + _patCur.AskToArriveEarly + " " + Lan.g(this, "minutes early at") + " " + apt.DateTimeAskedToArrive.ToShortTimeString() + "."); } apt.AptStatus = ApptStatus.Scheduled; apt.ClinicNum = _patCur.ClinicNum; apt.Op = OpNumClicked; apt = Appointments.AssignFieldsForOperatory(apt); //Use apt.ClinicNum because it was just set based on Op.ClinicNum in AssignFieldsForOperatory(). if (!AppointmentL.IsSpecialtyMismatchAllowed(_patCur.PatNum, apt.ClinicNum)) { return; } Appointments.Update(apt, oldApt); _otherResult = OtherResult.CreateNew; SecurityLogs.MakeLogEntry(Permissions.AppointmentCreate, apt.PatNum, apt.AptDateTime.ToString(), apt.AptNum, datePrevious); //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if (HL7Defs.IsExistingHL7Enabled()) { //S12 - New Appt Booking event MessageHL7 messageHL7 = MessageConstructor.GenerateSIU(_patCur, _famCur.GetPatient(_patCur.Guarantor), EventTypeHL7.S12, apt); //Will be null if there is no outbound SIU message defined, so do nothing if (messageHL7 != null) { HL7Msg hl7Msg = new HL7Msg(); hl7Msg.AptNum = apt.AptNum; hl7Msg.HL7Status = HL7MessageStatus.OutPending; //it will be marked outSent by the HL7 service. hl7Msg.MsgText = messageHL7.ToString(); hl7Msg.PatNum = _patCur.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show(this, messageHL7.ToString()); #endif } } DialogResult = DialogResult.OK; return; } //not initialClick _otherResult = OtherResult.PinboardAndSearch; Recall recall = Recalls.GetRecallProphyOrPerio(_patCur.PatNum); //shouldn't return null. if (recall.DateDue < DateTime.Today) { StringDateJumpTo = DateTime.Today.ToShortDateString(); //they are overdue } else { StringDateJumpTo = recall.DateDue.ToShortDateString(); } //no securitylog entry needed here. That will happen when it's dragged off pinboard. DialogResult = DialogResult.OK; }
///<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; }
///<summary></summary> public static PlannedApptStatus CreatePlannedAppt(Patient pat, int itemOrder, List <long> listPreSelectedProcNums = null) { if (!Security.IsAuthorized(Permissions.AppointmentCreate)) { return(PlannedApptStatus.Failure); } if (PatRestrictionL.IsRestricted(pat.PatNum, PatRestrict.ApptSchedule)) { return(PlannedApptStatus.Failure); } if (PromptForMerge(pat, out pat)) { FormOpenDental.S_Contr_PatientSelected(pat, true, false); } if (pat.PatStatus.In(PatientStatus.Archived, PatientStatus.Deceased)) { MsgBox.Show("Appointments", "Appointments cannot be scheduled for " + pat.PatStatus.ToString().ToLower() + " patients."); return(PlannedApptStatus.Failure); } Appointment AptCur = new Appointment(); AptCur.PatNum = pat.PatNum; AptCur.ProvNum = pat.PriProv; AptCur.ClinicNum = pat.ClinicNum; AptCur.AptStatus = ApptStatus.Planned; AptCur.AptDateTime = DateTimeOD.Today; List <Procedure> listProcs = Procedures.GetManyProc(listPreSelectedProcNums, false); //Returns empty list if null. //If listProcs is empty then AptCur.Pattern defaults to PrefName.AppointmentWithoutProcsDefaultLength value. //See Appointments.GetApptTimePatternForNoProcs(). AptCur.Pattern = Appointments.CalculatePattern(pat, AptCur.ProvNum, AptCur.ProvHyg, listProcs, isMake5Minute: true); AptCur.TimeLocked = PrefC.GetBool(PrefName.AppointmentTimeIsLocked); Appointments.Insert(AptCur); PlannedAppt plannedAppt = new PlannedAppt(); plannedAppt.AptNum = AptCur.AptNum; plannedAppt.PatNum = pat.PatNum; plannedAppt.ItemOrder = itemOrder; PlannedAppts.Insert(plannedAppt); Procedures.UpdateAptNums(listPreSelectedProcNums, plannedAppt.AptNum, true); //Simply returns if listPreSelectedProcNums is null FormApptEdit FormApptEdit = new FormApptEdit(AptCur.AptNum); FormApptEdit.IsNew = true; FormApptEdit.ShowDialog(); if (FormApptEdit.DialogResult != DialogResult.OK) { Procedures.UpdateAptNums(listPreSelectedProcNums, 0, true); //Simply returns if listPreSelectedProcNums is null return(PlannedApptStatus.FillGridNeeded); } //Only set the appointment hygienist to this patient's secondary provider if one was not manually set within the edit window. if (AptCur.ProvHyg < 1) { List <Procedure> myProcList = Procedures.GetProcsForSingle(AptCur.AptNum, true); bool allProcsHyg = (myProcList.Count > 0 && myProcList.Select(x => ProcedureCodes.GetProcCode(x.CodeNum)).ToList().All(x => x.IsHygiene)); //Automatically set the appointments hygienist to the secondary provider of the patient if one is set. if (allProcsHyg && pat.SecProv != 0) { Appointment aptOld = AptCur.Copy(); AptCur.ProvNum = pat.SecProv; Appointments.Update(AptCur, aptOld); } } Patient patOld = pat.Copy(); pat.PlannedIsDone = false; Patients.Update(pat, patOld); FormOpenDental.S_RefreshCurrentModule(isClinicRefresh: false); //if procs were added in appt, then this will display them return(PlannedApptStatus.Success); }
private void butApptProcs_Click(object sender, EventArgs e) { if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "This will fix procedure descriptions in the Appt module that aren't correctly showing tooth numbers.\r\nContinue?")) { return; } Cursor = Cursors.WaitCursor; //The ApptProcDescript region is also in FormProcEdit.SaveAndClose() and FormApptEdit.UpdateToDB() Make any changes there as well. #region ApptProcDescript List <long> aptNums = new List <long>(); Appointment[] aptList = Appointments.GetForPeriod(DateTime.Now.Date.AddMonths(-6), DateTime.MaxValue.AddDays(-10)); for (int i = 0; i < aptList.Length; i++) { aptNums.Add(aptList[i].AptNum); } for (int i = 0; i < aptList.Length; i++) { //This gets the list of procedures in the correct order. DataTable procTable = Appointments.GetProcTable(aptList[i].PatNum.ToString(), aptList[i].AptNum.ToString(), ((int)aptList[i].AptStatus).ToString(), aptList[i].AptDateTime.ToString()); Appointment newApt = aptList[i].Clone(); newApt.ProcDescript = ""; newApt.ProcsColored = ""; int count = 0; for (int j = 0; j < procTable.Rows.Count; j++) { if (procTable.Rows[j]["attached"].ToString() != "1") { continue; } string procDescOne = ""; string procCode = procTable.Rows[j]["ProcCode"].ToString(); if (count > 0) { newApt.ProcDescript += ", "; } switch (procTable.Rows[j]["TreatArea"].ToString()) { case "1": //TreatmentArea.Surf: procDescOne += "#" + Tooth.GetToothLabel(procTable.Rows[j]["ToothNum"].ToString()) + "-" + procTable.Rows[j]["Surf"].ToString() + "-"; //""#12-MOD-" break; case "2": //TreatmentArea.Tooth: procDescOne += "#" + Tooth.GetToothLabel(procTable.Rows[j]["ToothNum"].ToString()) + "-"; //"#12-" break; default: //area 3 or 0 (mouth) break; case "4": //TreatmentArea.Quad: procDescOne += procTable.Rows[j]["Surf"].ToString() + "-"; //"UL-" break; case "5": //TreatmentArea.Sextant: procDescOne += "S" + procTable.Rows[j]["Surf"].ToString() + "-"; //"S2-" break; case "6": //TreatmentArea.Arch: procDescOne += procTable.Rows[j]["Surf"].ToString() + "-"; //"U-" break; case "7": //TreatmentArea.ToothRange: //strLine+=table.Rows[j][13].ToString()+" ";//don't show range break; } procDescOne += procTable.Rows[j]["AbbrDesc"].ToString(); newApt.ProcDescript += procDescOne; //Color and previous date are determined by ProcApptColor object ProcApptColor pac = ProcApptColors.GetMatch(procCode); System.Drawing.Color pColor = System.Drawing.Color.Black; string prevDateString = ""; if (pac != null) { pColor = pac.ColorText; if (pac.ShowPreviousDate) { prevDateString = Procedures.GetRecentProcDateString(newApt.PatNum, newApt.AptDateTime, pac.CodeRange); if (prevDateString != "") { prevDateString = " (" + prevDateString + ")"; } } } newApt.ProcsColored += "<span color=\"" + pColor.ToArgb().ToString() + "\">" + procDescOne + prevDateString + "</span>"; count++; } Appointments.Update(newApt, aptList[i]); } #endregion Cursor = Cursors.Default; MsgBox.Show(this, "Done. Please refresh Appt module to see the changes."); }
/* * ///<summary>Only used in GetSearchResults. All times between start and stop get set to true in provBarSched.</summary> * private static void SetProvBarSched(ref bool[] provBarSched,TimeSpan timeStart,TimeSpan timeStop){ * int startI=GetProvBarIndex(timeStart); * int stopI=GetProvBarIndex(timeStop); * for(int i=startI;i<=stopI;i++){ * provBarSched[i]=true; * } * } * * private static int GetProvBarIndex(TimeSpan time) { * return (int)(((double)time.Hours*(double)60/(double)PrefC.GetLong(PrefName.AppointmentTimeIncrement)//aptTimeIncr=minutesPerIncr +(double)time.Minutes/(double)PrefC.GetLong(PrefName.AppointmentTimeIncrement)) *(double)ApptDrawing.LineH*ApptDrawing.RowsPerIncr) * /ApptDrawing.LineH;//rounds down * }*/ ///<summary>Used by UI when it needs a recall appointment placed on the pinboard ready to schedule. This method creates the appointment and attaches all appropriate procedures. It's up to the calling class to then place the appointment on the pinboard. If the appointment doesn't get scheduled, it's important to delete it. If a recallNum is not 0 or -1, then it will create an appt of that recalltype.</summary> public static Appointment CreateRecallApt(Patient patCur, List <InsPlan> planList, long recallNum, List <InsSub> subList , DateTime aptDateTime = default(DateTime)) { List <Recall> recallList = Recalls.GetList(patCur.PatNum); Recall recallCur = null; if (recallNum > 0) { recallCur = Recalls.GetRecall(recallNum); } else { for (int i = 0; i < recallList.Count; i++) { if (recallList[i].RecallTypeNum == RecallTypes.PerioType || recallList[i].RecallTypeNum == RecallTypes.ProphyType) { if (!recallList[i].IsDisabled) { recallCur = recallList[i]; } break; } } } if (recallCur == null) { //Typically never happens because everyone has a recall. However, it can happen when patients have custom recalls due throw new ApplicationException(Lan.g("AppointmentL", "No special type recall is due.")); } if (recallCur.DateScheduled.Date > DateTime.Today) { throw new ApplicationException(Lan.g("AppointmentL", "Recall has already been scheduled for ") + recallCur.DateScheduled.ToShortDateString()); } Appointment aptCur = new Appointment(); aptCur.AptDateTime = aptDateTime; List <string> procs = RecallTypes.GetProcs(recallCur.RecallTypeNum); List <Procedure> listProcs = Appointments.FillAppointmentForRecall(aptCur, recallCur, recallList, patCur, procs, planList, subList); for (int i = 0; i < listProcs.Count; i++) { if (Programs.UsingOrion) { FormProcEdit FormP = new FormProcEdit(listProcs[i], patCur.Copy(), Patients.GetFamily(patCur.PatNum)); FormP.IsNew = true; FormP.ShowDialog(); if (FormP.DialogResult == DialogResult.Cancel) { //any created claimprocs are automatically deleted from within procEdit window. try { Procedures.Delete(listProcs[i].ProcNum); //also deletes the claimprocs } catch (Exception ex) { MessageBox.Show(ex.Message); } } else { //Do not synch. Recalls based on ScheduleByDate reports in Orion mode. //Recalls.Synch(PatCur.PatNum); } } } return(aptCur); }
///<summary>Sets given appt.AptStatus to broken. ///Provide procCode that should be charted, can be null but will not chart a broken procedure. ///Also considers various broken procedure based prefs. ///Makes its own securitylog entries.</summary> public static void BreakApptHelper(Appointment appt, Patient pat, ProcedureCode procCode) { //suppressHistory is true due to below logic creating a log with a specific HistAppointmentAction instead of the generic changed. DateTime datePrevious = appt.DateTStamp; bool suppressHistory = false; if (procCode != null) { suppressHistory = (procCode.ProcCode.In("D9986", "D9987")); } Appointments.SetAptStatus(appt, ApptStatus.Broken, suppressHistory); //Appointments S-Class handles Signalods if (appt.AptStatus != ApptStatus.Complete) //seperate log entry for completed appointments. { SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit, pat.PatNum, appt.ProcDescript + ", " + appt.AptDateTime.ToString() + ", Broken from the Appts module.", appt.AptNum, datePrevious); } else { SecurityLogs.MakeLogEntry(Permissions.AppointmentCompleteEdit, pat.PatNum, appt.ProcDescript + ", " + appt.AptDateTime.ToString() + ", Broken from the Appts module.", appt.AptNum, datePrevious); } #region HL7 //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if (HL7Defs.IsExistingHL7Enabled()) { //S15 - Appt Cancellation event MessageHL7 messageHL7 = MessageConstructor.GenerateSIU(pat, Patients.GetPat(pat.Guarantor), EventTypeHL7.S15, appt); //Will be null if there is no outbound SIU message defined, so do nothing if (messageHL7 != null) { HL7Msg hl7Msg = new HL7Msg(); hl7Msg.AptNum = appt.AptNum; hl7Msg.HL7Status = HL7MessageStatus.OutPending; //it will be marked outSent by the HL7 service. hl7Msg.MsgText = messageHL7.ToString(); hl7Msg.PatNum = pat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show("Appointments", messageHL7.ToString()); #endif } } #endregion #region Charting the proc if (procCode != null) { switch (procCode.ProcCode) { case "D9986": //Missed HistAppointments.CreateHistoryEntry(appt.AptNum, HistAppointmentAction.Missed); break; case "D9987": //Cancelled HistAppointments.CreateHistoryEntry(appt.AptNum, HistAppointmentAction.Cancelled); break; } Procedure procedureCur = new Procedure(); procedureCur.PatNum = pat.PatNum; procedureCur.ProvNum = (procCode.ProvNumDefault > 0 ? procCode.ProvNumDefault : appt.ProvNum); procedureCur.CodeNum = procCode.CodeNum; procedureCur.ProcDate = DateTime.Today; procedureCur.DateEntryC = DateTime.Now; procedureCur.ProcStatus = ProcStat.C; procedureCur.ClinicNum = appt.ClinicNum; procedureCur.UserNum = Security.CurUser.UserNum; procedureCur.Note = Lans.g("AppointmentEdit", "Appt BROKEN for") + " " + appt.ProcDescript + " " + appt.AptDateTime.ToString(); procedureCur.PlaceService = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService); //Default proc place of service for the Practice is used. List <InsSub> listInsSubs = InsSubs.RefreshForFam(Patients.GetFamily(pat.PatNum)); List <InsPlan> listInsPlans = InsPlans.RefreshForSubList(listInsSubs); List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum); InsPlan insPlanPrimary = null; InsSub insSubPrimary = null; if (listPatPlans.Count > 0) { insSubPrimary = InsSubs.GetSub(listPatPlans[0].InsSubNum, listInsSubs); insPlanPrimary = InsPlans.GetPlan(insSubPrimary.PlanNum, listInsPlans); } double procFee; long feeSch; if (insPlanPrimary == null || procCode.NoBillIns) { feeSch = FeeScheds.GetFeeSched(0, pat.FeeSched, procedureCur.ProvNum); } else //Only take into account the patient's insurance fee schedule if the D9986 procedure is not marked as NoBillIns { feeSch = FeeScheds.GetFeeSched(insPlanPrimary.FeeSched, pat.FeeSched, procedureCur.ProvNum); } procFee = Fees.GetAmount0(procedureCur.CodeNum, feeSch, procedureCur.ClinicNum, procedureCur.ProvNum); if (insPlanPrimary != null && insPlanPrimary.PlanType == "p" && !insPlanPrimary.IsMedical) //PPO { double provFee = Fees.GetAmount0(procedureCur.CodeNum, Providers.GetProv(procedureCur.ProvNum).FeeSched, procedureCur.ClinicNum, procedureCur.ProvNum); procedureCur.ProcFee = Math.Max(provFee, procFee); } else { procedureCur.ProcFee = procFee; } if (!PrefC.GetBool(PrefName.EasyHidePublicHealth)) { procedureCur.SiteNum = pat.SiteNum; } Procedures.Insert(procedureCur); //Now make a claimproc if the patient has insurance. We do this now for consistency because a claimproc could get created in the future. List <Benefit> listBenefits = Benefits.Refresh(listPatPlans, listInsSubs); List <ClaimProc> listClaimProcsForProc = ClaimProcs.RefreshForProc(procedureCur.ProcNum); Procedures.ComputeEstimates(procedureCur, pat.PatNum, listClaimProcsForProc, false, listInsPlans, listPatPlans, listBenefits, pat.Age, listInsSubs); FormProcBroken FormPB = new FormProcBroken(procedureCur); FormPB.IsNew = true; FormPB.ShowDialog(); } #endregion #region BrokenApptAdjustment if (PrefC.GetBool(PrefName.BrokenApptAdjustment)) { Adjustment AdjustmentCur = new Adjustment(); AdjustmentCur.DateEntry = DateTime.Today; AdjustmentCur.AdjDate = DateTime.Today; AdjustmentCur.ProcDate = DateTime.Today; AdjustmentCur.ProvNum = appt.ProvNum; AdjustmentCur.PatNum = pat.PatNum; AdjustmentCur.AdjType = PrefC.GetLong(PrefName.BrokenAppointmentAdjustmentType); AdjustmentCur.ClinicNum = appt.ClinicNum; FormAdjust FormA = new FormAdjust(pat, AdjustmentCur); FormA.IsNew = true; FormA.ShowDialog(); } #endregion #region BrokenApptCommLog if (PrefC.GetBool(PrefName.BrokenApptCommLog)) { Commlog CommlogCur = new Commlog(); CommlogCur.PatNum = pat.PatNum; CommlogCur.CommDateTime = DateTime.Now; CommlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); CommlogCur.Note = Lan.g("Appointment", "Appt BROKEN for") + " " + appt.ProcDescript + " " + appt.AptDateTime.ToString(); CommlogCur.Mode_ = CommItemMode.None; CommlogCur.UserNum = Security.CurUser.UserNum; FormCommItem FormCI = new FormCommItem(); FormCI.ShowDialog(new CommItemModel() { CommlogCur = CommlogCur }, new CommItemController(FormCI) { IsNew = true }); } #endregion AutomationL.Trigger(AutomationTrigger.BreakAppointment, null, pat.PatNum); Recalls.SynchScheduledApptFull(appt.PatNum); }
///<summary></summary> public static List <DateTime> GetSearchResults(long aptNum, DateTime afterDate, List <long> providerNums, int resultCount, TimeSpan beforeTime, TimeSpan afterTime) { if (beforeTime == TimeSpan.FromSeconds(0)) //if they didn't set a before time, set it to a large timespan so that we can use the same logic for checking appointment times. { beforeTime = TimeSpan.FromHours(25); //bigger than any time of day. } SearchBehaviorCriteria SearchType = (SearchBehaviorCriteria)PrefC.GetInt(PrefName.AppointmentSearchBehavior); List <DateTime> retVal = new List <DateTime>(); DateTime dayEvaluating = afterDate.AddDays(1); Appointment appointmentToAdd = Appointments.GetOneApt(aptNum); List <DateTime> potentialProvAppointmentTime; List <DateTime> potentialOpAppointmentTime; List <Operatory> opsListAll = Operatories.GetDeepCopy(); //all operatory Numbers List <Schedule> scheduleListAll = Schedules.GetTwoYearPeriod(dayEvaluating); // Schedules for the given day. List <Appointment> appointmentListAll = Appointments.GetForPeriodList(dayEvaluating, dayEvaluating.AddYears(2)); List <ScheduleOp> schedOpListAll = ScheduleOps.GetForSchedList(scheduleListAll); List <ApptSearchProviderSchedule> provScheds = new List <ApptSearchProviderSchedule>(); //Provider Bar, ProviderSched Bar, Date and Provider List <ApptSearchOperatorySchedule> operatrorySchedules = new List <ApptSearchOperatorySchedule>(); //filtered based on SearchType List <long> operatoryNums = new List <long>(); //more usefull than a list of operatories. for (int i = 0; i < opsListAll.Count; i++) { operatoryNums.Add(opsListAll[i].OperatoryNum); } while (retVal.Count < resultCount && dayEvaluating < afterDate.AddYears(2)) { potentialOpAppointmentTime = new List <DateTime>(); //clear or create //Providers------------------------------------------------------------------------------------------------------------------------------------- potentialProvAppointmentTime = new List <DateTime>(); //clear or create provScheds = Appointments.GetApptSearchProviderScheduleForProvidersAndDate(providerNums, dayEvaluating, scheduleListAll, appointmentListAll); for (int i = 0; i < provScheds.Count; i++) { for (int j = 0; j < 288; j++) //search every 5 minute increment per day { if (j + appointmentToAdd.Pattern.Length > 288) { break; } if (potentialProvAppointmentTime.Contains(dayEvaluating.AddMinutes(j * 5))) { continue; } bool addDateTime = true; for (int k = 0; k < appointmentToAdd.Pattern.Length; k++) { if ((provScheds[i].ProvBar[j + k] == false && appointmentToAdd.Pattern[k] == 'X') || provScheds[i].ProvSchedule[j + k] == false) { addDateTime = false; break; } } if (addDateTime) { potentialProvAppointmentTime.Add(dayEvaluating.AddMinutes(j * 5)); } } } if (SearchType == SearchBehaviorCriteria.ProviderTimeOperatory) //Handle Operatories here---------------------------------------------------------------------------- { operatrorySchedules = GetAllForDate(dayEvaluating, scheduleListAll, appointmentListAll, schedOpListAll, operatoryNums, providerNums); potentialOpAppointmentTime = new List <DateTime>(); //create or clear //for(int j=0;j<operatrorySchedules.Count;j++) {//for each operatory for (int i = 0; i < 288; i++) //search every 5 minute increment per day { if (i + appointmentToAdd.Pattern.Length > 288) //skip if appointment would span across midnight { break; } for (int j = 0; j < operatrorySchedules.Count; j++) //for each operatory //if(potentialOpAppointmentTime.Contains(dayEvaluating.AddMinutes(i*5))) {//skip if we already have this dateTime // break; //} { bool addDateTime = true; for (int k = 0; k < appointmentToAdd.Pattern.Length; k++) //check appointment against operatories { if (operatrorySchedules[j].OperatorySched[i + k] == false) { addDateTime = false; break; } } if (!addDateTime) { continue; } if (addDateTime) // && SearchType==SearchBehaviorCriteria.ProviderTimeOperatory) {//check appointment against providers available for the given operatory { bool provAvail = false; for (int k = 0; k < providerNums.Count; k++) { if (!operatrorySchedules[j].ProviderNums.Contains(providerNums[k])) { continue; } provAvail = true; for (int m = 0; m < appointmentToAdd.Pattern.Length; m++) { if ((provScheds[k].ProvBar[i + m] == false && appointmentToAdd.Pattern[m] == 'X') || provScheds[k].ProvSchedule[i + m] == false) //if provider bar time slot { provAvail = false; break; } } if (provAvail) //found a provider with an available operatory { break; } } if (provAvail && addDateTime) //operatory and provider are available { potentialOpAppointmentTime.Add(dayEvaluating.AddMinutes(i * 5)); } } else //not using SearchBehaviorCriteria.ProviderTimeOperatory { if (addDateTime) { potentialOpAppointmentTime.Add(dayEvaluating.AddMinutes(i * 5)); } } } } } //At this point the potentialOpAppointmentTime is already filtered and only contains appointment times that match both provider time and operatory time. switch (SearchType) { case SearchBehaviorCriteria.ProviderTime: //Add based on provider bars for (int i = 0; i < potentialProvAppointmentTime.Count; i++) { if (potentialProvAppointmentTime[i].TimeOfDay > beforeTime || potentialProvAppointmentTime[i].TimeOfDay < afterTime) { continue; } retVal.Add(potentialProvAppointmentTime[i]); //add one for this day break; //stop looking through potential times for today. } break; case SearchBehaviorCriteria.ProviderTimeOperatory: //add based on provider bar and operatory bar for (int i = 0; i < potentialOpAppointmentTime.Count; i++) { if (potentialOpAppointmentTime[i].TimeOfDay > beforeTime || potentialOpAppointmentTime[i].TimeOfDay < afterTime) { continue; } retVal.Add(potentialOpAppointmentTime[i]); //add one for this day break; //stop looking through potential times for today. } break; } dayEvaluating = dayEvaluating.AddDays(1); } return(retVal); }
///<summary>Sets given appt.AptStatus to broken. ///Provide procCode that should be charted, can be null but will not chart a broken procedure. ///Also considers various broken procedure based prefs. ///Makes its own securitylog entries.</summary> public static void BreakApptHelper(Appointment appt, Patient pat, ProcedureCode procCode) { //suppressHistory is true due to below logic creating a log with a specific HistAppointmentAction instead of the generic changed. DateTime datePrevious = appt.DateTStamp; bool suppressHistory = false; if (procCode != null) { suppressHistory = (procCode.ProcCode.In("D9986", "D9987")); } Appointments.SetAptStatus(appt, ApptStatus.Broken, suppressHistory); //Appointments S-Class handles Signalods if (appt.AptStatus != ApptStatus.Complete) //seperate log entry for completed appointments. { SecurityLogs.MakeLogEntry(Permissions.AppointmentEdit, pat.PatNum, appt.ProcDescript + ", " + appt.AptDateTime.ToString() + ", Broken from the Appts module.", appt.AptNum, datePrevious); } else { SecurityLogs.MakeLogEntry(Permissions.AppointmentCompleteEdit, pat.PatNum, appt.ProcDescript + ", " + appt.AptDateTime.ToString() + ", Broken from the Appts module.", appt.AptNum, datePrevious); } #region HL7 //If there is an existing HL7 def enabled, send a SIU message if there is an outbound SIU message defined if (HL7Defs.IsExistingHL7Enabled()) { //S15 - Appt Cancellation event MessageHL7 messageHL7 = MessageConstructor.GenerateSIU(pat, Patients.GetPat(pat.Guarantor), EventTypeHL7.S15, appt); //Will be null if there is no outbound SIU message defined, so do nothing if (messageHL7 != null) { HL7Msg hl7Msg = new HL7Msg(); hl7Msg.AptNum = appt.AptNum; hl7Msg.HL7Status = HL7MessageStatus.OutPending; //it will be marked outSent by the HL7 service. hl7Msg.MsgText = messageHL7.ToString(); hl7Msg.PatNum = pat.PatNum; HL7Msgs.Insert(hl7Msg); #if DEBUG MessageBox.Show("Appointments", messageHL7.ToString()); #endif } } #endregion List <Procedure> listProcedures = new List <Procedure>(); //splits should only exist on procs if they are using tp pre-payments List <PaySplit> listSplitsForApptProcs = new List <PaySplit>(); bool isNonRefundable = false; double brokenProcAmount = 0; Procedure brokenProcedure = new Procedure(); bool wasBrokenProcDeleted = false; if (PrefC.GetYN(PrefName.PrePayAllowedForTpProcs)) { listProcedures = Procedures.GetProcsForSingle(appt.AptNum, false); if (listProcedures.Count > 0) { listSplitsForApptProcs = PaySplits.GetPaySplitsFromProcs(listProcedures.Select(x => x.ProcNum).ToList()); } } #region Charting the proc if (procCode != null) { switch (procCode.ProcCode) { case "D9986": //Missed HistAppointments.CreateHistoryEntry(appt.AptNum, HistAppointmentAction.Missed); break; case "D9987": //Cancelled HistAppointments.CreateHistoryEntry(appt.AptNum, HistAppointmentAction.Cancelled); break; } brokenProcedure.PatNum = pat.PatNum; brokenProcedure.ProvNum = (procCode.ProvNumDefault > 0 ? procCode.ProvNumDefault : appt.ProvNum); brokenProcedure.CodeNum = procCode.CodeNum; brokenProcedure.ProcDate = DateTime.Today; brokenProcedure.DateEntryC = DateTime.Now; brokenProcedure.ProcStatus = ProcStat.C; brokenProcedure.ClinicNum = appt.ClinicNum; brokenProcedure.UserNum = Security.CurUser.UserNum; brokenProcedure.Note = Lans.g("AppointmentEdit", "Appt BROKEN for") + " " + appt.ProcDescript + " " + appt.AptDateTime.ToString(); brokenProcedure.PlaceService = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService); //Default proc place of service for the Practice is used. List <InsSub> listInsSubs = InsSubs.RefreshForFam(Patients.GetFamily(pat.PatNum)); List <InsPlan> listInsPlans = InsPlans.RefreshForSubList(listInsSubs); List <PatPlan> listPatPlans = PatPlans.Refresh(pat.PatNum); InsPlan insPlanPrimary = null; InsSub insSubPrimary = null; if (listPatPlans.Count > 0) { insSubPrimary = InsSubs.GetSub(listPatPlans[0].InsSubNum, listInsSubs); insPlanPrimary = InsPlans.GetPlan(insSubPrimary.PlanNum, listInsPlans); } double procFee; long feeSch; if (insPlanPrimary == null || procCode.NoBillIns) { feeSch = FeeScheds.GetFeeSched(0, pat.FeeSched, brokenProcedure.ProvNum); } else //Only take into account the patient's insurance fee schedule if the D9986 procedure is not marked as NoBillIns { feeSch = FeeScheds.GetFeeSched(insPlanPrimary.FeeSched, pat.FeeSched, brokenProcedure.ProvNum); } procFee = Fees.GetAmount0(brokenProcedure.CodeNum, feeSch, brokenProcedure.ClinicNum, brokenProcedure.ProvNum); if (insPlanPrimary != null && insPlanPrimary.PlanType == "p" && !insPlanPrimary.IsMedical) //PPO { double provFee = Fees.GetAmount0(brokenProcedure.CodeNum, Providers.GetProv(brokenProcedure.ProvNum).FeeSched, brokenProcedure.ClinicNum, brokenProcedure.ProvNum); brokenProcedure.ProcFee = Math.Max(provFee, procFee); } else if (listSplitsForApptProcs.Count > 0 && PrefC.GetBool(PrefName.TpPrePayIsNonRefundable) && procCode.ProcCode == "D9986") { //if there are pre-payments, non-refundable pre-payments is turned on, and the broken appointment is a missed code then auto-fill //the window with the sum of the procs for the appointment. Transfer money below after broken procedure is confirmed by the user. brokenProcedure.ProcFee = listSplitsForApptProcs.Sum(x => x.SplitAmt); isNonRefundable = true; } else { brokenProcedure.ProcFee = procFee; } if (!PrefC.GetBool(PrefName.EasyHidePublicHealth)) { brokenProcedure.SiteNum = pat.SiteNum; } Procedures.Insert(brokenProcedure); //Now make a claimproc if the patient has insurance. We do this now for consistency because a claimproc could get created in the future. List <Benefit> listBenefits = Benefits.Refresh(listPatPlans, listInsSubs); List <ClaimProc> listClaimProcsForProc = ClaimProcs.RefreshForProc(brokenProcedure.ProcNum); Procedures.ComputeEstimates(brokenProcedure, pat.PatNum, listClaimProcsForProc, false, listInsPlans, listPatPlans, listBenefits, pat.Age, listInsSubs); FormProcBroken FormPB = new FormProcBroken(brokenProcedure, isNonRefundable); FormPB.IsNew = true; FormPB.ShowDialog(); brokenProcAmount = FormPB.AmountTotal; wasBrokenProcDeleted = FormPB.IsProcDeleted; } #endregion #region BrokenApptAdjustment if (PrefC.GetBool(PrefName.BrokenApptAdjustment)) { Adjustment AdjustmentCur = new Adjustment(); AdjustmentCur.DateEntry = DateTime.Today; AdjustmentCur.AdjDate = DateTime.Today; AdjustmentCur.ProcDate = DateTime.Today; AdjustmentCur.ProvNum = appt.ProvNum; AdjustmentCur.PatNum = pat.PatNum; AdjustmentCur.AdjType = PrefC.GetLong(PrefName.BrokenAppointmentAdjustmentType); AdjustmentCur.ClinicNum = appt.ClinicNum; FormAdjust FormA = new FormAdjust(pat, AdjustmentCur); FormA.IsNew = true; FormA.ShowDialog(); } #endregion #region BrokenApptCommLog if (PrefC.GetBool(PrefName.BrokenApptCommLog)) { Commlog commlogCur = new Commlog(); commlogCur.PatNum = pat.PatNum; commlogCur.CommDateTime = DateTime.Now; commlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.APPT); commlogCur.Note = Lan.g("Appointment", "Appt BROKEN for") + " " + appt.ProcDescript + " " + appt.AptDateTime.ToString(); commlogCur.Mode_ = CommItemMode.None; commlogCur.UserNum = Security.CurUser.UserNum; commlogCur.IsNew = true; FormCommItem FormCI = new FormCommItem(commlogCur); FormCI.ShowDialog(); } #endregion #region Transfer money from TP Procedures if necessary //Note this MUST come after FormProcBroken since clicking cancel in that window will delete the procedure. if (isNonRefundable && !wasBrokenProcDeleted && listSplitsForApptProcs.Count > 0) { //transfer what the user specified in the broken appointment window. //transfer up to the amount specified by the user foreach (Procedure proc in listProcedures) { if (brokenProcAmount == 0) { break; } List <PaySplit> listSplitsForAppointmentProcedure = listSplitsForApptProcs.FindAll(x => x.ProcNum == proc.ProcNum); foreach (PaySplit split in listSplitsForAppointmentProcedure) { if (brokenProcAmount == 0) { break; } double amt = Math.Min(brokenProcAmount, split.SplitAmt); Payments.CreateTransferForTpProcs(proc, new List <PaySplit> { split }, brokenProcedure, amt); double amtPaidOnApt = listSplitsForApptProcs.Sum(x => x.SplitAmt); if (amtPaidOnApt > amt) { //If the original prepayment amount is greater than the amt being specified for the appointment break, transfer //the difference to an Unallocated Unearned Paysplit on the account. double remainingAmt = amtPaidOnApt - amt; //We have to create a new transfer payment here to correlate to the split. Payment txfrPayment = new Payment(); txfrPayment.PayAmt = 0; txfrPayment.PayDate = DateTime.Today; txfrPayment.ClinicNum = split.ClinicNum; txfrPayment.PayNote = "Automatic transfer from treatment planned procedure prepayment."; txfrPayment.PatNum = split.PatNum; //ultimately where the payment ends up. txfrPayment.PayType = 0; Payments.Insert(txfrPayment); PaymentEdit.IncomeTransferData transferData = PaymentEdit.IncomeTransferData.CreateTransfer(split, txfrPayment.PayNum, true, remainingAmt); PaySplit offset = transferData.ListSplitsCur.FirstOrDefault(x => x.FSplitNum != 0); long offsetSplitNum = PaySplits.Insert(offset); //Get the FSplitNum from the offset PaySplit allocation = transferData.ListSplitsCur.FirstOrDefault(x => x.FSplitNum == 0); allocation.FSplitNum = offsetSplitNum; PaySplits.Insert(allocation); //Insert so the split is now up to date SecurityLogs.MakeLogEntry(Permissions.PaymentCreate, txfrPayment.PatNum, "Automatic transfer of funds for treatment plan procedure pre-payments."); } brokenProcAmount -= amt; } } } //if broken appointment procedure was deleted (user cancelled out of the window) just keep money on the original procedure. #endregion AppointmentEvent.Fire(ODEventType.AppointmentEdited, appt); AutomationL.Trigger(AutomationTrigger.BreakAppointment, null, pat.PatNum); Recalls.SynchScheduledApptFull(appt.PatNum); }
private void FillGrid() { ODProgress.ShowAction( //Show progress window while filling the grid. () => { string order = ""; switch (comboOrder.SelectedIndex) { case 0: order = "status"; break; case 1: order = "alph"; break; case 2: order = "date"; break; } long provNum = 0; if (comboProv.SelectedIndex != 0) { provNum = _listProviders[comboProv.SelectedIndex - 1].ProvNum; } long siteNum = 0; if (!PrefC.GetBool(PrefName.EasyHidePublicHealth) && comboSite.SelectedIndex != 0) { siteNum = _listSites[comboSite.SelectedIndex - 1].SiteNum; } bool showBrokenAppts; showBrokenAppts = checkBrokenAppts.Checked; long clinicNum = PrefC.HasClinicsEnabled ? comboClinic.SelectedClinicNum : -1; _listUnschedApt = Appointments.RefreshUnsched(order, provNum, siteNum, showBrokenAppts, clinicNum, codeRangeFilter.StartRange, codeRangeFilter.EndRange, dateRangePicker.GetDateTimeFrom(), dateRangePicker.GetDateTimeTo()); UnscheduleListEvent.Fire(ODEventType.UnscheduledList, Lans.g(this, "Filling the Unscheduled List grid...")); int scrollVal = grid.ScrollValue; grid.BeginUpdate(); grid.ListGridColumns.Clear(); GridColumn col = new GridColumn(Lan.g("TableUnsched", "Patient"), 140); grid.ListGridColumns.Add(col); col = new GridColumn(Lan.g("TableUnsched", "Date"), 65); grid.ListGridColumns.Add(col); col = new GridColumn(Lan.g("TableUnsched", "AptStatus"), 90); grid.ListGridColumns.Add(col); col = new GridColumn(Lan.g("TableUnsched", "UnschedStatus"), 110); grid.ListGridColumns.Add(col); col = new GridColumn(Lan.g("TableUnsched", "Prov"), 50); grid.ListGridColumns.Add(col); col = new GridColumn(Lan.g("TableUnsched", "Procedures"), 150); grid.ListGridColumns.Add(col); col = new GridColumn(Lan.g("TableUnsched", "Notes"), 200); grid.ListGridColumns.Add(col); grid.ListGridRows.Clear(); GridRow row; Dictionary <long, string> dictPatNames = Patients.GetPatientNames(_listUnschedApt.Select(x => x.PatNum).ToList()); foreach (Appointment apt in _listUnschedApt) { row = new GridRow(); string patName = Lan.g(this, "UNKNOWN"); dictPatNames.TryGetValue(apt.PatNum, out patName); row.Cells.Add(patName); if (apt.AptDateTime.Year < 1880) { row.Cells.Add(""); } else { row.Cells.Add(apt.AptDateTime.ToShortDateString()); } if (apt.AptStatus == ApptStatus.Broken) { row.Cells.Add(Lan.g(this, "Broken")); } else { row.Cells.Add(Lan.g(this, "Unscheduled")); } row.Cells.Add(Defs.GetName(DefCat.RecallUnschedStatus, apt.UnschedStatus)); row.Cells.Add(Providers.GetAbbr(apt.ProvNum)); row.Cells.Add(apt.ProcDescript); row.Cells.Add(apt.Note); grid.ListGridRows.Add(row); } grid.EndUpdate(); grid.ScrollValue = scrollVal; }, startingMessage: Lans.g(this, "Retrieving data for the Unscheduled List grid..."), eventType: typeof(UnscheduleListEvent), odEventType: ODEventType.UnscheduledList ); }
public static bool Trigger <T>(AutomationTrigger trigger, List <string> procCodes, long patNum, long aptNum = 0, T triggerObj = default(T)) { if (patNum == 0) //Could happen for OpenPatient trigger { return(false); } List <Automation> listAutomations = Automations.GetDeepCopy(); bool automationHappened = false; for (int i = 0; i < listAutomations.Count; i++) { if (listAutomations[i].Autotrigger != trigger) { continue; } if (trigger == AutomationTrigger.CompleteProcedure || trigger == AutomationTrigger.ScheduleProcedure) { if (procCodes == null || procCodes.Count == 0) { continue; //fail silently } string[] arrayCodes = listAutomations[i].ProcCodes.Split(','); if (procCodes.All(x => !arrayCodes.Contains(x))) { continue; } } //matching automation item has been found //Get possible list of conditions that exist for this automation item List <AutomationCondition> autoConditionsList = AutomationConditions.GetListByAutomationNum(listAutomations[i].AutomationNum); if (autoConditionsList.Count > 0 && !CheckAutomationConditions(autoConditionsList, patNum, triggerObj)) { continue; } SheetDef sheetDef; Sheet sheet; FormSheetFillEdit FormSF; Appointment aptNew; Appointment aptOld; switch (listAutomations[i].AutoAction) { case AutomationAction.CreateCommlog: if (Plugins.HookMethod(null, "AutomationL.Trigger_CreateCommlog_start", patNum, aptNum, listAutomations[i].CommType, listAutomations[i].MessageContent)) { automationHappened = true; continue; } Commlog commlogCur = new Commlog(); commlogCur.PatNum = patNum; commlogCur.CommDateTime = DateTime.Now; commlogCur.CommType = listAutomations[i].CommType; commlogCur.Note = listAutomations[i].MessageContent; commlogCur.Mode_ = CommItemMode.None; commlogCur.UserNum = Security.CurUser.UserNum; FormCommItem commItemView = new FormCommItem(); commItemView.ShowDialog(new CommItemModel() { CommlogCur = commlogCur }, new CommItemController(commItemView) { IsNew = true }); automationHappened = true; continue; case AutomationAction.PopUp: MessageBox.Show(listAutomations[i].MessageContent); automationHappened = true; continue; case AutomationAction.PopUpThenDisable10Min: long automationNum = listAutomations[i].AutomationNum; bool hasAutomationBlock = FormOpenDental.DicBlockedAutomations.ContainsKey(automationNum); if (hasAutomationBlock && FormOpenDental.DicBlockedAutomations[automationNum].ContainsKey(patNum)) //Automation block exist for current patient. { continue; } if (hasAutomationBlock) { FormOpenDental.DicBlockedAutomations[automationNum].Add(patNum, DateTime.Now.AddMinutes(10)); //Disable for 10 minutes. } else //Add automationNum to higher level dictionary . { FormOpenDental.DicBlockedAutomations.Add(automationNum, new Dictionary <long, DateTime>() { { patNum, DateTime.Now.AddMinutes(10) } //Disable for 10 minutes. }); } MessageBox.Show(listAutomations[i].MessageContent); automationHappened = true; continue; case AutomationAction.PrintPatientLetter: case AutomationAction.ShowExamSheet: case AutomationAction.ShowConsentForm: sheetDef = SheetDefs.GetSheetDef(listAutomations[i].SheetDefNum); sheet = SheetUtil.CreateSheet(sheetDef, patNum); SheetParameter.SetParameter(sheet, "PatNum", patNum); SheetFiller.FillFields(sheet); SheetUtil.CalculateHeights(sheet); FormSF = new FormSheetFillEdit(sheet); FormSF.ShowDialog(); automationHappened = true; continue; case AutomationAction.PrintReferralLetter: long referralNum = RefAttaches.GetReferralNum(patNum); if (referralNum == 0) { MsgBox.Show("Automations", "This patient has no referral source entered."); automationHappened = true; continue; } sheetDef = SheetDefs.GetSheetDef(listAutomations[i].SheetDefNum); sheet = SheetUtil.CreateSheet(sheetDef, patNum); SheetParameter.SetParameter(sheet, "PatNum", patNum); SheetParameter.SetParameter(sheet, "ReferralNum", referralNum); //Don't fill these params if the sheet doesn't use them. if (sheetDef.SheetFieldDefs.Any(x => (x.FieldType == SheetFieldType.Grid && x.FieldName == "ReferralLetterProceduresCompleted") || (x.FieldType == SheetFieldType.Special && x.FieldName == "toothChart"))) { List <Procedure> listProcs = Procedures.GetCompletedForDateRange(DateTime.Today, DateTime.Today , listPatNums: new List <long>() { patNum } , includeNote: true , includeGroupNote: true ); if (sheetDef.SheetFieldDefs.Any(x => x.FieldType == SheetFieldType.Grid && x.FieldName == "ReferralLetterProceduresCompleted")) { SheetParameter.SetParameter(sheet, "CompletedProcs", listProcs); } if (sheetDef.SheetFieldDefs.Any(x => x.FieldType == SheetFieldType.Special && x.FieldName == "toothChart")) { SheetParameter.SetParameter(sheet, "toothChartImg", SheetPrinting.GetToothChartHelper(patNum, false, listProceduresFilteredOverride: listProcs)); } } SheetFiller.FillFields(sheet); SheetUtil.CalculateHeights(sheet); FormSF = new FormSheetFillEdit(sheet); FormSF.ShowDialog(); automationHappened = true; continue; case AutomationAction.SetApptASAP: aptNew = Appointments.GetOneApt(aptNum); if (aptNew == null) { MsgBox.Show("Automations", "Invalid appointment for automation."); automationHappened = true; continue; } aptOld = aptNew.Copy(); aptNew.Priority = ApptPriority.ASAP; Appointments.Update(aptNew, aptOld); //Appointments S-Class handles Signalods continue; case AutomationAction.SetApptType: aptNew = Appointments.GetOneApt(aptNum); if (aptNew == null) { MsgBox.Show("Automations", "Invalid appointment for automation."); automationHappened = true; continue; } aptOld = aptNew.Copy(); aptNew.AppointmentTypeNum = listAutomations[i].AppointmentTypeNum; AppointmentType aptTypeCur = AppointmentTypes.GetFirstOrDefault(x => x.AppointmentTypeNum == aptNew.AppointmentTypeNum); if (aptTypeCur != null) { aptNew.ColorOverride = aptTypeCur.AppointmentTypeColor; } Appointments.Update(aptNew, aptOld); //Appointments S-Class handles Signalods continue; case AutomationAction.PatRestrictApptSchedTrue: if (!Security.IsAuthorized(Permissions.PatientApptRestrict, true)) { SecurityLogs.MakeLogEntry(Permissions.PatientApptRestrict, patNum, "Attempt to restrict patient scheduling was blocked due to lack of user permission."); continue; } PatRestrictions.Upsert(patNum, PatRestrict.ApptSchedule); automationHappened = true; continue; case AutomationAction.PatRestrictApptSchedFalse: if (!Security.IsAuthorized(Permissions.PatientApptRestrict, true)) { SecurityLogs.MakeLogEntry(Permissions.PatientApptRestrict, patNum, "Attempt to allow patient scheduling was blocked due to lack of user permission."); continue; } PatRestrictions.RemovePatRestriction(patNum, PatRestrict.ApptSchedule); automationHappened = true; continue; } } return(automationHappened); }
private void FillRecall() { comboStatus.Items.Clear(); comboStatus.Items.Add(Lan.g(this, "None")); comboStatus.SelectedIndex = 0; for (int i = 0; i < DefB.Short[(int)DefCat.RecallUnschedStatus].Length; i++) { comboStatus.Items.Add(DefB.Short[(int)DefCat.RecallUnschedStatus][i].ItemName); if (DefB.Short[(int)DefCat.RecallUnschedStatus][i].DefNum == RecallCur.RecallStatus) { comboStatus.SelectedIndex = i + 1; } } textNote.Text = RecallCur.Note; //Now, the family list: listFamily.Items.Clear(); Appointment[] aptsOnePat; ListViewItem item; Recall[] recallList = Recalls.GetList(FamCur.List); DateTime dateDue; for (int i = 0; i < FamCur.List.Length; i++) { item = new ListViewItem(FamCur.GetNameInFamFLI(i)); if (FamCur.List[i].PatNum == PatCur.PatNum) { item.BackColor = Color.Silver; } item.SubItems.Add(Shared.AgeToString(FamCur.List[i].Age)); item.SubItems.Add(FamCur.List[i].Gender.ToString()); dateDue = DateTime.MinValue; for (int j = 0; j < recallList.Length; j++) { if (recallList[j].PatNum == FamCur.List[i].PatNum) { dateDue = recallList[j].DateDue; } } if (dateDue.Year < 1880) { item.SubItems.Add(""); } else { item.SubItems.Add(dateDue.ToShortDateString()); } if (dateDue <= DateTime.Today) { item.ForeColor = Color.Red; } aptsOnePat = Appointments.GetForPat(FamCur.List[i].PatNum); for (int a = 0; a < aptsOnePat.Length; a++) { if (aptsOnePat[a].AptDateTime.Date <= DateTime.Today) { continue; //disregard old appts. } item.SubItems.Add(aptsOnePat[a].AptDateTime.ToShortDateString()); break; //we only want one appt //could add condition here to add blank subitem if no date found } listFamily.Items.Add(item); //if(Patients.FamilyList[i].PatNum==Patients.Cur.PatNum){ // listFamily.Items[i].Selected=true;//doesn't work //} } }
public static bool Trigger <T>(AutomationTrigger trigger, List <string> procCodes, long patNum, long aptNum = 0, T triggerObj = default(T)) { if (patNum == 0) //Could happen for OpenPatient trigger { return(false); } List <Automation> listAutomations = Automations.GetDeepCopy(); bool automationHappened = false; for (int i = 0; i < listAutomations.Count; i++) { if (listAutomations[i].Autotrigger != trigger) { continue; } if (trigger == AutomationTrigger.CompleteProcedure || trigger == AutomationTrigger.ScheduleProcedure) { if (procCodes == null || procCodes.Count == 0) { continue; //fail silently } string[] arrayCodes = listAutomations[i].ProcCodes.Split(','); if (procCodes.All(x => !arrayCodes.Contains(x))) { continue; } } //matching automation item has been found //Get possible list of conditions that exist for this automation item List <AutomationCondition> autoConditionsList = AutomationConditions.GetListByAutomationNum(listAutomations[i].AutomationNum); if (autoConditionsList.Count > 0 && !CheckAutomationConditions(autoConditionsList, patNum, triggerObj)) { continue; } SheetDef sheetDef; Sheet sheet; FormSheetFillEdit FormSF; Appointment aptNew; Appointment aptOld; switch (listAutomations[i].AutoAction) { case AutomationAction.CreateCommlog: if (Plugins.HookMethod(null, "AutomationL.Trigger_CreateCommlog_start", patNum, aptNum, listAutomations[i].CommType, listAutomations[i].MessageContent, trigger)) { automationHappened = true; continue; } Commlog commlogCur = new Commlog(); commlogCur.PatNum = patNum; commlogCur.CommDateTime = DateTime.Now; commlogCur.CommType = listAutomations[i].CommType; commlogCur.Note = listAutomations[i].MessageContent; commlogCur.Mode_ = CommItemMode.None; commlogCur.UserNum = Security.CurUser.UserNum; commlogCur.IsNew = true; FormCommItem commItemView = new FormCommItem(commlogCur); commItemView.ShowDialog(); automationHappened = true; continue; case AutomationAction.PopUp: MessageBox.Show(listAutomations[i].MessageContent); automationHappened = true; continue; case AutomationAction.PopUpThenDisable10Min: Plugins.HookAddCode(null, "AutomationL.Trigger_PopUpThenDisable10Min_begin", listAutomations[i], procCodes, patNum); long automationNum = listAutomations[i].AutomationNum; bool hasAutomationBlock = FormOpenDental.DicBlockedAutomations.ContainsKey(automationNum); if (hasAutomationBlock && FormOpenDental.DicBlockedAutomations[automationNum].ContainsKey(patNum)) //Automation block exist for current patient. { continue; } if (hasAutomationBlock) { FormOpenDental.DicBlockedAutomations[automationNum].Add(patNum, DateTime.Now.AddMinutes(10)); //Disable for 10 minutes. } else //Add automationNum to higher level dictionary . { FormOpenDental.DicBlockedAutomations.Add(automationNum, new Dictionary <long, DateTime>() { { patNum, DateTime.Now.AddMinutes(10) } //Disable for 10 minutes. }); } MessageBox.Show(listAutomations[i].MessageContent); automationHappened = true; continue; case AutomationAction.PrintPatientLetter: case AutomationAction.ShowExamSheet: case AutomationAction.ShowConsentForm: sheetDef = SheetDefs.GetSheetDef(listAutomations[i].SheetDefNum); sheet = SheetUtil.CreateSheet(sheetDef, patNum); SheetParameter.SetParameter(sheet, "PatNum", patNum); SheetFiller.FillFields(sheet); SheetUtil.CalculateHeights(sheet); FormSF = new FormSheetFillEdit(sheet); FormSF.ShowDialog(); automationHappened = true; continue; case AutomationAction.PrintReferralLetter: long referralNum = RefAttaches.GetReferralNum(patNum); if (referralNum == 0) { MsgBox.Show("Automations", "This patient has no referral source entered."); automationHappened = true; continue; } sheetDef = SheetDefs.GetSheetDef(listAutomations[i].SheetDefNum); sheet = SheetUtil.CreateSheet(sheetDef, patNum); SheetParameter.SetParameter(sheet, "PatNum", patNum); SheetParameter.SetParameter(sheet, "ReferralNum", referralNum); //Don't fill these params if the sheet doesn't use them. if (sheetDef.SheetFieldDefs.Any(x => (x.FieldType == SheetFieldType.Grid && x.FieldName == "ReferralLetterProceduresCompleted") || (x.FieldType == SheetFieldType.Special && x.FieldName == "toothChart"))) { List <Procedure> listProcs = Procedures.GetCompletedForDateRange(DateTime.Today, DateTime.Today , listPatNums: new List <long>() { patNum } , includeNote: true , includeGroupNote: true ); if (sheetDef.SheetFieldDefs.Any(x => x.FieldType == SheetFieldType.Grid && x.FieldName == "ReferralLetterProceduresCompleted")) { SheetParameter.SetParameter(sheet, "CompletedProcs", listProcs); } if (sheetDef.SheetFieldDefs.Any(x => x.FieldType == SheetFieldType.Special && x.FieldName == "toothChart")) { SheetParameter.SetParameter(sheet, "toothChartImg", SheetPrinting.GetToothChartHelper(patNum, false, listProceduresFilteredOverride: listProcs)); } } SheetFiller.FillFields(sheet); SheetUtil.CalculateHeights(sheet); FormSF = new FormSheetFillEdit(sheet); FormSF.ShowDialog(); automationHappened = true; continue; case AutomationAction.SetApptASAP: aptNew = Appointments.GetOneApt(aptNum); if (aptNew == null) { MsgBox.Show("Automations", "Invalid appointment for automation."); automationHappened = true; continue; } aptOld = aptNew.Copy(); aptNew.Priority = ApptPriority.ASAP; Appointments.Update(aptNew, aptOld); //Appointments S-Class handles Signalods continue; case AutomationAction.SetApptType: aptNew = Appointments.GetOneApt(aptNum); if (aptNew == null) { MsgBox.Show("Automations", "Invalid appointment for automation."); automationHappened = true; continue; } aptOld = aptNew.Copy(); aptNew.AppointmentTypeNum = listAutomations[i].AppointmentTypeNum; AppointmentType aptTypeCur = AppointmentTypes.GetFirstOrDefault(x => x.AppointmentTypeNum == aptNew.AppointmentTypeNum); if (aptTypeCur != null) { aptNew.ColorOverride = aptTypeCur.AppointmentTypeColor; aptNew.Pattern = AppointmentTypes.GetTimePatternForAppointmentType(aptTypeCur); List <Procedure> listProcs = Appointments.ApptTypeMissingProcHelper(aptNew, aptTypeCur, new List <Procedure>()); Procedures.UpdateAptNums(listProcs.Select(x => x.ProcNum).ToList(), aptNew.AptNum, aptNew.AptStatus == ApptStatus.Planned); } Appointments.Update(aptNew, aptOld); //Appointments S-Class handles Signalods continue; case AutomationAction.PatRestrictApptSchedTrue: if (!Security.IsAuthorized(Permissions.PatientApptRestrict, true)) { SecurityLogs.MakeLogEntry(Permissions.PatientApptRestrict, patNum, "Attempt to restrict patient scheduling was blocked due to lack of user permission."); continue; } PatRestrictions.Upsert(patNum, PatRestrict.ApptSchedule); automationHappened = true; continue; case AutomationAction.PatRestrictApptSchedFalse: if (!Security.IsAuthorized(Permissions.PatientApptRestrict, true)) { SecurityLogs.MakeLogEntry(Permissions.PatientApptRestrict, patNum, "Attempt to allow patient scheduling was blocked due to lack of user permission."); continue; } PatRestrictions.RemovePatRestriction(patNum, PatRestrict.ApptSchedule); automationHappened = true; continue; case AutomationAction.PrintRxInstruction: List <RxPat> listRx = (List <RxPat>)(object) triggerObj; if (listRx == null) { //Got here via a pre-existing trigger that doesn't pass in triggerObj. We now block creation of automation triggers that could get //here via code that does not pass in triggerObj. continue; } //We go through each new Rx where the patient note isn't blank. //There should only usually be one new rx, but we'll loop just in case. foreach (RxPat rx in listRx.Where(x => !string.IsNullOrWhiteSpace(x.PatientInstruction))) { //This logic is an exact copy of FormRxManage.butPrintSelect_Click()'s logic when 1 Rx is selected. //If this is updated, that method needs to be updated as well. sheetDef = SheetDefs.GetSheetDef(listAutomations[i].SheetDefNum); sheet = SheetUtil.CreateSheet(sheetDef, patNum); SheetParameter.SetParameter(sheet, "RxNum", rx.RxNum); SheetFiller.FillFields(sheet); SheetUtil.CalculateHeights(sheet); FormSF = new FormSheetFillEdit(sheet); FormSF.ShowDialog(); automationHappened = true; } continue; case AutomationAction.ChangePatStatus: Patient pat = Patients.GetPat(patNum); Patient patOld = pat.Copy(); pat.PatStatus = listAutomations[i].PatStatus; //Don't allow changing status from Archived if this is a merged patient. if (patOld.PatStatus != pat.PatStatus && patOld.PatStatus == PatientStatus.Archived && PatientLinks.WasPatientMerged(patOld.PatNum)) { MsgBox.Show("FormPatientEdit", "Not allowed to change the status of a merged patient."); continue; } switch (pat.PatStatus) { case PatientStatus.Deceased: if (patOld.PatStatus != PatientStatus.Deceased) { List <Appointment> listFutureAppts = Appointments.GetFutureSchedApts(pat.PatNum); if (listFutureAppts.Count > 0) { string apptDates = string.Join("\r\n", listFutureAppts.Take(10).Select(x => x.AptDateTime.ToString())); if (listFutureAppts.Count > 10) { apptDates += "(...)"; } if (MessageBox.Show( Lan.g("FormPatientEdit", "This patient has scheduled appointments in the future") + ":\r\n" + apptDates + "\r\n" + Lan.g("FormPatientEdit", "Would you like to delete them and set the patient to Deceased?"), Lan.g("FormPatientEdit", "Delete future appointments?"), MessageBoxButtons.YesNo) == DialogResult.Yes) { foreach (Appointment appt in listFutureAppts) { Appointments.Delete(appt.AptNum, true); } } else { continue; } } } break; } //Re-activate or disable recalls depending on the the status that the patient is changing to. Patients.UpdateRecalls(pat, patOld, "ChangePatStatus automation"); if (Patients.Update(pat, patOld)) { SecurityLogs.MakeLogEntry(Permissions.PatientEdit, patNum, "Patient status changed from " + patOld.PatStatus.GetDescription() + " to " + listAutomations[i].PatStatus.GetDescription() + " through ChangePatStatus automation."); } automationHappened = true; continue; } } return(automationHappened); }
private void FillMain(){ DateTime dateFrom=PIn.Date(textDateFrom.Text); DateTime dateTo=PIn.Date(textDateTo.Text); long provNum=0; if(comboProv.SelectedIndex!=0) { provNum=ProviderC.ListShort[comboProv.SelectedIndex-1].ProvNum; } long clinicNum=0; if(comboClinic.SelectedIndex > 0) { clinicNum=Clinics.List[comboClinic.SelectedIndex-1].ClinicNum; } bool showRecalls=false; bool showNonRecalls=false; if(comboShowRecall.SelectedIndex==0 || comboShowRecall.SelectedIndex==1) {//All or Recall Only showRecalls=true; } if(comboShowRecall.SelectedIndex==0 || comboShowRecall.SelectedIndex==2) {//All or Exclude Recalls showNonRecalls=true; } Table=Appointments.GetConfirmList(dateFrom,dateTo,provNum,clinicNum,showRecalls,showNonRecalls); int scrollVal=grid.ScrollValue; grid.BeginUpdate(); grid.Columns.Clear(); ODGridColumn col=new ODGridColumn(Lan.g("TableConfirmList","Date Time"),70); grid.Columns.Add(col); col=new ODGridColumn(Lan.g("TableConfirmList","Patient"),80); grid.Columns.Add(col); col=new ODGridColumn(Lan.g("TableConfirmList","Age"),30); grid.Columns.Add(col); col=new ODGridColumn(Lan.g("TableConfirmList","Contact"),150); grid.Columns.Add(col); col=new ODGridColumn(Lan.g("TableConfirmList","Addr/Ph Note"),100); grid.Columns.Add(col); col=new ODGridColumn(Lan.g("TableConfirmList","Status"),80);//confirmed grid.Columns.Add(col); col=new ODGridColumn(Lan.g("TableConfirmList","Procs"),110); grid.Columns.Add(col); col=new ODGridColumn(Lan.g("TableConfirmList","Medical"),80); grid.Columns.Add(col); col=new ODGridColumn(Lan.g("TableConfirmList","Appt Note"),204); grid.Columns.Add(col); grid.Rows.Clear(); ODGridRow row; ODGridCell cell; for(int i=0;i<Table.Rows.Count;i++){ row=new ODGridRow(); //aptDateTime=PIn.PDateT(table.Rows[i][4].ToString()); row.Cells.Add(Table.Rows[i]["aptDateTime"].ToString()); //aptDateTime.ToShortDateString()+"\r\n"+aptDateTime.ToShortTimeString()); row.Cells.Add(Table.Rows[i]["patientName"].ToString()); row.Cells.Add(Table.Rows[i]["age"].ToString()); row.Cells.Add(Table.Rows[i]["contactMethod"].ToString()); row.Cells.Add(Table.Rows[i]["AddrNote"].ToString()); row.Cells.Add(Table.Rows[i]["confirmed"].ToString()); row.Cells.Add(Table.Rows[i]["ProcDescript"].ToString()); cell=new ODGridCell(Table.Rows[i]["medNotes"].ToString()); cell.ColorText=Color.Red; row.Cells.Add(cell); row.Cells.Add(Table.Rows[i]["Note"].ToString()); grid.Rows.Add(row); } grid.EndUpdate(); grid.ScrollValue=scrollVal; }
private void butNote_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.AppointmentCreate)) { return; } if (PatRestrictionL.IsRestricted(_patCur.PatNum, PatRestrict.ApptSchedule)) { return; } 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 = PrefC.GetLong(PrefName.PracticeDefaultProv); } else { aptCur.ProvNum = _patCur.PriProv; } aptCur.ProvHyg = _patCur.SecProv; aptCur.AptStatus = ApptStatus.PtNote; aptCur.ClinicNum = _patCur.ClinicNum; aptCur.TimeLocked = PrefC.GetBool(PrefName.AppointmentTimeIsLocked); if (IsInitialDoubleClick) //initially double clicked on appt module { aptCur.AptDateTime = DateTimeClicked; aptCur.Op = OpNumClicked; } else { //new appt will be placed on pinboard instead of specific time } try { if (!AppointmentL.IsSpecialtyMismatchAllowed(_patCur.PatNum, aptCur.ClinicNum)) { return; } Appointments.Insert(aptCur); } catch (ApplicationException ex) { MessageBox.Show(ex.Message); return; } FormApptEdit formApptEdit = new FormApptEdit(aptCur.AptNum); formApptEdit.IsNew = true; formApptEdit.ShowDialog(); if (formApptEdit.DialogResult != DialogResult.OK) { return; } ListAptNumsSelected.Add(aptCur.AptNum); if (IsInitialDoubleClick) { _otherResult = OtherResult.CreateNew; } else { _otherResult = OtherResult.NewToPinBoard; } DialogResult = DialogResult.OK; }
private void butEmail_Click(object sender,EventArgs e) { if(grid.Rows.Count==0) { MsgBox.Show(this,"There are no Patients in the table. Must have at least one."); return; } if(!EmailAddresses.ExistsValidEmail()) { MsgBox.Show(this,"You need to enter an SMTP server name in e-mail setup before you can send e-mail."); return; } if(PrefC.GetLong(PrefName.ConfirmStatusEmailed)==0) { MsgBox.Show(this,"You need to set a status first for confirmation e-mails in the Recall Setup window."); return; } if(grid.SelectedIndices.Length==0) { ContactMethod cmeth; for(int i=0;i<Table.Rows.Count;i++) { cmeth=(ContactMethod)PIn.Int(Table.Rows[i]["PreferConfirmMethod"].ToString()); if(cmeth!=ContactMethod.Email) { continue; } if(Table.Rows[i]["confirmed"].ToString()==DefC.GetName(DefCat.ApptConfirmed,PrefC.GetLong(PrefName.ConfirmStatusEmailed))) {//Already confirmed by email continue; } if(Table.Rows[i]["email"].ToString()=="") { continue; } grid.SetSelected(i,true); } if(grid.SelectedIndices.Length==0) { MsgBox.Show(this,"Confirmations have been sent to all patients of email type who also have an email address entered."); return; } } else {//deselect the ones that do not have email addresses specified int skipped=0; for(int i=grid.SelectedIndices.Length-1;i>=0;i--) { if(Table.Rows[grid.SelectedIndices[i]]["email"].ToString()=="") { skipped++; grid.SetSelected(grid.SelectedIndices[i],false); } } if(grid.SelectedIndices.Length==0) { MsgBox.Show(this,"None of the selected patients had email addresses entered."); return; } if(skipped>0) { MessageBox.Show(Lan.g(this,"Selected patients skipped due to missing email addresses: ")+skipped.ToString()); } } if(!MsgBox.Show(this,MsgBoxButtons.YesNo,"Send email to all of the selected patients?")) { return; } Cursor=Cursors.WaitCursor; EmailMessage message; string str=""; List<long> patNumsSelected=new List<long>(); List<long> patNumsFailed=new List<long>(); EmailAddress emailAddress; for(int i=0;i<grid.SelectedIndices.Length;i++){ message=new EmailMessage(); message.PatNum=PIn.Long(Table.Rows[grid.SelectedIndices[i]]["PatNum"].ToString()); message.ToAddress=Table.Rows[grid.SelectedIndices[i]]["email"].ToString();//Could be guarantor email. emailAddress=EmailAddresses.GetByClinic(PIn.Long(Table.Rows[grid.SelectedIndices[i]]["ClinicNum"].ToString())); message.FromAddress=emailAddress.SenderAddress; message.Subject=PrefC.GetString(PrefName.ConfirmEmailSubject); patNumsSelected.Add(message.PatNum); str=PrefC.GetString(PrefName.ConfirmEmailMessage); str=str.Replace("[NameF]",Table.Rows[grid.SelectedIndices[i]]["nameF"].ToString()); str=str.Replace("[NameFL]",Table.Rows[grid.SelectedIndices[i]]["nameFL"].ToString()); str=str.Replace("[date]",((DateTime)Table.Rows[grid.SelectedIndices[i]]["AptDateTime"]).ToShortDateString()); str=str.Replace("[time]",((DateTime)Table.Rows[grid.SelectedIndices[i]]["AptDateTime"]).ToShortTimeString()); message.BodyText=str; try { EmailMessages.SendEmailUnsecure(message,emailAddress); } catch { patNumsFailed.Add(message.PatNum); continue; } message.MsgDateTime=DateTime.Now; message.SentOrReceived=EmailSentOrReceived.Sent; EmailMessages.Insert(message); Appointments.SetConfirmed(PIn.Long(Table.Rows[grid.SelectedIndices[i]]["AptNum"].ToString()),PrefC.GetLong(PrefName.ConfirmStatusEmailed)); } Cursor=Cursors.Default; if(patNumsFailed.Count==grid.SelectedIndices.Length){ //all failed //no need to refresh MsgBox.Show(this,"All emails failed. Possibly due to invalid email addresses, a loss of connectivity, or a firewall blocking communication.");//msg: all failed return; } else if(patNumsFailed.Count>0){//if some failed FillMain(); //reselect only the failed ones for(int i=0;i<Table.Rows.Count;i++) { //table.Rows.Count=grid.Rows.Count long patNum=PIn.Long(Table.Rows[i]["PatNum"].ToString()); if(patNumsFailed.Contains(patNum)) { grid.SetSelected(i,true); } } MsgBox.Show(this,"Some emails failed to send."); return; } //none failed FillMain(); //reselect the original list for(int i=0;i<Table.Rows.Count;i++) { long patNum=PIn.Long(Table.Rows[i]["PatNum"].ToString()); if(patNumsSelected.Contains(patNum)) { grid.SetSelected(i,true); } } }
private void butAddTo_Click(object sender, EventArgs e) { if (!Security.IsAuthorized(Permissions.RefAttachAdd)) { return; } FormReferralSelect FormRS = new FormReferralSelect(); FormRS.IsSelectionMode = true; FormRS.ShowDialog(); if (FormRS.DialogResult != DialogResult.OK) { return; } RefAttach refattach = new RefAttach(); refattach.ReferralNum = FormRS.SelectedReferral.ReferralNum; refattach.PatNum = PatNum; refattach.RefType = ReferralType.RefTo; refattach.RefDate = DateTimeOD.Today; refattach.IsTransitionOfCare = FormRS.SelectedReferral.IsDoctor; refattach.ItemOrder = RefAttachList.Select(x => x.ItemOrder + 1).OrderByDescending(x => x).FirstOrDefault();//Max+1 or 0 refattach.ProcNum = ProcNum; //We want to help EHR users meet their measures. Therefore, we are going to make an educated guess as to who is making this referral. //We are doing this for non-EHR users as well because we think it might be nice automation. long provNumLastAppt = Appointments.GetProvNumFromLastApptForPat(PatNum); if (Security.CurUser.ProvNum != 0) { refattach.ProvNum = Security.CurUser.ProvNum; } else if (provNumLastAppt != 0) { refattach.ProvNum = provNumLastAppt; } else { refattach.ProvNum = Patients.GetProvNum(PatNum); } RefAttaches.Insert(refattach); SecurityLogs.MakeLogEntry(Permissions.RefAttachAdd, PatNum, "Referred To " + Referrals.GetNameFL(refattach.ReferralNum)); if (PrefC.GetBool(PrefName.AutomaticSummaryOfCareWebmail)) { FormRefAttachEdit FormRAE = new FormRefAttachEdit(); FormRAE.RefAttachCur = refattach; FormRAE.ShowDialog(); //In order to help offices meet EHR Summary of Care measure 1 of Core Measure 15 of 17, we are going to send a summary of care to the patient portal behind the scenes. //We can send the summary of care to the patient instead of to the Dr. because of the following point in the Additional Information section of the Core Measure: //"The EP can send an electronic or paper copy of the summary care record directly to the next provider or can provide it to the patient to deliver to the next provider, if the patient can reasonably expected to do so and meet Measure 1." //We will only send the summary of care if the ref attach is a TO referral and is a transition of care. if (FormRAE.DialogResult == DialogResult.OK && refattach.RefType == ReferralType.RefTo && refattach.IsTransitionOfCare) { try { //This is like FormEhrClinicalSummary.butSendToPortal_Click such that the email gets treated like a web mail. Patient PatCur = Patients.GetPat(PatNum); string strCcdValidationErrors = EhrCCD.ValidateSettings(); if (strCcdValidationErrors != "") { throw new Exception(); } strCcdValidationErrors = EhrCCD.ValidatePatient(PatCur); if (strCcdValidationErrors != "") { throw new Exception(); } Provider prov = null; if (Security.CurUser.ProvNum != 0) { prov = Providers.GetProv(Security.CurUser.ProvNum); } else { prov = Providers.GetProv(PatCur.PriProv); } EmailMessage msgWebMail = new EmailMessage(); //New mail object msgWebMail.FromAddress = prov.GetFormalName(); //Adding from address msgWebMail.ToAddress = PatCur.GetNameFL(); //Adding to address msgWebMail.PatNum = PatCur.PatNum; //Adding patient number msgWebMail.SentOrReceived = EmailSentOrReceived.WebMailSent; //Setting to sent msgWebMail.ProvNumWebMail = prov.ProvNum; //Adding provider number msgWebMail.Subject = "Referral To " + FormRS.SelectedReferral.GetNameFL(); msgWebMail.BodyText = "You have been referred to another provider. Your summary of care is attached.\r\n" + "You may give a copy of this summary of care to the referred provider if desired.\r\n" + "The contact information for the doctor you are being referred to is as follows:\r\n" + "\r\n"; //Here we provide the same information that would go out on a Referral Slip. //When the user prints a Referral Slip, the doctor referred to information is included and contains the doctor's name, address, and phone. msgWebMail.BodyText += "Name: " + FormRS.SelectedReferral.GetNameFL() + "\r\n"; if (FormRS.SelectedReferral.Address.Trim() != "") { msgWebMail.BodyText += "Address: " + FormRS.SelectedReferral.Address.Trim() + "\r\n"; if (FormRS.SelectedReferral.Address2.Trim() != "") { msgWebMail.BodyText += "\t" + FormRS.SelectedReferral.Address2.Trim() + "\r\n"; } msgWebMail.BodyText += "\t" + FormRS.SelectedReferral.City + " " + FormRS.SelectedReferral.ST + " " + FormRS.SelectedReferral.Zip + "\r\n"; } if (FormRS.SelectedReferral.Telephone != "") { msgWebMail.BodyText += "Phone: (" + FormRS.SelectedReferral.Telephone.Substring(0, 3) + ")" + FormRS.SelectedReferral.Telephone.Substring(3, 3) + "-" + FormRS.SelectedReferral.Telephone.Substring(6) + "\r\n"; } msgWebMail.BodyText += "\r\n" + "To view the Summary of Care for the referral to this provider:\r\n" + "1) Download all attachments to the same folder. Do not rename the files.\r\n" + "2) Open the ccd.xml file in an internet browser."; msgWebMail.MsgDateTime = DateTime.Now; //Message time is now msgWebMail.PatNumSubj = PatCur.PatNum; //Subject of the message is current patient string ccd = ""; Cursor = Cursors.WaitCursor; ccd = EhrCCD.GenerateSummaryOfCare(Patients.GetPat(PatNum)); //Create summary of care, can throw exceptions but they're caught below msgWebMail.Attachments.Add(EmailAttaches.CreateAttach("ccd.xml", Encoding.UTF8.GetBytes(ccd))); //Create summary of care attachment, can throw exceptions but caught below msgWebMail.Attachments.Add(EmailAttaches.CreateAttach("ccd.xsl", Encoding.UTF8.GetBytes(FormEHR.GetEhrResource("CCD")))); //Create xsl attachment, can throw exceptions EmailMessages.Insert(msgWebMail); //Insert mail into DB for patient portal EhrMeasureEvent newMeasureEvent = new EhrMeasureEvent(); newMeasureEvent.DateTEvent = DateTime.Now; newMeasureEvent.EventType = EhrMeasureEventType.SummaryOfCareProvidedToDr; newMeasureEvent.PatNum = PatCur.PatNum; newMeasureEvent.FKey = FormRAE.RefAttachCur.RefAttachNum; //Can be 0 if user didn't pick a referral for some reason. EhrMeasureEvents.Insert(newMeasureEvent); } catch { //We are just trying to be helpful so it doesn't really matter if something failed above. //They can simply go to the EHR dashboard and send the summary of care manually like they always have. They will get detailed validation errors there. MsgBox.Show(this, "There was a problem automatically sending a summary of care. Please go to the EHR dashboard to send a summary of care to meet the summary of care core measure."); } } } Cursor = Cursors.Default; FillGrid(); for (int i = 0; i < RefAttachList.Count; i++) { if (RefAttachList[i].ReferralNum == refattach.ReferralNum) { gridMain.SetSelected(i, true); } } }
private void FormPatientUnschedList_Load(object sender, EventArgs e) { this.Text = " " + _patCur.GetNameLF(); _listUnschedApptsForPat = Appointments.GetUnschedApptsForPat(_patCur.PatNum); FillGrid(); }
private void Filltb() { SelectedPatNum = PatCur.PatNum; //just in case user has selected a different family member RecallList = Recalls.GetList(FamCur.List); Appointment[] aptsOnePat; listFamily.Items.Clear(); ListViewItem item; DateTime dateDue; for (int i = 0; i < FamCur.List.Length; i++) { item = new ListViewItem(FamCur.GetNameInFamFLI(i)); if (FamCur.List[i].PatNum == PatCur.PatNum) { item.BackColor = Color.Silver; } item.SubItems.Add(FamCur.List[i].Age.ToString()); item.SubItems.Add(FamCur.List[i].Gender.ToString()); dateDue = DateTime.MinValue; for (int j = 0; j < RecallList.Length; j++) { if (RecallList[j].PatNum == FamCur.List[i].PatNum) { dateDue = RecallList[j].DateDue; } } if (dateDue.Year < 1880) { item.SubItems.Add(""); } else { item.SubItems.Add(dateDue.ToShortDateString()); } if (dateDue <= DateTime.Today) { item.ForeColor = Color.Red; } aptsOnePat = Appointments.GetForPat(FamCur.List[i].PatNum); for (int a = 0; a < aptsOnePat.Length; a++) { if (aptsOnePat[a].AptDateTime.Date <= DateTime.Today) { continue; //disregard old appts. } item.SubItems.Add(aptsOnePat[a].AptDateTime.ToShortDateString()); break; //we only want one appt //could add condition here to add blank subitem if no date found } listFamily.Items.Add(item); } if (PatCur.NextAptNum == -1) { checkDone.Checked = true; } else { checkDone.Checked = false; } ListOth = Appointments.GetForPat(PatCur.PatNum); tbApts.ResetRows(ListOth.Length); tbApts.SetGridColor(Color.DarkGray); for (int i = 0; i < ListOth.Length; i++) { tbApts.Cell[0, i] = ListOth[i].AptStatus.ToString(); if (ListOth[i].AptDateTime.Year > 1880) { //only regular still scheduled appts if (ListOth[i].AptStatus != ApptStatus.Planned && ListOth[i].AptStatus != ApptStatus.PtNote && ListOth[i].AptStatus != ApptStatus.PtNoteCompleted && ListOth[i].AptStatus != ApptStatus.UnschedList && ListOth[i].AptStatus != ApptStatus.Broken) { tbApts.Cell[1, i] = ListOth[i].AptDateTime.ToString("d"); tbApts.Cell[2, i] = ListOth[i].AptDateTime.ToString("t"); if (ListOth[i].AptDateTime < DateTime.Today) //Past { tbApts.SetBackColorRow(i, (DefB.Long[(int)DefCat.ProgNoteColors][11].ItemColor)); tbApts.SetTextColorRow(i, (DefB.Long[(int)DefCat.ProgNoteColors][10].ItemColor)); } else if (ListOth[i].AptDateTime.Date == DateTime.Today.Date) //Today { tbApts.SetBackColorRow(i, (DefB.Long[(int)DefCat.ProgNoteColors][9].ItemColor)); tbApts.SetTextColorRow(i, (DefB.Long[(int)DefCat.ProgNoteColors][8].ItemColor)); tbApts.Cell[0, i] = Lan.g(this, "Today"); } else if (ListOth[i].AptDateTime > DateTime.Today) //Future { tbApts.SetBackColorRow(i, DefB.Long[(int)DefCat.ProgNoteColors][13].ItemColor); tbApts.SetTextColorRow(i, (DefB.Long[(int)DefCat.ProgNoteColors][12].ItemColor)); } } else if (ListOth[i].AptStatus == ApptStatus.Planned) //show line for planned appt { tbApts.SetTextColorRow(i, DefB.Long[(int)DefCat.ProgNoteColors][16].ItemColor); tbApts.SetBackColorRow(i, DefB.Long[(int)DefCat.ProgNoteColors][17].ItemColor); tbApts.Cell[0, i] = Lan.g("enumApptStatus", "Planned"); } else if (ListOth[i].AptStatus == ApptStatus.PtNote) { tbApts.SetTextColorRow(i, DefB.Long[(int)DefCat.ProgNoteColors][18].ItemColor); tbApts.SetBackColorRow(i, DefB.Long[(int)DefCat.ProgNoteColors][19].ItemColor); tbApts.Cell[0, i] = Lan.g("enumApptStatus", "PtNote"); } else if (ListOth[i].AptStatus == ApptStatus.PtNoteCompleted) { tbApts.SetTextColorRow(i, DefB.Long[(int)DefCat.ProgNoteColors][20].ItemColor); tbApts.SetBackColorRow(i, DefB.Long[(int)DefCat.ProgNoteColors][21].ItemColor); tbApts.Cell[0, i] = Lan.g("enumApptStatus", "PtNoteCompleted"); } else if (ListOth[i].AptStatus == ApptStatus.Broken | ListOth[i].AptStatus == ApptStatus.UnschedList) { if (ListOth[i].AptStatus == ApptStatus.Broken) { tbApts.Cell[0, i] = Lan.g("enumApptStatus", "Broken"); } else { tbApts.Cell[0, i] = Lan.g("enumApptStatus", "UnschedList"); } tbApts.SetTextColorRow(i, DefB.Long[(int)DefCat.ProgNoteColors][14].ItemColor); tbApts.SetBackColorRow(i, DefB.Long[(int)DefCat.ProgNoteColors][15].ItemColor); } } else { tbApts.Cell[1, i] = ""; tbApts.Cell[2, i] = ""; } tbApts.Cell[3, i] = (ListOth[i].Pattern.Length * 5).ToString(); tbApts.Cell[4, i] = ListOth[i].ProcDescript; tbApts.Cell[5, i] = ListOth[i].Note; } textFinUrg.Text = PatCur.FamFinUrgNote; tbApts.LayoutTables(); }
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; }
private void butText_Click(object sender,EventArgs e) { long patNum; string wirelessPhone; YN txtMsgOk; if(grid.Rows.Count==0) { MsgBox.Show(this,"There are no Patients in the table. Must have at least one."); return; } if(PrefC.GetLong(PrefName.ConfirmStatusTextMessaged)==0) { MsgBox.Show(this,"You need to set a status first for confirmation text messages in the Recall Setup window."); return; } if(grid.SelectedIndices.Length==0) {//None selected. Select all of type text that are not yet confirmed by text message. ContactMethod cmeth; for(int i=0;i<Table.Rows.Count;i++) { cmeth=(ContactMethod)PIn.Int(Table.Rows[i]["PreferConfirmMethod"].ToString()); if(cmeth!=ContactMethod.TextMessage) { continue; } if(Table.Rows[i]["confirmed"].ToString()==DefC.GetName(DefCat.ApptConfirmed,PrefC.GetLong(PrefName.ConfirmStatusTextMessaged))) {//Already confirmed by text continue; } if(!Table.Rows[i]["contactMethod"].ToString().StartsWith("Text:")) {//Check contact method continue; } grid.SetSelected(i,true); } if(grid.SelectedIndices.Length==0) { MsgBox.Show(this,"All patients of text message type have been sent confirmations."); return; } } //deselect the ones that do not have text messages specified or are not OK to send texts to or have already been texted int skipped=0; for(int i=grid.SelectedIndices.Length-1;i>=0;i--) { wirelessPhone=Table.Rows[grid.SelectedIndices[i]]["WirelessPhone"].ToString(); if(wirelessPhone=="") {//Check for wireless number skipped++; grid.SetSelected(grid.SelectedIndices[i],false); continue; } txtMsgOk=(YN)PIn.Int(Table.Rows[grid.SelectedIndices[i]]["TxtMsgOk"].ToString()); if(txtMsgOk==YN.Unknown && PrefC.GetBool(PrefName.TextMsgOkStatusTreatAsNo)) {//Check if OK to text skipped++; grid.SetSelected(grid.SelectedIndices[i],false); continue; } if(txtMsgOk==YN.No){//Check if OK to text skipped++; grid.SetSelected(grid.SelectedIndices[i],false); continue; } } if(grid.SelectedIndices.Length==0) { MsgBox.Show(this,"None of the selected patients have wireless phone numbers and are OK to text."); return; } if(skipped>0) { MessageBox.Show(Lan.g(this,"Selected patients skipped: ")+skipped.ToString()); } if(!MsgBox.Show(this,MsgBoxButtons.YesNo,"Send text message to all of the selected patients?")) { return; } Cursor=Cursors.WaitCursor; FormTxtMsgEdit FormTME=new FormTxtMsgEdit(); string message=""; //Appointment apt; for(int i=0;i<grid.SelectedIndices.Length;i++){ patNum=PIn.Long(Table.Rows[grid.SelectedIndices[i]]["PatNum"].ToString()); wirelessPhone=PIn.String(Table.Rows[grid.SelectedIndices[i]]["WirelessPhone"].ToString()); txtMsgOk=((YN)PIn.Int(Table.Rows[grid.SelectedIndices[i]]["TxtMsgOk"].ToString())); message=PrefC.GetString(PrefName.ConfirmTextMessage); message=message.Replace("[NameF]",Table.Rows[grid.SelectedIndices[i]]["nameF"].ToString()); message=message.Replace("[NameFL]",Table.Rows[grid.SelectedIndices[i]]["nameFL"].ToString()); message=message.Replace("[date]",((DateTime)Table.Rows[grid.SelectedIndices[i]]["AptDateTime"]).ToShortDateString()); message=message.Replace("[time]",((DateTime)Table.Rows[grid.SelectedIndices[i]]["AptDateTime"]).ToShortTimeString()); FormTME.SendText(patNum,wirelessPhone,message,txtMsgOk); Appointments.SetConfirmed(PIn.Long(Table.Rows[grid.SelectedIndices[i]]["AptNum"].ToString()),PrefC.GetLong(PrefName.ConfirmStatusTextMessaged)); } FillMain(); Cursor=Cursors.Default; }
private void FormLabCaseEdit_Load(object sender, System.EventArgs e) { textPatient.Text = Patients.GetPat(CaseCur.PatNum).GetNameFL(); ListLabs = Laboratories.Refresh(); for (int i = 0; i < ListLabs.Count; i++) { listLab.Items.Add(ListLabs[i].Description + " " + ListLabs[i].Phone); if (ListLabs[i].LaboratoryNum == CaseCur.LaboratoryNum) { listLab.SelectedIndex = i; } } for (int i = 0; i < Providers.List.Length; i++) { comboProv.Items.Add(Providers.List[i].Abbr); if (Providers.List[i].ProvNum == CaseCur.ProvNum) { comboProv.SelectedIndex = i; } } Appointment apt = Appointments.GetOneApt(CaseCur.AptNum); if (apt != null) { if (apt.AptStatus == ApptStatus.UnschedList) { textAppointment.Text = Lan.g(this, "Unscheduled"); } else { textAppointment.Text = apt.AptDateTime.ToShortDateString() + " " + apt.AptDateTime.ToShortTimeString(); } textAppointment.Text += ", " + apt.ProcDescript; } apt = Appointments.GetOneApt(CaseCur.PlannedAptNum); if (apt != null) { textPlanned.Text = apt.ProcDescript; if (textPlanned.Text == "") { textPlanned.Text = Lan.g(this, "Attached"); } } if (CaseCur.DateTimeCreated.Year > 1880) { textDateCreated.Text = CaseCur.DateTimeCreated.ToString(); } if (CaseCur.DateTimeSent.Year > 1880) { textDateSent.Text = CaseCur.DateTimeSent.ToString(); } if (CaseCur.DateTimeRecd.Year > 1880) { textDateRecd.Text = CaseCur.DateTimeRecd.ToString(); } if (CaseCur.DateTimeChecked.Year > 1880) { textDateChecked.Text = CaseCur.DateTimeChecked.ToString(); } if (CaseCur.DateTimeDue.Year > 1880) { textDateDue.Text = CaseCur.DateTimeDue.ToShortDateString() + " " + CaseCur.DateTimeDue.ToShortTimeString(); } textInstructions.Text = CaseCur.Instructions; }
private void FormEhrAptObsEdit_Load(object sender, EventArgs e) { _appt = Appointments.GetOneApt(_ehrAptObsCur.AptNum); comboObservationQuestion.Items.Clear(); string[] arrayQuestionNames = Enum.GetNames(typeof(EhrAptObsIdentifier)); for (int i = 0; i < arrayQuestionNames.Length; i++) { comboObservationQuestion.Items.Add(arrayQuestionNames[i]); EhrAptObsIdentifier ehrAptObsIdentifier = (EhrAptObsIdentifier)i; if (_ehrAptObsCur.IdentifyingCode == ehrAptObsIdentifier) { comboObservationQuestion.SelectedIndex = i; } } listValueType.Items.Clear(); string[] arrayValueTypeNames = Enum.GetNames(typeof(EhrAptObsType)); for (int i = 0; i < arrayValueTypeNames.Length; i++) { listValueType.Items.Add(arrayValueTypeNames[i]); EhrAptObsType ehrAptObsType = (EhrAptObsType)i; if (_ehrAptObsCur.ValType == ehrAptObsType) { listValueType.SelectedIndex = i; } } if (_ehrAptObsCur.ValType == EhrAptObsType.Coded) { _strValCodeSystem = _ehrAptObsCur.ValCodeSystem; if (_ehrAptObsCur.ValCodeSystem == "LOINC") { _loincValue = Loincs.GetByCode(_ehrAptObsCur.ValReported); textValue.Text = _loincValue.NameShort; } else if (_ehrAptObsCur.ValCodeSystem == "SNOMEDCT") { _snomedValue = Snomeds.GetByCode(_ehrAptObsCur.ValReported); textValue.Text = _snomedValue.Description; } else if (_ehrAptObsCur.ValCodeSystem == "ICD9") { _icd9Value = ICD9s.GetByCode(_ehrAptObsCur.ValReported); textValue.Text = _icd9Value.Description; } else if (_ehrAptObsCur.ValCodeSystem == "ICD10") { _icd10Value = Icd10s.GetByCode(_ehrAptObsCur.ValReported); textValue.Text = _icd10Value.Description; } } else { textValue.Text = _ehrAptObsCur.ValReported; } comboUnits.Items.Clear(); comboUnits.Items.Add("none"); comboUnits.SelectedIndex = 0; List <string> listUcumCodes = Ucums.GetAllCodes(); for (int i = 0; i < listUcumCodes.Count; i++) { string ucumCode = listUcumCodes[i]; comboUnits.Items.Add(ucumCode); if (ucumCode == _ehrAptObsCur.UcumCode) { comboUnits.SelectedIndex = i + 1; } } SetFlags(); }
private void FillGrid() { Cursor = Cursors.WaitCursor; string order = ""; switch (comboOrder.SelectedIndex) { case 0: order = "status"; break; case 1: order = "alph"; break; case 2: order = "date"; break; } long provNum = 0; if (comboProv.SelectedIndex != 0) { provNum = ProviderC.ListShort[comboProv.SelectedIndex - 1].ProvNum; } long siteNum = 0; if (!PrefC.GetBool(PrefName.EasyHidePublicHealth) && comboSite.SelectedIndex != 0) { siteNum = SiteC.List[comboSite.SelectedIndex - 1].SiteNum; } long clinicNum = 0; if (comboClinic.SelectedIndex > 0) { clinicNum = Clinics.List[comboClinic.SelectedIndex - 1].ClinicNum; } AptList = Appointments.RefreshPlannedTracker(order, provNum, siteNum, clinicNum); gridMain.BeginUpdate(); gridMain.Columns.Clear(); ODGridColumn col = new ODGridColumn(Lan.g(this, "Patient"), 140); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g(this, "Date"), 65); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g(this, "Status"), 110); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g(this, "Prov"), 50); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g(this, "Procedures"), 150); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g(this, "Notes"), 200); gridMain.Columns.Add(col); gridMain.Rows.Clear(); ODGridRow row; for (int i = 0; i < AptList.Count; i++) { row = new ODGridRow(); row.Cells.Add(patientNames[AptList[i].PatNum]); if (AptList[i].AptDateTime.Year < 1880) { row.Cells.Add(""); } else { row.Cells.Add(AptList[i].AptDateTime.ToShortDateString()); } row.Cells.Add(DefC.GetName(DefCat.RecallUnschedStatus, AptList[i].UnschedStatus)); if (AptList[i].IsHygiene) { row.Cells.Add(Providers.GetAbbr(AptList[i].ProvHyg)); } else { row.Cells.Add(Providers.GetAbbr(AptList[i].ProvNum)); } row.Cells.Add(AptList[i].ProcDescript); row.Cells.Add(AptList[i].Note); gridMain.Rows.Add(row); } gridMain.EndUpdate(); Cursor = Cursors.Default; }