///<summary>Used when printing recall cards to make a commlog entry for everyone at once.</summary> public static void InsertForRecallPostcard(int patNum) { int recallType = Commlogs.GetTypeAuto(CommItemTypeAuto.RECALL); string command; if (recallType != 0) { command = "SELECT COUNT(*) FROM commlog WHERE "; if (FormChooseDatabase.DBtype == DatabaseType.Oracle) { command += "TO_DATE(CommDateTime) = " + POut.PDate(MiscData.GetNowDateTime()); } else //Assume MySQL { command += "DATE(CommDateTime) = CURDATE()"; } command += " AND PatNum=" + POut.PInt(patNum) + " AND CommType=" + POut.PInt(recallType) + " AND Mode_=2 AND SentOrReceived=1"; if (General.GetCount(command) != "0") { return; } } Commlog com = new Commlog(); com.PatNum = patNum; com.CommDateTime = DateTime.Now; com.CommType = recallType; com.Mode_ = CommItemMode.Mail; com.SentOrReceived = CommSentOrReceived.Sent; com.Note = Lan.g("FormRecallList", "Sent recall postcard"); Insert(com); }
///<summary>Sends text message to callfire. If patNum=0 will not create commlog entry.</summary> private bool SendCallFire(long patNum, string wirelessPhone, string message) { string key = ProgramProperties.GetPropVal(ProgramName.CallFire, "Key From CallFire"); string msg = wirelessPhone + "," + message.Replace(",", ""); //ph#,msg Commas in msg cause error. try { CallFireService.SMSService callFire = new CallFireService.SMSService(); callFire.sendSMSCampaign( key, new string[] { msg }, "Open Dental"); } catch (Exception ex) { MsgBox.Show(this, "Error sending text message.\r\n\r\n" + ex.Message); return(false); } if (patNum == 0) //No patient selected, do not make commlog. { return(true); } Commlog commlog = new Commlog(); commlog.CommDateTime = DateTime.Now; commlog.DateTStamp = DateTime.Now; commlog.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.TEXT); commlog.Mode_ = CommItemMode.Text; commlog.Note = msg;//phone,note commlog.PatNum = patNum; commlog.SentOrReceived = CommSentOrReceived.Sent; commlog.UserNum = Security.CurUser.UserNum; commlog.DateTimeEnd = DateTime.Now; Commlogs.Insert(commlog); SecurityLogs.MakeLogEntry(Permissions.CommlogEdit, commlog.PatNum, "Insert Text Message"); return(true); }
private void butStationary_Click(object sender, EventArgs e) { if (PrefB.GetString("StationaryDocument") == "") { MsgBox.Show(this, "You must setup your stationary document and word processor path in Setup | Misc"); return; } Cursor = Cursors.AppStarting; PtLetter_ToClipboard(); try { this.Cursor = Cursors.AppStarting; string patFolder = ODFileUtils.CombinePaths( FormPath.GetPreferredImagePath(), PatCur.ImageFolder.Substring(0, 1), PatCur.ImageFolder); //string ProgName = @"C:\Program Files\OpenOffice.org 2.0\program\swriter.exe"; //string ProgName = PrefB.GetString("WordProcessorPath"); string TheFile = ODFileUtils.CombinePaths(patFolder, "Letter_" + DateTime.Now.ToFileTime() + ".doc"); try{ File.Copy( ODFileUtils.CombinePaths(FormPath.GetPreferredImagePath(), PrefB.GetString("StationaryDocument")), TheFile); DialogResult = DialogResult.OK; } catch { } try { Process.Start(TheFile); } catch { } this.Cursor = Cursors.Default; Commlog CommlogCur = new Commlog(); CommlogCur.CommDateTime = DateTime.Now; CommlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.MISC); CommlogCur.PatNum = PatCur.PatNum; CommlogCur.Note = Lan.g(this, "Letter sent: See Images for this date."); Commlogs.Insert(CommlogCur); } catch { Cursor = Cursors.Default; MsgBox.Show(this, "Cannot find stationary document. Or another problem exists."); } }
private void butPreview_Click(object sender, System.EventArgs e) { #if !DISABLE_MICROSOFT_OFFICE if (listLetters.SelectedIndex == -1) { MsgBox.Show(this, "Please select a letter first."); return; } LetterMerge letterCur = ListForCat[listLetters.SelectedIndex]; letterCur.ImageFolder = comboImageCategory.SelectedTag <Def>().DefNum; string templateFile = ODFileUtils.CombinePaths(PrefC.GetString(PrefName.LetterMergePath), letterCur.TemplateName); string dataFile = ODFileUtils.CombinePaths(PrefC.GetString(PrefName.LetterMergePath), letterCur.DataFileName); if (!File.Exists(templateFile)) { MsgBox.Show(this, "Template file does not exist."); return; } if (!CreateDataFile(dataFile, letterCur)) { return; } Word.MailMerge wrdMailMerge; //Create an instance of Word. Word.Application WrdApp; try{ WrdApp = LetterMerges.WordApp; } catch { MsgBox.Show(this, "Error. Is Word installed?"); return; } string errorMessage = ""; //Open a document. try { Object oName = templateFile; wrdDoc = WrdApp.Documents.Open(ref oName, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); wrdDoc.Select(); } catch (Exception ex) { errorMessage = Lan.g(this, "Error opening document:") + "\r\n" + ex.Message; MessageBox.Show(errorMessage); return; } //Attach the data file. try { wrdMailMerge = wrdDoc.MailMerge; wrdDoc.MailMerge.OpenDataSource(dataFile, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); wrdMailMerge.Destination = Word.WdMailMergeDestination.wdSendToNewDocument; wrdMailMerge.Execute(ref oFalse); } catch (Exception ex) { errorMessage = Lan.g(this, "Error attaching data file:") + "\r\n" + ex.Message; MessageBox.Show(errorMessage); return; } if (letterCur.ImageFolder != 0) //if image folder exist for this letter, save to AtoZ folder //Open document from the atoz folder. { try { WrdApp.Activate(); string tempFilePath = ODFileUtils.CreateRandomFile(Path.GetTempPath(), GetFileExtensionForWordDoc(templateFile)); Object oFileName = tempFilePath; WrdApp.ActiveDocument.SaveAs(oFileName); //save the document to temp location Document doc = SaveToImageFolder(tempFilePath, letterCur); string patFolder = ImageStore.GetPatientFolder(PatCur, ImageStore.GetPreferredAtoZpath()); string fileName = ImageStore.GetFilePath(doc, patFolder); if (!FileAtoZ.Exists(fileName)) { throw new ApplicationException(Lans.g("LetterMerge", "Error opening document" + " " + doc.FileName)); } FileAtoZ.StartProcess(fileName); WrdApp.ActiveDocument.Close(); //Necessary since we created an extra document try { File.Delete(tempFilePath); //Clean up the temp file } catch (Exception ex) { ex.DoNothing(); } } catch (Exception ex) { FriendlyException.Show(Lan.g(this, "Error saving file to the Image module:") + "\r\n" + ex.Message, ex); } } //Close the original form document since just one record. try { wrdDoc.Saved = true; wrdDoc.Close(ref oFalse, ref oMissing, ref oMissing); } catch (Exception ex) { errorMessage = Lan.g(this, "Error closing document:") + "\r\n" + ex.Message; MessageBox.Show(errorMessage); return; } //At this point, Word remains open with just one new document. try { WrdApp.Activate(); if (WrdApp.WindowState == Word.WdWindowState.wdWindowStateMinimize) { WrdApp.WindowState = Word.WdWindowState.wdWindowStateMaximize; } } catch (Exception ex) { errorMessage = Lan.g(this, "Error showing Microsoft Word:") + "\r\n" + ex.Message; MessageBox.Show(errorMessage); return; } wrdMailMerge = null; wrdDoc = null; Commlog CommlogCur = new Commlog(); CommlogCur.CommDateTime = DateTime.Now; CommlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.MISC); CommlogCur.Mode_ = CommItemMode.Mail; CommlogCur.SentOrReceived = CommSentOrReceived.Sent; CommlogCur.PatNum = PatCur.PatNum; CommlogCur.Note = "Letter sent: " + letterCur.Description + ". "; CommlogCur.UserNum = Security.CurUser.UserNum; Commlogs.Insert(CommlogCur); #else MessageBox.Show(this, "This version of Open Dental does not support Microsoft Word."); #endif //this window now closes regardless of whether the user saved the comm item. DialogResult = DialogResult.OK; }
private void butPrint_Click(object sender, System.EventArgs e) { #if DISABLE_MICROSOFT_OFFICE MessageBox.Show(this, "This version of Open Dental does not support Microsoft Word."); return; #endif if (listLetters.SelectedIndex == -1) { MsgBox.Show(this, "Please select a letter first."); return; } LetterMerge letterCur = ListForCat[listLetters.SelectedIndex]; letterCur.ImageFolder = comboImageCategory.SelectedTag <Def>().DefNum; string templateFile = ODFileUtils.CombinePaths(PrefC.GetString(PrefName.LetterMergePath), letterCur.TemplateName); string dataFile = ODFileUtils.CombinePaths(PrefC.GetString(PrefName.LetterMergePath), letterCur.DataFileName); if (!File.Exists(templateFile)) { MsgBox.Show(this, "Template file does not exist."); return; } PrintDocument pd = new PrintDocument(); if (!PrinterL.SetPrinter(pd, PrintSituation.Default, PatCur.PatNum, "Letter merge " + letterCur.Description + " printed")) { return; } if (!CreateDataFile(dataFile, letterCur)) { return; } Word.MailMerge wrdMailMerge; //Create an instance of Word. Word.Application WrdApp; try { WrdApp = LetterMerges.WordApp; } catch { MsgBox.Show(this, "Error. Is MS Word installed?"); return; } //Open a document. Object oName = templateFile; wrdDoc = WrdApp.Documents.Open(ref oName, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); wrdDoc.Select(); wrdMailMerge = wrdDoc.MailMerge; //Attach the data file. wrdDoc.MailMerge.OpenDataSource(dataFile, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); wrdMailMerge.Destination = Word.WdMailMergeDestination.wdSendToPrinter; //WrdApp.ActivePrinter=pd.PrinterSettings.PrinterName; //replaced with following 4 lines due to MS bug that changes computer default printer object oWBasic = WrdApp.WordBasic; object[] oWBValues = new object[] { pd.PrinterSettings.PrinterName, 1 }; String[] sWBNames = new String[] { "Printer", "DoNotSetAsSysDefault" }; oWBasic.GetType().InvokeMember("FilePrintSetup", BindingFlags.InvokeMethod, null, oWBasic, oWBValues, null, null, sWBNames); wrdMailMerge.Execute(ref oFalse); if (letterCur.ImageFolder != 0) //if image folder exist for this letter, save to AtoZ folder { try { wrdDoc.Select(); wrdMailMerge.Destination = Word.WdMailMergeDestination.wdSendToNewDocument; wrdMailMerge.Execute(ref oFalse); WrdApp.Activate(); string tempFilePath = ODFileUtils.CreateRandomFile(Path.GetTempPath(), GetFileExtensionForWordDoc(templateFile)); Object oFileName = tempFilePath; WrdApp.ActiveDocument.SaveAs(oFileName); //save the document WrdApp.ActiveDocument.Close(); SaveToImageFolder(tempFilePath, letterCur); } catch (Exception ex) { FriendlyException.Show(Lan.g(this, "Error saving file to the Image module:") + "\r\n" + ex.Message, ex); } } //Close the original form document since just one record. wrdDoc.Saved = true; wrdDoc.Close(ref oFalse, ref oMissing, ref oMissing); //At this point, Word remains open with no documents. WrdApp.WindowState = Word.WdWindowState.wdWindowStateMinimize; wrdMailMerge = null; wrdDoc = null; Commlog CommlogCur = new Commlog(); CommlogCur.CommDateTime = DateTime.Now; CommlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.MISC); CommlogCur.Mode_ = CommItemMode.Mail; CommlogCur.SentOrReceived = CommSentOrReceived.Sent; CommlogCur.PatNum = PatCur.PatNum; CommlogCur.Note = "Letter sent: " + letterCur.Description + ". "; CommlogCur.UserNum = Security.CurUser.UserNum; Commlogs.Insert(CommlogCur); DialogResult = DialogResult.OK; }
///<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>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 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 butPreview_Click(object sender, System.EventArgs e) { #if !DISABLE_MICROSOFT_OFFICE if (listLetters.SelectedIndex == -1) { MsgBox.Show(this, "Please select a letter first."); return; } LetterMerge letterCur = ListForCat[listLetters.SelectedIndex]; string templateFile = ODFileUtils.CombinePaths(PrefC.GetString(PrefName.LetterMergePath), letterCur.TemplateName); string dataFile = ODFileUtils.CombinePaths(PrefC.GetString(PrefName.LetterMergePath), letterCur.DataFileName); if (!File.Exists(templateFile)) { MsgBox.Show(this, "Template file does not exist."); return; } if (!CreateDataFile(dataFile, letterCur)) { return; } Word.MailMerge wrdMailMerge; //Create an instance of Word. Word.Application WrdApp; try{ WrdApp = LetterMerges.WordApp; } catch { MsgBox.Show(this, "Error. Is Word installed?"); return; } //Open a document. Object oName = templateFile; wrdDoc = WrdApp.Documents.Open(ref oName, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); wrdDoc.Select(); wrdMailMerge = wrdDoc.MailMerge; //Attach the data file. wrdDoc.MailMerge.OpenDataSource(dataFile, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); wrdMailMerge.Destination = Word.WdMailMergeDestination.wdSendToNewDocument; wrdMailMerge.Execute(ref oFalse); //Close the original form document since just one record. wrdDoc.Saved = true; wrdDoc.Close(ref oFalse, ref oMissing, ref oMissing); //At this point, Word remains open with just one new document. WrdApp.Activate(); if (WrdApp.WindowState == Word.WdWindowState.wdWindowStateMinimize) { WrdApp.WindowState = Word.WdWindowState.wdWindowStateMaximize; } wrdMailMerge = null; wrdDoc = null; Commlog CommlogCur = new Commlog(); CommlogCur.CommDateTime = DateTime.Now; CommlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.MISC); CommlogCur.Mode_ = CommItemMode.Mail; CommlogCur.SentOrReceived = CommSentOrReceived.Sent; CommlogCur.PatNum = PatCur.PatNum; CommlogCur.Note = "Letter sent: " + letterCur.Description + ". "; CommlogCur.UserNum = Security.CurUser.UserNum; Commlogs.Insert(CommlogCur); #else MessageBox.Show(this, "This version of Open Dental does not support Microsoft Word."); #endif //this window now closes regardless of whether the user saved the comm item. DialogResult = DialogResult.OK; }
///<summary>Called from Pin_Click and OK_Click.</summary> private void SaveRecall() { int newStatus; if (comboStatus.SelectedIndex == 0) { newStatus = 0; } else { newStatus = DefB.Short[(int)DefCat.RecallUnschedStatus][comboStatus.SelectedIndex - 1].DefNum; } if (newStatus != RecallCur.RecallStatus || //if the status has changed (RecallCur.Note == "" && textNote.Text != "")) //or a note was added { //make a commlog entry //unless there is an existing recall commlog entry for today bool recallEntryToday = false; Commlog[] CommlogList = Commlogs.Refresh(PatCur.PatNum); for (int i = 0; i < CommlogList.Length; i++) { if (CommlogList[i].CommDateTime.Date == DateTime.Today && CommlogList[i].CommType == Commlogs.GetTypeAuto(CommItemTypeAuto.RECALL)) { recallEntryToday = true; } } if (!recallEntryToday) { Commlog CommlogCur = new Commlog(); CommlogCur.CommDateTime = DateTime.Now; CommlogCur.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.RECALL); CommlogCur.PatNum = PatCur.PatNum; if (newStatus != RecallCur.RecallStatus) { //Commlogs.Cur.Note+=Lan.g(this,"Status changed to")+" "; if (newStatus == 0) { CommlogCur.Note += Lan.g(this, "Status None"); } else { CommlogCur.Note += DefB.GetName(DefCat.RecallUnschedStatus, newStatus); } if (RecallCur.Note == "" && textNote.Text != "") { CommlogCur.Note += ", "; } } if (RecallCur.Note == "" && textNote.Text != "") { CommlogCur.Note += textNote.Text; } CommlogCur.Note += ". "; FormCommItem FormCI = new FormCommItem(CommlogCur); FormCI.IsNew = true; //forces user to at least consider a commlog entry FormCI.ShowDialog(); //typically saved in this window. } } RecallCur.RecallStatus = newStatus; RecallCur.Note = textNote.Text; Recalls.Update(RecallCur); Patient PatOld = PatCur.Copy(); PatCur.WkPhone = textWkPhone.Text; PatCur.WirelessPhone = textWirelessPhone.Text; PatCur.Email = textEmail.Text; PatCur.PreferRecallMethod = (ContactMethod)comboRecallMethod.SelectedIndex; Patients.Update(PatCur, PatOld); Patients.UpdatePhoneAndNoteIfNeeded(textHmPhone.Text, textAddrNotes.Text, PatCur.PatNum); }
///<summary>Go through the transaction dictionary created in CreateProcedureLogs() to edit repeat charges as needed. ///Returns the note for the newly generated repeat charge.</summary> private void ZeroOutRepeatingCharge(ProcedureCode procCur, List <AvaTax.TransQtyAmt> listCurTrans) { Commlog prepaymentCommlog = new Commlog(); prepaymentCommlog.PatNum = _patCur.PatNum; prepaymentCommlog.SentOrReceived = CommSentOrReceived.Received; prepaymentCommlog.CommDateTime = DateTime.Now; prepaymentCommlog.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.FIN); prepaymentCommlog.Mode_ = CommItemMode.None; prepaymentCommlog.Note = "";//Appended to below. prepaymentCommlog.UserNum = Security.CurUser.UserNum; string note = "From PrepaymentTool: \r\n"; bool hasBeenBilledThisMonth = (DateTimeOD.Today.Day >= _patCur.BillingCycleDay); //Get all applicable repeat charges. List <RepeatCharge> listRcForProc = _listRcForPat.FindAll(x => x.ProcCode == procCur.ProcCode && x.IsEnabled); //Get number of months new repeat charge will be for. int numMonths = listCurTrans.Sum(x => x.qty); //Create repeat charge, taken from ContrAccount.cs RepeatCharge rcNew = new RepeatCharge(); rcNew.PatNum = _patCur.PatNum; rcNew.ProcCode = procCur.ProcCode; rcNew.ChargeAmt = 0; rcNew.IsEnabled = true; rcNew.CopyNoteToProc = true; //Build dates using billing day so the patient doesn't have gaps in their repeat charges. DateTime dateBillThisMonth = DateTimeOD.GetMostRecentValidDate(DateTime.Today.Year, DateTime.Today.Month, _patCur.BillingCycleDay); if (hasBeenBilledThisMonth) { //Current month has been billed, push new repeat charge out a month. rcNew.DateStart = dateBillThisMonth.AddMonths(1); rcNew.DateStop = dateBillThisMonth.AddMonths(numMonths); } else { //Current month has not been billed yet, include on this repeat charge. rcNew.DateStart = dateBillThisMonth; rcNew.DateStop = dateBillThisMonth.AddMonths(numMonths - 1); } //Use the stop date to update the Note as requested by Accounting. DatePrepaidThrough = rcNew.DateStop.AddMonths(1).AddDays(-1); rcNew.Note = _prepaidThroughNote; //Edit exisiting repeat charge start/stop dates. foreach (RepeatCharge rcExisting in listRcForProc) { if (rcExisting.DateStop.Year > 1880 && rcExisting.DateStop < DateTimeOD.Today) { continue; //The charge has a stop date in the past (has been disabled). } if (rcExisting.DateStop.Year > 1880 && rcExisting.DateStop <= DateTimeOD.Today.AddMonths(numMonths)) { rcExisting.DateStop = DateTimeOD.Today; rcExisting.IsEnabled = false; //This repeat charge will never be used again due to the prepayment we are creating right now. Disable and add note to commlog for history. note += "Disabled repeat charge with Rate: " + POut.Double(rcExisting.ChargeAmt) + " for Code: " + POut.String(rcExisting.ProcCode) + " Start Date: " + POut.Date(rcExisting.DateStart) + " Stop Date: " + POut.Date(rcExisting.DateStop) + "\r\n"; RepeatCharges.Update(rcExisting); continue; } //Need to push start date of existing repeat charge forward one month past the new repeat charge (if charge months overlap). DateTime dateNext = rcNew.DateStop.AddMonths(1); if (dateNext > rcExisting.DateStart) //Only change if needed. { note += "Edited Start Date for repeat charge from: " + POut.Date(rcExisting.DateStart) + " to: " + POut.Date(dateNext) + " Code: " + POut.String(rcExisting.ProcCode) + " Rate: " + POut.Double(rcExisting.ChargeAmt) + "\r\n"; //Change to billing day to make sure it matches other repeat charges. rcExisting.DateStart = dateNext; RepeatCharges.Update(rcExisting); } } //Insert the new repeat charge. prepaymentCommlog.Note = note; Commlogs.Insert(prepaymentCommlog); RepeatCharges.Insert(rcNew); }