///<summary></summary> public static long Insert(Statement statement) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { statement.StatementNum=Meth.GetLong(MethodBase.GetCurrentMethod(),statement); return statement.StatementNum; } return Crud.StatementCrud.Insert(statement); }
///<summary></summary> public static void Update(Statement statement) { if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(),statement); return; } Crud.StatementCrud.Update(statement); }
///<summary></summary> public static void DeleteObject(Statement statement){ if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(),statement); return; } //validate that not already in use. Crud.StatementCrud.Delete(statement.StatementNum); }
/////<summary>Not used. This code is copied and pasted in several locations. Easiest to find by searching for "info.Verb="print";"</summary> //public static void PrintStatement(object parameters) { // List<object> listParams=(List<object>)parameters; // SheetDef sheetDef=(SheetDef)listParams[0]; // Statement stmt=(Statement)listParams[1]; // string filePath=(string)listParams[2]; // try { // ProcessStartInfo info=new ProcessStartInfo(); // info.Arguments = "\"" + Printers.GetForSit(PrintSituation.Statement).PrinterName + "\""; // info.UseShellExecute = true; // info.Verb="PrintTo"; // info.FileName=filePath; // info.CreateNoWindow=true; // info.WindowStyle=ProcessWindowStyle.Hidden; // Process p=new Process(); // p.StartInfo=info; // p.Start(); // p.WaitForInputIdle(); // System.Threading.Thread.Sleep(3000); // if(p.CloseMainWindow()==false) { // p.Kill(); // } // } // catch(Exception ex) { // //Must restet sheet, as PDF printing modifies fields. // Sheet sheet=SheetUtil.CreateSheet(sheetDef,stmt.PatNum,stmt.HidePayment); // SheetFiller.FillFields(sheet,stmt); // SheetUtil.CalculateHeights(sheet,Graphics.FromImage(new Bitmap(sheet.HeightPage,sheet.WidthPage)),stmt); // SheetPrinting.Print(sheet,1,false,stmt);//use GDI+ printing, which is slightly different than the pdf. // } //} ///<summary>Surround with try/catch.</summary> public static void PrintBatch(List<Sheet> sheetBatch,Statement stmt=null){ //currently no validation for parameters in a batch because of the way it was created. //could validate field names here later. _sheetList=sheetBatch; _sheetsPrinted=0; _pagesPrinted=0; _yPosPrint=0; PrintDocument pd=new PrintDocument(); pd.OriginAtMargins=true; pd.PrintPage+=new PrintPageEventHandler(pd_PrintPage); if(sheetBatch[0].Width>0 && sheetBatch[0].Height>0){ pd.DefaultPageSettings.PaperSize=new PaperSize("Default",sheetBatch[0].Width,sheetBatch[0].Height); } PrintSituation sit=PrintSituation.Default; pd.DefaultPageSettings.Landscape=sheetBatch[0].IsLandscape; switch(sheetBatch[0].SheetType){ case SheetTypeEnum.LabelPatient: case SheetTypeEnum.LabelCarrier: case SheetTypeEnum.LabelReferral: sit=PrintSituation.LabelSingle; break; case SheetTypeEnum.ReferralSlip: sit=PrintSituation.Default; break; } //Moved Calculate heights here because we need to caluclate height before printing, not while we are printing. foreach(Sheet s in _sheetList) { SheetUtil.CalculateHeights(s,Graphics.FromImage(new Bitmap(s.WidthPage,s.HeightPage)),stmt,_isPrinting,_printMargin.Top,_printMargin.Bottom); } //later: add a check here for print preview. #if DEBUG pd.DefaultPageSettings.Margins=new Margins(20,20,0,0); int pageCount=0; foreach(Sheet s in _sheetList) { //SetForceSinglePage(s); SheetUtil.CalculateHeights(s,Graphics.FromImage(new Bitmap(s.WidthPage,s.HeightPage)),stmt,_isPrinting,_printMargin.Top,_printMargin.Bottom); pageCount+=Sheets.CalculatePageCount(s,_printMargin);//(_forceSinglePage?1:Sheets.CalculatePageCount(s,_printMargin)); } FormPrintPreview printPreview=new FormPrintPreview(sit,pd,pageCount,0,"Batch of "+sheetBatch[0].Description+" printed"); printPreview.ShowDialog(); #else try { foreach(Sheet s in _sheetList) { s.SheetFields.Sort(OpenDentBusiness.SheetFields.SortDrawingOrderLayers); } if(!PrinterL.SetPrinter(pd,sit,0,"Batch of "+sheetBatch[0].Description+" printed")) { return; } pd.DefaultPageSettings.Margins=new Margins(0,0,0,0); pd.Print(); } catch(Exception ex){ throw ex; //MessageBox.Show(Lan.g("Sheet","Printer not available")); } #endif }
///<summary>Prints one statement. Does not generate pdf or print from existing pdf.</summary> public void PrintStatement(Statement stmt,bool previewOnly,DataSet dataSet,Family fam,Patient pat) { PrintDocument pd=new PrintDocument(); if(previewOnly) { //Don't want to have print dialogue come up when not printing. } else { if(!PrinterL.SetPrinter(pd,PrintSituation.Statement,pat.PatNum,"Statement from "+stmt.DateTStamp.ToShortDateString()+" printed")) { return; } } PrintStatement(stmt,previewOnly,pd,dataSet,fam,pat); }
/// <summary>Saves the statement. Attaches a pdf to it by creating a doc object. Prints it or emails it. </summary> private void PrintStatement(Statement stmt) { Cursor=Cursors.WaitCursor; Statements.Insert(stmt); FormRpStatement FormST=new FormRpStatement(); DataSet dataSet=AccountModules.GetStatementDataSet(stmt); FormST.CreateStatementPdf(stmt,PatCur,FamCur,dataSet); //if(ImageStore.UpdatePatient == null){ // ImageStore.UpdatePatient = new FileStore.UpdatePatientDelegate(Patients.Update); //} Patient guar=Patients.GetPat(stmt.PatNum); string guarFolder=ImageStore.GetPatientFolder(guar,ImageStore.GetPreferredAtoZpath()); //OpenDental.Imaging.ImageStoreBase imageStore = OpenDental.Imaging.ImageStore.GetImageStore(guar); if(stmt.Mode_==StatementMode.Email){ string attachPath=FormEmailMessageEdit.GetAttachPath(); Random rnd=new Random(); string fileName=DateTime.Now.ToString("yyyyMMdd")+"_"+DateTime.Now.TimeOfDay.Ticks.ToString()+rnd.Next(1000).ToString()+".pdf"; string filePathAndName=ODFileUtils.CombinePaths(attachPath,fileName); File.Copy(ImageStore.GetFilePath(Documents.GetByNum(stmt.DocNum),guarFolder),filePathAndName); //Process.Start(filePathAndName); EmailMessage message=new EmailMessage(); message.PatNum=guar.PatNum; message.ToAddress=guar.Email; message.FromAddress=PrefC.GetString(PrefName.EmailSenderAddress); string str; str=PrefC.GetString(PrefName.BillingEmailSubject); str=str.Replace("[nameF]",guar.GetNameFirst()); str=str.Replace("[nameFL]",guar.GetNameFL()); str=str.Replace("[namePref]",guar.Preferred); str=str.Replace("[PatNum]",guar.PatNum.ToString()); message.Subject=str; str=PrefC.GetString(PrefName.BillingEmailBodyText); str=str.Replace("[nameF]",guar.GetNameFirst()); str=str.Replace("[nameFL]",guar.GetNameFL()); str=str.Replace("[namePref]",guar.Preferred); str=str.Replace("[PatNum]",guar.PatNum.ToString()); message.BodyText=str; EmailAttach attach=new EmailAttach(); attach.DisplayedFileName="Statement.pdf"; attach.ActualFileName=fileName; message.Attachments.Add(attach); FormEmailMessageEdit FormE=new FormEmailMessageEdit(message); FormE.IsNew=true; FormE.ShowDialog(); } else{ #if DEBUG //don't bother to check valid path because it's just debug. string imgPath=ImageStore.GetFilePath(Documents.GetByNum(stmt.DocNum),guarFolder); DateTime now=DateTime.Now; while(DateTime.Now<now.AddSeconds(5) && !File.Exists(imgPath)) {//wait up to 5 seconds. Application.DoEvents(); } Process.Start(imgPath); #else FormST.PrintStatement(stmt,false,dataSet,FamCur,PatCur); #endif } Cursor=Cursors.Default; }
///<summary>Prints one statement to a specified printer which is passed in as a PrintDocument field. Used when printer selection happens before a batch</summary> public void PrintStatement(Statement stmt,PrintDocument pd,DataSet dataSet,Family fam,Patient pat) { PrintStatement(stmt,false,pd,dataSet,fam,pat); }
private static DataTable getTable_StatementEnclosed(Statement stmt) { DataSet dataSet=AccountModules.GetStatementDataSet(stmt); DataTable tableMisc=dataSet.Tables["misc"]; string text=""; DataTable table=new DataTable(); table.Columns.Add(new DataColumn("AmountDue")); table.Columns.Add(new DataColumn("DateDue")); table.Columns.Add(new DataColumn("AmountEnclosed")); DataRow row=table.NewRow(); Patient patGuar=Patients.GetPat(Patients.GetPat(stmt.PatNum).Guarantor); double balTotal=patGuar.BalTotal; if(!PrefC.GetBool(PrefName.BalancesDontSubtractIns)) {//this is typical balTotal-=patGuar.InsEst; } for(int m=0;m<tableMisc.Rows.Count;m++) { if(tableMisc.Rows[m]["descript"].ToString()=="payPlanDue") { balTotal+=PIn.Double(tableMisc.Rows[m]["value"].ToString()); //payPlanDue;//PatGuar.PayPlanDue; } } InstallmentPlan installPlan=InstallmentPlans.GetOneForFam(patGuar.PatNum); if(installPlan!=null) { //show lesser of normal total balance or the monthly payment amount. if(installPlan.MonthlyPayment < balTotal) { text=installPlan.MonthlyPayment.ToString("F"); } else { text=balTotal.ToString("F"); } } else {//no installmentplan text=balTotal.ToString("F"); } row[0]=text; if(PrefC.GetLong(PrefName.StatementsCalcDueDate)==-1) { text=Lans.g("Statements","Upon Receipt"); } else { text=DateTime.Today.AddDays(PrefC.GetLong(PrefName.StatementsCalcDueDate)).ToShortDateString(); } row[1]=text; row[2]=""; table.Rows.Add(row); return table; }
private static DataTable getTable_StatementPayPlan(Statement stmt) { DataTable retVal=new DataTable(); DataSet ds=AccountModules.GetAccount(stmt.PatNum,stmt.DateRangeFrom,stmt.DateRangeTo,stmt.Intermingled,stmt.SinglePatient,stmt.StatementNum,PrefC.GetBool(PrefName.StatementShowProcBreakdown),PrefC.GetBool(PrefName.StatementShowNotes),stmt.IsInvoice,PrefC.GetBool(PrefName.StatementShowAdjNotes),true,true); foreach(DataTable t in ds.Tables) { if(!t.TableName.StartsWith("payplan")) { continue; } retVal=t.Clone(); foreach(DataRow r in t.Rows) { retVal.ImportRow(r); } } return retVal; }
///<summary>Adds the xml for one statement. Validation is performed here. Throws an exception if there is a validation failure.</summary> public static void GenerateOneStatement(XmlWriter writer,Statement stmt,Patient pat,Family fam,DataSet dataSet){ Patient guar=fam.ListPats[0]; if(!Regex.IsMatch(guar.State,"^[A-Z]{2}$")) { throw new ApplicationException(Lan.g("EHG_Statements","Guarantor state must be two uppercase characters.")+" "+guar.FName+" "+guar.LName+" #"+guar.PatNum); } writer.WriteStartElement("EisStatement"); writer.WriteAttributeString("OutputFormat","StmOut_Blue6Col"); writer.WriteAttributeString("CreditCardChoice",PrefC.GetString(PrefName.BillingElectCreditCardChoices)); writer.WriteStartElement("Patient"); writer.WriteElementString("Name",guar.GetNameFLFormal()); writer.WriteElementString("Account",guar.PatNum.ToString()); writer.WriteElementString("Address1",guar.Address); writer.WriteElementString("Address2",guar.Address2); writer.WriteElementString("City",guar.City); writer.WriteElementString("State",guar.State); writer.WriteElementString("Zip",guar.Zip); string email=""; Def billingDef=DefC.GetDef(DefCat.BillingTypes,guar.BillingType); if(billingDef.ItemValue=="E") { email=guar.Email; } writer.WriteElementString("EMail",email); //Account summary----------------------------------------------------------------------- writer.WriteStartElement("AccountSummary"); if(stmt.DateRangeFrom.Year<1880) {//make up a statement date. writer.WriteElementString("PriorStatementDate",DateTime.Today.AddMonths(-1).ToString("MM/dd/yyyy")); } else { writer.WriteElementString("PriorStatementDate",stmt.DateRangeFrom.AddDays(-1).ToString("MM/dd/yyyy")); } DateTime dueDate; if(PrefC.GetLong(PrefName.StatementsCalcDueDate)==-1){ dueDate=DateTime.Today.AddDays(10); } else{ dueDate=DateTime.Today.AddDays(PrefC.GetLong(PrefName.StatementsCalcDueDate)); } writer.WriteElementString("DueDate",dueDate.ToString("MM/dd/yyyy")); writer.WriteElementString("StatementDate",stmt.DateSent.ToString("MM/dd/yyyy")); double balanceForward=0; for(int r=0;r<dataSet.Tables["misc"].Rows.Count;r++){ if(dataSet.Tables["misc"].Rows[r]["descript"].ToString()=="balanceForward"){ balanceForward=PIn.Double(dataSet.Tables["misc"].Rows[r]["value"].ToString()); } } writer.WriteElementString("PriorBalance",balanceForward.ToString("F2")); writer.WriteElementString("RunningBalance","");//for future use writer.WriteElementString("PerPayAdj","");//optional writer.WriteElementString("InsPayAdj","");//optional writer.WriteElementString("Adjustments","");//for future use writer.WriteElementString("NewCharges","");//optional writer.WriteElementString("FinanceCharges","");//for future use DataTable tableAccount=null; for(int i=0;i<dataSet.Tables.Count;i++) { if(dataSet.Tables[i].TableName.StartsWith("account")) { tableAccount=dataSet.Tables[i]; } } double credits=0; for(int i=0;i<tableAccount.Rows.Count;i++) { credits+=PIn.Double(tableAccount.Rows[i]["creditsDouble"].ToString()); } writer.WriteElementString("Credits",credits.ToString("F2")); //on a regular printed statement, the amount due at the top might be different from the balance at the middle right. //This is because of payment plan balances. //But in e-bills, there is only one amount due. //Insurance estimate is already subtracted, and payment plan balance is already added. double amountDue=guar.BalTotal; //add payplan due amt: for(int m=0;m<dataSet.Tables["misc"].Rows.Count;m++) { if(dataSet.Tables["misc"].Rows[m]["descript"].ToString()=="payPlanDue") { amountDue+=PIn.Double(dataSet.Tables["misc"].Rows[m]["value"].ToString()); } } if(PrefC.GetBool(PrefName.BalancesDontSubtractIns)) { writer.WriteElementString("EstInsPayments","");//optional. } else {//this is typical writer.WriteElementString("EstInsPayments",guar.InsEst.ToString("F2"));//optional. amountDue-=guar.InsEst; } InstallmentPlan installPlan=InstallmentPlans.GetOneForFam(guar.PatNum); if(installPlan!=null){ //show lesser of normal total balance or the monthly payment amount. if(installPlan.MonthlyPayment < amountDue) { amountDue=installPlan.MonthlyPayment; } } writer.WriteElementString("PatientShare",amountDue.ToString("F2")); writer.WriteElementString("CurrentBalance",amountDue.ToString("F2"));//this is ambiguous. It seems to be AmountDue, but it could possibly be 0-30 days aging writer.WriteElementString("PastDue30",guar.Bal_31_60.ToString("F2"));//optional writer.WriteElementString("PastDue60",guar.Bal_61_90.ToString("F2"));//optional writer.WriteElementString("PastDue90",guar.BalOver90.ToString("F2"));//optional writer.WriteElementString("PastDue120","");//optional writer.WriteEndElement();//AccountSummary //Notes----------------------------------------------------------------------------------- writer.WriteStartElement("Notes"); if(stmt.NoteBold!="") { writer.WriteStartElement("Note"); writer.WriteAttributeString("FgColor","Red");//ColorToHexString(Color.DarkRed)); //writer.WriteAttributeString("BgColor",ColorToHexString(Color.White)); writer.WriteString(Tidy(stmt.NoteBold,500));//Limit of 500 char on notes. writer.WriteEndElement();//Note } if(stmt.Note!="") { writer.WriteStartElement("Note"); //writer.WriteAttributeString("FgColor",ColorToHexString(Color.Black)); //writer.WriteAttributeString("BgColor",ColorToHexString(Color.White)); writer.WriteString(Tidy(stmt.Note,500));//Limit of 500 char on notes. writer.WriteEndElement();//Note } writer.WriteEndElement();//Notes //Detail items------------------------------------------------------------------------------ writer.WriteStartElement("DetailItems"); //string note; string descript; string fulldesc; string procCode; string tth; //string linedesc; string[] lineArray; List<string> lines; DateTime date; int seq=0; for(int i=0;i<tableAccount.Rows.Count;i++) { procCode=tableAccount.Rows[i]["ProcCode"].ToString(); tth=tableAccount.Rows[i]["tth"].ToString(); descript=tableAccount.Rows[i]["description"].ToString(); fulldesc=procCode+" "+tth+" "+descript;//There are frequently CRs within a procedure description for things like ins est. lineArray=fulldesc.Split(new string[] { "\r\n" },StringSplitOptions.RemoveEmptyEntries); lines=new List<string>(lineArray); //The specs say that the line limit is 30 char. But in testing, it will take 50 char. //We will use 40 char to be safe. if(lines[0].Length>40) { string newline=lines[0].Substring(40); lines[0]=lines[0].Substring(0,40);//first half lines.Insert(1,newline);//second half } for(int li=0;li<lines.Count;li++) { writer.WriteStartElement("DetailItem");//has a child item. We won't add optional child note writer.WriteAttributeString("sequence",seq.ToString()); writer.WriteStartElement("Item"); if(li==0) { date=(DateTime)tableAccount.Rows[i]["DateTime"]; writer.WriteElementString("Date",date.ToString("MM/dd/yyyy")); writer.WriteElementString("PatientName",tableAccount.Rows[i]["patient"].ToString()); } else { writer.WriteElementString("Date",""); writer.WriteElementString("PatientName",""); } writer.WriteStartElement("Description"); writer.WriteCData(Tidy(lines[li],40));//Jessica at DentalXchange says limit is 120. Docs say limit is 30. CData to allow any string. writer.WriteEndElement();//Description if(li==0) { writer.WriteElementString("Charges",tableAccount.Rows[i]["charges"].ToString()); writer.WriteElementString("Credits",tableAccount.Rows[i]["credits"].ToString()); writer.WriteElementString("Balance",tableAccount.Rows[i]["balance"].ToString()); } else { writer.WriteElementString("Charges",""); writer.WriteElementString("Credits",""); writer.WriteElementString("Balance",""); } writer.WriteEndElement();//Item writer.WriteEndElement();//DetailItem seq++; } /*The code below just didn't work because notes don't get displayed on the statement. linedesc=lines[0]; note=""; if(linedesc.Length>30) { note=linedesc.Substring(30); linedesc=linedesc.Substring(0,30); } for(int l=1;l<lines.Length;l++) { if(note!="") { note+="\r\n"; } note+=lines[l]; } if(note!="") { writer.WriteStartElement("Note"); //we're not going to specify colors here since they're optional writer.WriteCData(note); writer.WriteEndElement();//Note }*/ } writer.WriteEndElement();//DetailItems writer.WriteEndElement();//Patient writer.WriteEndElement();//EisStatement }
///<summary>Adds the xml for one statement.</summary> public static void GenerateOneStatement(XmlWriter writer,Statement stmt,Patient pat,Family fam,DataSet dataSet) { Patient guar=fam.ListPats[0]; writer.WriteStartElement("Statement"); //writer.WriteAttributeString("CreditCardChoice",PrefC.GetString(PrefName.BillingElectCreditCardChoices")); //remit address---------------------------------------------------------- writer.WriteStartElement("RemitAddress"); if(!PrefC.GetBool(PrefName.EasyNoClinics) && Clinics.List.Length>0 //if using clinics && Clinics.GetClinic(guar.ClinicNum)!=null)//and this guar is assigned to a clinic { Clinic clinic=Clinics.GetClinic(guar.ClinicNum); writer.WriteElementString("Name",clinic.Description); writer.WriteElementString("Address",clinic.Address); writer.WriteElementString("Address2",clinic.Address2); writer.WriteElementString("City",clinic.City); writer.WriteElementString("State",clinic.State); writer.WriteElementString("Zip",clinic.Zip); string phone=""; if(clinic.Phone.Length==10) { phone="("+clinic.Phone.Substring(0,3)+")"+clinic.Phone.Substring(3,3)+"-"+clinic.Phone.Substring(6); } writer.WriteElementString("Phone",phone); } else{//not using clinics writer.WriteElementString("Name",PrefC.GetString(PrefName.PracticeTitle)); writer.WriteElementString("Address",PrefC.GetString(PrefName.PracticeAddress)); writer.WriteElementString("Address2",PrefC.GetString(PrefName.PracticeAddress2)); writer.WriteElementString("City",PrefC.GetString(PrefName.PracticeCity)); writer.WriteElementString("State",PrefC.GetString(PrefName.PracticeST)); writer.WriteElementString("Zip",PrefC.GetString(PrefName.PracticeZip)); writer.WriteElementString("Phone",PrefC.GetString(PrefName.PracticePhone)); } writer.WriteEndElement();//RemitAddress //Patient------------------------------------------------------------------------------- writer.WriteStartElement("Patient"); writer.WriteElementString("Name",guar.GetNameFLFormal()); writer.WriteElementString("AccountNum",guar.PatNum.ToString()); writer.WriteElementString("Address",guar.Address); writer.WriteElementString("Address2",guar.Address2); writer.WriteElementString("City",guar.City); writer.WriteElementString("State",guar.State); writer.WriteElementString("Zip",guar.Zip); writer.WriteEndElement();//Patient //Account summary----------------------------------------------------------------------- writer.WriteStartElement("AccountSummary"); if(PrefC.GetLong(PrefName.StatementsCalcDueDate)==-1){ writer.WriteElementString("DueDate",Lan.g("FormRpStatement","Upon Receipt")); } else{ DateTime dueDate=DateTime.Today.AddDays(PrefC.GetLong(PrefName.StatementsCalcDueDate)); writer.WriteElementString("DueDate",dueDate.ToString("MM/dd/yyyy")); } writer.WriteElementString("StatementDate",stmt.DateSent.ToString("MM/dd/yyyy")); DataTable tableAccount=null; for(int i=0;i<dataSet.Tables.Count;i++) { if(dataSet.Tables[i].TableName.StartsWith("account")) { tableAccount=dataSet.Tables[i]; } } //on a regular printed statement, the amount due at the top might be different from the balance at the middle right. //This is because of payment plan balances. //But in e-bills, there is only one amount due. //Insurance estimate is already subtracted, and payment plan balance is already added. double amountDue=guar.BalTotal; //add payplan due amt: for(int m=0;m<dataSet.Tables["misc"].Rows.Count;m++) { if(dataSet.Tables["misc"].Rows[m]["descript"].ToString()=="payPlanDue") { amountDue+=PIn.Double(dataSet.Tables["misc"].Rows[m]["value"].ToString()); } } if(PrefC.GetBool(PrefName.BalancesDontSubtractIns)) { writer.WriteElementString("EstInsPayments",""); writer.WriteElementString("AmountDue",amountDue.ToString("F2")); } else{//this is typical writer.WriteElementString("EstInsPayments",guar.InsEst.ToString("F2")); amountDue-=guar.InsEst; writer.WriteElementString("AmountDue",amountDue.ToString("F2")); } writer.WriteElementString("Bal_0_30",guar.Bal_0_30.ToString("F2")); writer.WriteElementString("Bal_31_60",guar.Bal_31_60.ToString("F2")); writer.WriteElementString("Bal_61_90",guar.Bal_61_90.ToString("F2")); writer.WriteElementString("BalOver90",guar.BalOver90.ToString("F2")); writer.WriteEndElement();//AccountSummary //Notes----------------------------------------------------------------------------------- writer.WriteStartElement("Notes"); if(stmt.NoteBold!="") { writer.WriteStartElement("Note"); writer.WriteAttributeString("FgColor",ColorToHexString(Color.DarkRed)); writer.WriteCData(stmt.NoteBold); writer.WriteEndElement();//Note } if(stmt.Note!="") { writer.WriteStartElement("Note"); writer.WriteAttributeString("FgColor",ColorToHexString(Color.Black)); writer.WriteCData(stmt.Note); writer.WriteEndElement();//Note } writer.WriteEndElement();//Notes //Detail items------------------------------------------------------------------------------ writer.WriteStartElement("DetailItems"); string descript; string fulldesc; string procCode; string tth; string[] lineArray; List<string> lines; DateTime date; int seq=0; for(int i=0;i<tableAccount.Rows.Count;i++) { procCode=tableAccount.Rows[i]["ProcCode"].ToString(); tth=tableAccount.Rows[i]["tth"].ToString(); descript=tableAccount.Rows[i]["description"].ToString(); fulldesc=procCode+" "+tth+" "+descript; lineArray=fulldesc.Split(new string[] { "\r\n" },StringSplitOptions.RemoveEmptyEntries); lines=new List<string>(lineArray); //We assume that the line limit is 40 char. if(lines[0].Length>40) { string newline=lines[0].Substring(40); lines[0]=lines[0].Substring(0,40);//first half lines.Insert(1,newline);//second half } for(int li=0;li<lines.Count;li++) { writer.WriteStartElement("Item"); writer.WriteAttributeString("sequence",seq.ToString()); if(li==0) { date=(DateTime)tableAccount.Rows[i]["DateTime"]; writer.WriteElementString("Date",date.ToString("MM/dd/yyyy")); writer.WriteElementString("PatientName",tableAccount.Rows[i]["patient"].ToString()); } else { writer.WriteElementString("Date",""); writer.WriteElementString("PatientName",""); } writer.WriteElementString("Description",lines[li]); if(li==0) { writer.WriteElementString("Charges",tableAccount.Rows[i]["charges"].ToString()); writer.WriteElementString("Credits",tableAccount.Rows[i]["credits"].ToString()); writer.WriteElementString("Balance",tableAccount.Rows[i]["balance"].ToString()); } else { writer.WriteElementString("Charges",""); writer.WriteElementString("Credits",""); writer.WriteElementString("Balance",""); } writer.WriteEndElement();//Item seq++; } } writer.WriteEndElement();//DetailItems writer.WriteEndElement();//Statement }
private void menuItemReceipt_Click(object sender,EventArgs e) { Statement stmt=new Statement(); stmt.PatNum=PatCur.PatNum; stmt.DateSent=DateTimeOD.Today; stmt.IsSent=true; stmt.Mode_=StatementMode.InPerson; stmt.HidePayment=true; stmt.SinglePatient=true; stmt.Intermingled=false; stmt.IsReceipt=true; if(PrefC.GetBool(PrefName.IntermingleFamilyDefault)) { stmt.Intermingled = true; stmt.SinglePatient=false; } stmt.DateRangeFrom=DateTimeOD.Today; stmt.DateRangeTo=DateTimeOD.Today; stmt.Note=""; stmt.NoteBold=""; PrintStatement(stmt); ModuleSelected(PatCur.PatNum); }
private void menuItemInvoice_Click(object sender,EventArgs e) { DataTable table=DataSetMain.Tables["account"]; if(gridAccount.SelectedIndices.Length==0) { //autoselect procedures and adjustments for(int i=0;i<table.Rows.Count;i++) {//loop through every line showing on screen if(table.Rows[i]["ProcNum"].ToString()=="0" && table.Rows[i]["AdjNum"].ToString()=="0") { continue;//ignore items that aren't procs or adjustments } if(PIn.Date(table.Rows[i]["date"].ToString())!=DateTime.Today) { continue; } if(table.Rows[i]["ProcNum"].ToString()!="0") {//if selected item is a procedure Procedure proc=Procedures.GetOneProc(PIn.Long(table.Rows[i]["ProcNum"].ToString()),false); if(proc.StatementNum!=0) {//already attached so don't autoselect continue; } if(proc.PatNum!=PatCur.PatNum) { continue; } } else {//item guaranteed to be a proc or adjustment, so must be adjustment Adjustment adj=Adjustments.GetOne(PIn.Long(table.Rows[i]["AdjNum"].ToString())); if(adj.StatementNum!=0) {//already attached so don't autoselect continue; } if(adj.PatNum!=PatCur.PatNum) { continue; } } gridAccount.SetSelected(i,true); } if(gridAccount.SelectedIndices.Length==0) {//if still none selected MsgBox.Show(this,"Please select procedures or adjustments first."); return; } } for(int i=0;i<gridAccount.SelectedIndices.Length;i++) { if(table.Rows[gridAccount.SelectedIndices[i]]["ProcNum"].ToString()=="0" && table.Rows[gridAccount.SelectedIndices[i]]["AdjNum"].ToString()=="0") //the selected item is neither a procedure nor an adjustment { MsgBox.Show(this,"You can only select procedures or adjustments."); gridAccount.SetSelected(false); return; } if(table.Rows[gridAccount.SelectedIndices[i]]["ProcNum"].ToString()!="0") {//the selected item is a proc Procedure proc=Procedures.GetOneProc(PIn.Long(table.Rows[gridAccount.SelectedIndices[i]]["ProcNum"].ToString()),false); if(proc.PatNum!=PatCur.PatNum) { MsgBox.Show(this,"You can only select procedures or adjustments for a single patient on an invoice."); gridAccount.SetSelected(false); return; } if(proc.StatementNum!=0) { MsgBox.Show(this,"Selected procedure(s) are already attached to an invoice."); gridAccount.SetSelected(false); return; } } else {//the selected item must be an adjustment Adjustment adj=Adjustments.GetOne(PIn.Long(table.Rows[gridAccount.SelectedIndices[i]]["AdjNum"].ToString())); if(adj.PatNum!=PatCur.PatNum) { MsgBox.Show(this,"You can only select procedures or adjustments for a single patient on an invoice."); gridAccount.SetSelected(false); return; } if(adj.StatementNum!=0) { MsgBox.Show(this,"Selected adjustment(s) are already attached to an invoice."); gridAccount.SetSelected(false); return; } } } //At this point, all selected items are procedures or adjustments, and are not already attached, and are for a single patient. Statement stmt=new Statement(); stmt.PatNum=PatCur.PatNum; stmt.DateSent=DateTimeOD.Today; stmt.IsSent=false; stmt.Mode_=StatementMode.InPerson; stmt.HidePayment=true; stmt.SinglePatient=true; stmt.Intermingled=false; stmt.IsReceipt=false; stmt.IsInvoice=true; stmt.DateRangeFrom=DateTime.MinValue; stmt.DateRangeTo=DateTimeOD.Today; stmt.Note=PrefC.GetString(PrefName.BillingDefaultsInvoiceNote); stmt.NoteBold=""; Statements.Insert(stmt); stmt.IsNew=true; List<Procedure> procsForPat=Procedures.Refresh(PatCur.PatNum); for(int i=0;i<gridAccount.SelectedIndices.Length;i++) { if(table.Rows[gridAccount.SelectedIndices[i]]["ProcNum"].ToString()!="0") {//if selected item is a procedure Procedure proc=Procedures.GetProcFromList(procsForPat,PIn.Long(table.Rows[gridAccount.SelectedIndices[i]]["ProcNum"].ToString())); Procedure oldProc=proc.Copy(); proc.StatementNum=stmt.StatementNum; Procedures.Update(proc,oldProc); } else {//every selected item guaranteed to be a proc or adjustment, so must be adjustment Adjustment adj=Adjustments.GetOne(PIn.Long(table.Rows[gridAccount.SelectedIndices[i]]["AdjNum"].ToString())); adj.StatementNum=stmt.StatementNum; Adjustments.Update(adj); } } //All printing and emailing will be done from within the form: FormStatementOptions FormSO=new FormStatementOptions(); FormSO.StmtCur=stmt; FormSO.ShowDialog(); if(FormSO.DialogResult!=DialogResult.OK) { Procedures.DetachFromInvoice(stmt.StatementNum); Adjustments.DetachFromInvoice(stmt.StatementNum); Statements.Delete(stmt.StatementNum); } ModuleSelected(PatCur.PatNum); }
private void toolBarButStatement_Click() { Statement stmt=new Statement(); stmt.PatNum=PatCur.Guarantor; stmt.DateSent=DateTimeOD.Today; stmt.IsSent=true; stmt.Mode_=StatementMode.InPerson; stmt.HidePayment=false; stmt.SinglePatient=false; stmt.Intermingled=false; stmt.DateRangeFrom=DateTime.MinValue; if (PrefC.GetBool(PrefName.IntermingleFamilyDefault)){ stmt.Intermingled = true; } if (PrefC.GetBool(PrefName.FuchsOptionsOn)){ stmt.DateRangeFrom = PIn.Date(DateTime.Today.AddDays(-45).ToShortDateString()); stmt.DateRangeTo = PIn.Date(DateTime.Today.ToShortDateString()); } else{ if (textDateStart.errorProvider1.GetError(textDateStart) == "") { if (textDateStart.Text != "") { stmt.DateRangeFrom = PIn.Date(textDateStart.Text); } } } stmt.DateRangeTo = DateTimeOD.Today;//This is needed for payment plan accuracy.//new DateTime(2200,1,1); if (textDateEnd.errorProvider1.GetError(textDateEnd) == "") { if (textDateEnd.Text != "") { stmt.DateRangeTo = PIn.Date(textDateEnd.Text); } } stmt.Note = ""; stmt.NoteBold = ""; PrintStatement(stmt); ModuleSelected(PatCur.PatNum); }
private void menuItemStatementEmail_Click(object sender,EventArgs e) { Statement stmt=new Statement(); stmt.PatNum=PatCur.Guarantor; stmt.DateSent=DateTimeOD.Today; stmt.IsSent=true; stmt.Mode_=StatementMode.Email; stmt.HidePayment=false; stmt.SinglePatient=false; stmt.Intermingled=false; stmt.IsReceipt=false; if(PrefC.GetBool(PrefName.IntermingleFamilyDefault)){ stmt.Intermingled=true; } stmt.DateRangeFrom=DateTime.MinValue; if(textDateStart.errorProvider1.GetError(textDateStart)==""){ if(textDateStart.Text!=""){ stmt.DateRangeFrom=PIn.Date(textDateStart.Text); } } stmt.DateRangeTo=new DateTime(2200,1,1); if(textDateEnd.errorProvider1.GetError(textDateEnd)==""){ if(textDateEnd.Text!=""){ stmt.DateRangeTo=PIn.Date(textDateEnd.Text); } } stmt.Note=""; stmt.NoteBold=""; //It's pointless to give the user the window to select statement options, because they could just as easily have hit the More Options dropdown, then Email from there. PrintStatement(stmt); ModuleSelected(PatCur.PatNum); }
private void PrintStatementSheets(Statement stmt) { Cursor=Cursors.WaitCursor; Statements.Insert(stmt); SheetDef sheetDef=SheetUtil.GetStatementSheetDef(); Sheet sheet=SheetUtil.CreateSheet(sheetDef,stmt.PatNum,stmt.HidePayment); SheetFiller.FillFields(sheet,stmt); SheetUtil.CalculateHeights(sheet,Graphics.FromImage(new Bitmap(sheet.HeightPage,sheet.WidthPage)),stmt); string tempPath=CodeBase.ODFileUtils.CombinePaths(PrefL.GetTempFolderPath(),stmt.PatNum.ToString()+".pdf"); SheetPrinting.CreatePdf(sheet,tempPath,stmt);//We don't delete this from temp folder long category=0; for(int i=0;i<DefC.Short[(int)DefCat.ImageCats].Length;i++) { if(Regex.IsMatch(DefC.Short[(int)DefCat.ImageCats][i].ItemValue,@"S")) { category=DefC.Short[(int)DefCat.ImageCats][i].DefNum; break; } } if(category==0) { category=DefC.Short[(int)DefCat.ImageCats][0].DefNum;//put it in the first category. } //create doc-------------------------------------------------------------------------------------- OpenDentBusiness.Document docc=null; try { docc=ImageStore.Import(tempPath,category,Patients.GetPat(stmt.PatNum)); } catch { MsgBox.Show(this,"Error saving document."); //this.Cursor=Cursors.Default; return; } docc.ImgType=ImageType.Document; docc.DateCreated=stmt.DateSent; Documents.Update(docc); stmt.DocNum=docc.DocNum;//this signals the calling class that the pdf was created successfully. Statements.AttachDoc(stmt.StatementNum,docc.DocNum); //if(ImageStore.UpdatePatient == null){ // ImageStore.UpdatePatient = new FileStore.UpdatePatientDelegate(Patients.Update); //} Patient guar=Patients.GetPat(stmt.PatNum); string guarFolder=ImageStore.GetPatientFolder(guar,ImageStore.GetPreferredAtoZpath()); //OpenDental.Imaging.ImageStoreBase imageStore = OpenDental.Imaging.ImageStore.GetImageStore(guar); if(stmt.Mode_==StatementMode.Email) { if(!Security.IsAuthorized(Permissions.EmailSend)) { Cursor=Cursors.Default; return; } string attachPath=EmailAttaches.GetAttachPath(); Random rnd=new Random(); string fileName=DateTime.Now.ToString("yyyyMMdd")+"_"+DateTime.Now.TimeOfDay.Ticks.ToString()+rnd.Next(1000).ToString()+".pdf"; string filePathAndName=ODFileUtils.CombinePaths(attachPath,fileName); File.Copy(ImageStore.GetFilePath(Documents.GetByNum(stmt.DocNum),guarFolder),filePathAndName); //Process.Start(filePathAndName); EmailMessage message=Statements.GetEmailMessageForStatement(stmt,guar); EmailAttach attach=new EmailAttach(); attach.DisplayedFileName="Statement.pdf"; attach.ActualFileName=fileName; message.Attachments.Add(attach); FormEmailMessageEdit FormE=new FormEmailMessageEdit(message); FormE.IsNew=true; FormE.ShowDialog(); //If user clicked delete or cancel, delete pdf and statement if(FormE.DialogResult==DialogResult.Cancel) { Patient pat; string patFolder; if(stmt.DocNum!=0) { //delete the pdf pat=Patients.GetPat(stmt.PatNum); patFolder=ImageStore.GetPatientFolder(pat,ImageStore.GetPreferredAtoZpath()); List<Document> listdocs=new List<Document>(); listdocs.Add(Documents.GetByNum(stmt.DocNum)); try { ImageStore.DeleteDocuments(listdocs,patFolder); } catch { //Image could not be deleted, in use. //This should never get hit because the file was created by this user within this method. //If the doc cannot be deleted, then we will not stop them, they will have to manually delete it from the images module. } } //delete statement Statements.Delete(stmt); } } else {//not email #if DEBUG //don't bother to check valid path because it's just debug. string imgPath=ImageStore.GetFilePath(Documents.GetByNum(stmt.DocNum),guarFolder); DateTime now=DateTime.Now; while(DateTime.Now<now.AddSeconds(5) && !File.Exists(imgPath)) {//wait up to 5 seconds. Application.DoEvents(); } Process.Start(imgPath); #else //Thread thread=new Thread(new ParameterizedThreadStart(SheetPrinting.PrintStatement)); //thread.Start(new List<object> { sheetDef,stmt,tempPath }); //NOTE: This is printing a "fresh" GDI+ version of the statment which is ever so slightly different than the PDFSharp statment that was saved to disk. sheet=SheetUtil.CreateSheet(sheetDef,stmt.PatNum,stmt.HidePayment); SheetFiller.FillFields(sheet,stmt); SheetUtil.CalculateHeights(sheet,Graphics.FromImage(new Bitmap(sheet.HeightPage,sheet.WidthPage)),stmt); SheetPrinting.Print(sheet,1,false,stmt);//use GDI+ printing, which is slightly different than the pdf. #endif } Cursor=Cursors.Default; }
/// <summary>Saves the statement. Attaches a pdf to it by creating a doc object. Prints it or emails it. </summary> private void PrintStatement(Statement stmt) { if(PrefC.GetBool(PrefName.StatementsUseSheets)) { PrintStatementSheets(stmt); } else { PrintStatementClassic(stmt); } }
///<summary>Prints one statement. Does not generate pdf or print from existing pdf.</summary> public void PrintStatement(Statement stmt,bool previewOnly,DataSet dataSet,Family fam,Patient pat) { PrintDocument pd=new PrintDocument(); if(!PrinterL.SetPrinter(pd,PrintSituation.Statement)){ return; } PrintStatement(stmt,previewOnly,pd,dataSet,fam,pat); }
///<summary>Prints one statement. Does not generate pdf or print from existing pdf.</summary> public void PrintStatement(Statement stmt,bool previewOnly,PrintDocument pd,DataSet dataSet,Family fam,Patient pat) { Stmt=stmt; //dataSet=AccountModuleL.GetStatement(stmt.PatNum,stmt.SinglePatient,stmt.DateRangeFrom,stmt.DateRangeTo, // stmt.Intermingled); pd.DefaultPageSettings.Margins=new Margins(40,40,40,60); if(CultureInfo.CurrentCulture.Name.EndsWith("CH")) {//CH is for switzerland. eg de-CH //leave a big margin on the bottom for the routing slip pd.DefaultPageSettings.Margins=new Margins(40,40,40,440);//4.4" from bottom } //pd.OriginAtMargins=true; if(pd.DefaultPageSettings.PaperSize.Height==0) { pd.DefaultPageSettings.PaperSize=new PaperSize("default",850,1100); } MigraDoc.DocumentObjectModel.Document doc=CreateDocument(pd,fam,pat,dataSet); MigraDoc.Rendering.Printing.MigraDocPrintDocument printdoc=new MigraDoc.Rendering.Printing.MigraDocPrintDocument(); MigraDoc.Rendering.DocumentRenderer renderer=new MigraDoc.Rendering.DocumentRenderer(doc); renderer.PrepareDocument(); totalPages=renderer.FormattedDocument.PageCount; labelTotPages.Text="1 / "+totalPages.ToString(); printdoc.Renderer=renderer; printdoc.PrinterSettings=pd.PrinterSettings; if(previewOnly) { printPreviewControl2.Document=printdoc; } else { try { printdoc.Print(); } catch { MessageBox.Show(Lan.g(this,"Printer not available")); } } }
private void menuItemStatementMore_Click(object sender, System.EventArgs e) { Statement stmt=new Statement(); stmt.PatNum=PatCur.PatNum; stmt.DateSent=DateTime.Today; stmt.IsSent=false; stmt.Mode_=StatementMode.InPerson; stmt.HidePayment=false; stmt.SinglePatient=false; stmt.Intermingled=false; stmt.IsReceipt=false; if(PrefC.GetBool(PrefName.IntermingleFamilyDefault)) { stmt.Intermingled=true; } else { stmt.Intermingled=false; } stmt.DateRangeFrom=DateTime.MinValue; stmt.DateRangeFrom=DateTime.MinValue; if(textDateStart.errorProvider1.GetError(textDateStart)==""){ if(textDateStart.Text!=""){ stmt.DateRangeFrom=PIn.Date(textDateStart.Text); } } if(PrefC.GetBool(PrefName.FuchsOptionsOn)) { stmt.DateRangeFrom=DateTime.Today.AddDays(-90); } stmt.DateRangeTo=DateTime.Today;//Needed for payplan accuracy.//new DateTime(2200,1,1); if(textDateEnd.errorProvider1.GetError(textDateEnd)==""){ if(textDateEnd.Text!=""){ stmt.DateRangeTo=PIn.Date(textDateEnd.Text); } } stmt.Note=""; stmt.NoteBold=""; //All printing and emailing will be done from within the form: FormStatementOptions FormSO=new FormStatementOptions(); stmt.IsNew=true; FormSO.StmtCur=stmt; FormSO.ShowDialog(); ModuleSelected(PatCur.PatNum); }
///<summary></summary> public static void Delete(Statement statement) { //No need to check RemotingRole; no call to db. Delete(statement.StatementNum); }
/// <summary>Saves the statement. Attaches a pdf to it by creating a doc object. Prints it or emails it. </summary> private void PrintStatement(Statement stmt) { Cursor=Cursors.WaitCursor; Statements.Insert(stmt); FormRpStatement FormST=new FormRpStatement(); DataSet dataSet=AccountModules.GetStatementDataSet(stmt); FormST.CreateStatementPdf(stmt,PatCur,FamCur,dataSet); //if(ImageStore.UpdatePatient == null){ // ImageStore.UpdatePatient = new FileStore.UpdatePatientDelegate(Patients.Update); //} Patient guar=Patients.GetPat(stmt.PatNum); string guarFolder=ImageStore.GetPatientFolder(guar,ImageStore.GetPreferredAtoZpath()); //OpenDental.Imaging.ImageStoreBase imageStore = OpenDental.Imaging.ImageStore.GetImageStore(guar); if(stmt.Mode_==StatementMode.Email) { string attachPath=EmailMessages.GetEmailAttachPath(); Random rnd=new Random(); string fileName=DateTime.Now.ToString("yyyyMMdd")+"_"+DateTime.Now.TimeOfDay.Ticks.ToString()+rnd.Next(1000).ToString()+".pdf"; string filePathAndName=ODFileUtils.CombinePaths(attachPath,fileName); File.Copy(ImageStore.GetFilePath(Documents.GetByNum(stmt.DocNum),guarFolder),filePathAndName); //Process.Start(filePathAndName); EmailMessage message=Statements.GetEmailMessageForStatement(stmt,guar); EmailAttach attach=new EmailAttach(); attach.DisplayedFileName="Statement.pdf"; attach.ActualFileName=fileName; message.Attachments.Add(attach); FormEmailMessageEdit FormE=new FormEmailMessageEdit(message); FormE.IsNew=true; FormE.ShowDialog(); //If user clicked delete or cancel, delete pdf and statement if(FormE.DialogResult==DialogResult.Cancel) { Patient pat; string patFolder; if(stmt.DocNum!=0) { //delete the pdf pat=Patients.GetPat(stmt.PatNum); patFolder=ImageStore.GetPatientFolder(pat,ImageStore.GetPreferredAtoZpath()); List<Document> listdocs=new List<Document>(); listdocs.Add(Documents.GetByNum(stmt.DocNum)); try { ImageStore.DeleteDocuments(listdocs,patFolder); } catch { //Image could not be deleted, in use. //This should never get hit because the file was created by this user within this method. //If the doc cannot be deleted, then we will not stop them, they will have to manually delete it from the images module. } } //delete statement Procedures.DetachFromInvoice(stmt.StatementNum); Adjustments.DetachFromInvoice(stmt.StatementNum); Statements.DeleteObject(stmt); } } else {//not email #if DEBUG //don't bother to check valid path because it's just debug. string imgPath=ImageStore.GetFilePath(Documents.GetByNum(stmt.DocNum),guarFolder); DateTime now=DateTime.Now; while(DateTime.Now<now.AddSeconds(5) && !File.Exists(imgPath)) {//wait up to 5 seconds. Application.DoEvents(); } Process.Start(imgPath); #else FormST.PrintStatement(stmt,false,dataSet,FamCur,PatCur); #endif } Cursor=Cursors.Default; }
///<summary>Adds the xml for one statement.</summary> public static void GenerateOneStatement(XmlWriter writer,Statement stmt,Patient pat,Family fam,DataSet dataSet) { writer.WriteStartElement("Statement"); writer.WriteStartElement("RecipientAddress"); Patient guar=fam.ListPats[0]; writer.WriteElementString("Name",guar.GetNameFLFormal()); if(PrefC.GetBool(PrefName.StatementAccountsUseChartNumber)) { writer.WriteElementString("Account",guar.ChartNumber); } else { writer.WriteElementString("Account",POut.Long(guar.PatNum)); } writer.WriteElementString("Address1",guar.Address); writer.WriteElementString("Address2",guar.Address2); writer.WriteElementString("City",guar.City); writer.WriteElementString("State",guar.State); writer.WriteElementString("Zip",guar.Zip); string email=""; Def billingDef=DefC.GetDef(DefCat.BillingTypes,guar.BillingType); if(billingDef.ItemValue=="E") { email=guar.Email; } writer.WriteElementString("EMail",email); writer.WriteEndElement();//RecipientAddress //Account summary----------------------------------------------------------------------- if(stmt.DateRangeFrom.Year<1880) {//make up a statement date. writer.WriteElementString("PriorStatementDate",DateTime.Today.AddMonths(-1).ToString("MM/dd/yyyy")); } else { writer.WriteElementString("PriorStatementDate",stmt.DateRangeFrom.AddDays(-1).ToString("MM/dd/yyyy")); } DateTime dueDate; if(PrefC.GetLong(PrefName.StatementsCalcDueDate)==-1) { dueDate=DateTime.Today.AddDays(10); } else { dueDate=DateTime.Today.AddDays(PrefC.GetLong(PrefName.StatementsCalcDueDate)); } writer.WriteElementString("DueDate",dueDate.ToString("MM/dd/yyyy")); writer.WriteElementString("StatementDate",stmt.DateSent.ToString("MM/dd/yyyy")); double balanceForward=0; for(int r=0;r<dataSet.Tables["misc"].Rows.Count;r++) { if(dataSet.Tables["misc"].Rows[r]["descript"].ToString()=="balanceForward") { balanceForward=PIn.Double(dataSet.Tables["misc"].Rows[r]["value"].ToString()); } } writer.WriteElementString("PriorBalance",balanceForward.ToString("F2")); DataTable tableAccount=null; for(int i=0;i<dataSet.Tables.Count;i++) { if(dataSet.Tables[i].TableName.StartsWith("account")) { tableAccount=dataSet.Tables[i]; } } double credits=0; for(int i=0;i<tableAccount.Rows.Count;i++) { credits+=PIn.Double(tableAccount.Rows[i]["creditsDouble"].ToString()); } writer.WriteElementString("Credits",credits.ToString("F2")); decimal payPlanDue=0; double amountDue=guar.BalTotal; for(int m=0;m<dataSet.Tables["misc"].Rows.Count;m++) { if(dataSet.Tables["misc"].Rows[m]["descript"].ToString()=="payPlanDue") { payPlanDue+=PIn.Decimal(dataSet.Tables["misc"].Rows[m]["value"].ToString());//This will be an option once more users are using it. } } writer.WriteElementString("PayPlanDue",payPlanDue.ToString("F2")); if(PrefC.GetBool(PrefName.BalancesDontSubtractIns)) { writer.WriteElementString("EstInsPayments","");//optional. } else {//this is typical writer.WriteElementString("EstInsPayments",guar.InsEst.ToString("F2"));//optional. amountDue-=guar.InsEst; } InstallmentPlan installPlan=InstallmentPlans.GetOneForFam(guar.PatNum); if(installPlan!=null) { //show lesser of normal total balance or the monthly payment amount. if(installPlan.MonthlyPayment < amountDue) { amountDue=installPlan.MonthlyPayment; } } writer.WriteElementString("AmountDue",amountDue.ToString("F2")); writer.WriteElementString("Bal_0_30",guar.Bal_0_30.ToString("F2"));//optional writer.WriteElementString("PastDue30",guar.Bal_31_60.ToString("F2"));//optional writer.WriteElementString("PastDue60",guar.Bal_61_90.ToString("F2"));//optional writer.WriteElementString("PastDue90",guar.BalOver90.ToString("F2"));//optional //Notes----------------------------------------------------------------------------------- writer.WriteStartElement("Notes"); if(stmt.NoteBold!="") { writer.WriteStartElement("Note"); writer.WriteAttributeString("FgColor","Red"); writer.WriteCData(stmt.NoteBold); writer.WriteEndElement();//Note } if(stmt.Note!="") { writer.WriteStartElement("Note"); writer.WriteCData(stmt.Note); writer.WriteEndElement();//Note } writer.WriteEndElement();//Notes //Detail items------------------------------------------------------------------------------ writer.WriteStartElement("DetailItems"); //string note; string descript; string fulldesc; string procCode; string tth; //string linedesc; string[] lineArray; List<string> lines; DateTime date; int seq=0; for(int i=0;i<tableAccount.Rows.Count;i++) { procCode=tableAccount.Rows[i]["ProcCode"].ToString(); tth=tableAccount.Rows[i]["tth"].ToString(); descript=tableAccount.Rows[i]["description"].ToString(); if(tth=="") { fulldesc=descript; } else { fulldesc=tth+" "+descript; } if(fulldesc==""){ fulldesc=" "; } lineArray=fulldesc.Split(new string[] { "\r\n" },StringSplitOptions.RemoveEmptyEntries); lines=new List<string>(lineArray); //The specs say that the line limit is 30 char. But in testing, it will take 50 char. //We will use 40 char to be safe. if(lines[0].Length>40) { string newline=lines[0].Substring(40); lines[0]=lines[0].Substring(0,40);//first half lines.Insert(1,newline);//second half } for(int li=0;li<lines.Count;li++) { writer.WriteStartElement("DetailItem");//has a child item. We won't add optional child note writer.WriteAttributeString("sequence",seq.ToString()); writer.WriteElementString("ProcCode",procCode); writer.WriteStartElement("Item"); if(li==0) { date=(DateTime)tableAccount.Rows[i]["DateTime"]; writer.WriteElementString("Date",date.ToString("MM/dd/yyyy")); writer.WriteElementString("PatientName",tableAccount.Rows[i]["patient"].ToString()); } else { writer.WriteElementString("Date",""); writer.WriteElementString("PatientName",""); } writer.WriteElementString("Description",lines[li]); if(li==0) { writer.WriteElementString("Charges",tableAccount.Rows[i]["charges"].ToString()); writer.WriteElementString("Credits",tableAccount.Rows[i]["credits"].ToString()); writer.WriteElementString("Balance",tableAccount.Rows[i]["balance"].ToString()); } else { writer.WriteElementString("Charges",""); writer.WriteElementString("Credits",""); writer.WriteElementString("Balance",""); } writer.WriteEndElement();//Item writer.WriteEndElement();//DetailItem seq++; } } writer.WriteEndElement();//DetailItems writer.WriteEndElement();//Statement }
private static DataTable getTable_StatementAging(Statement stmt) { DataTable retVal=new DataTable(); retVal.Columns.Add(new DataColumn("Age00to30")); retVal.Columns.Add(new DataColumn("Age31to60")); retVal.Columns.Add(new DataColumn("Age61to90")); retVal.Columns.Add(new DataColumn("Age90plus")); Patient guar=Patients.GetPat(Patients.GetPat(stmt.PatNum).Guarantor); DataRow row=retVal.NewRow(); row[0]=guar.Bal_0_30.ToString("F"); row[1]=guar.Bal_31_60.ToString("F"); row[2]=guar.Bal_61_90.ToString("F"); row[3]=guar.BalOver90.ToString("F"); retVal.Rows.Add(row); return retVal; }
private static void CreateStatements(int StatementCount) { long[] patNumArray=Patients.GetAllPatNums(); for(int i=0;i<patNumArray.Length;i++) { for(int j=0;j<StatementCount;j++) { Statement st= new Statement(); st.DateSent=new DateTime(2010,12,1,11,0,0).AddDays(1+j); st.DocNum=i+j; st.PatNum=patNumArray[i]; Statements.Insert(st); } } }
///<summary>Creates a new pdf, attaches it to a new doc, and attaches that to the statement. If it cannot create a pdf, for example if no AtoZ folders, then it will simply result in a docnum of zero, so no attached doc. ///Only used for batch statment printing.</summary> public void CreateStatementPdfSheets(Statement stmt,Patient pat,Family fam,DataSet dataSet) { Statement StmtCur=stmt; SheetDef sheetDef=SheetUtil.GetStatementSheetDef(); Sheet sheet=SheetUtil.CreateSheet(sheetDef,StmtCur.PatNum,StmtCur.HidePayment); SheetFiller.FillFields(sheet,StmtCur); SheetUtil.CalculateHeights(sheet,Graphics.FromImage(new Bitmap(sheet.HeightPage,sheet.WidthPage)),StmtCur); string tempPath=CodeBase.ODFileUtils.CombinePaths(PrefL.GetTempFolderPath(),StmtCur.PatNum.ToString()+".pdf"); SheetPrinting.CreatePdf(sheet,tempPath,StmtCur); long category=0; for(int i=0;i<DefC.Short[(int)DefCat.ImageCats].Length;i++) { if(Regex.IsMatch(DefC.Short[(int)DefCat.ImageCats][i].ItemValue,@"S")) { category=DefC.Short[(int)DefCat.ImageCats][i].DefNum; break; } } if(category==0) { category=DefC.Short[(int)DefCat.ImageCats][0].DefNum;//put it in the first category. } //create doc-------------------------------------------------------------------------------------- OpenDentBusiness.Document docc=null; try { docc=ImageStore.Import(tempPath,category,Patients.GetPat(StmtCur.PatNum)); } catch { MsgBox.Show(this,"Error saving document."); //this.Cursor=Cursors.Default; return; } finally { //Delete the temp file since we don't need it anymore. try { File.Delete(tempPath); } catch { //Do nothing. This file will likely get cleaned up later. } } docc.ImgType=ImageType.Document; if(StmtCur.IsInvoice) { docc.Description=Lan.g(this,"Invoice"); } else { if(StmtCur.IsReceipt==true) { docc.Description=Lan.g(this,"Receipt"); } else { docc.Description=Lan.g(this,"Statement"); } } docc.DateCreated=StmtCur.DateSent; Documents.Update(docc); StmtCur.DocNum=docc.DocNum;//this signals the calling class that the pdf was created successfully. Statements.AttachDoc(StmtCur.StatementNum,docc.DocNum); }
///<summary>Returns an email message for the patient based on the statement passed in.</summary> public static EmailMessage GetEmailMessageForStatement(Statement stmt,Patient pat) { //No need to check RemotingRole; no call to db. EmailMessage message=new EmailMessage(); message.PatNum=pat.PatNum; message.ToAddress=pat.Email; message.FromAddress=EmailAddresses.GetByClinic(pat.ClinicNum).SenderAddress; string str; if(stmt.EmailSubject!=null && stmt.EmailSubject!="") { str=stmt.EmailSubject;//Set str to the email subject if one was already set. } else {//Subject was not set. Set str to the default billing email subject. str=PrefC.GetString(PrefName.BillingEmailSubject); } message.Subject=Statements.ReplaceVarsForEmail(str,pat); if(stmt.EmailBody!=null && stmt.EmailBody!="") { str=stmt.EmailBody;//Set str to the email body if one was already set. } else {//Body was not set. Set str to the default billing email body text. str=PrefC.GetString(PrefName.BillingEmailBodyText); } message.BodyText=Statements.ReplaceVarsForEmail(str,pat); return message; }
///<summary>Creates a new pdf, attaches it to a new doc, and attaches that to the statement. If it cannot create a pdf, for example if no AtoZ folders, then it will simply result in a docnum of zero, so no attached doc.</summary> public void CreateStatementPdf(Statement stmt,Patient pat,Family fam,DataSet dataSet){ Stmt=stmt; dataSett=dataSet; //dataSet=AccountModuleL.GetStatement(stmt.PatNum,stmt.SinglePatient,stmt.DateRangeFrom,stmt.DateRangeTo, // stmt.Intermingled); //if(ImageStore.UpdatePatient == null){ // ImageStore.UpdatePatient = new FileStore.UpdatePatientDelegate(Patients.Update); //} //The "pat2" could be either the pat or the guarantor Patient pat2=fam.GetPatient(stmt.PatNum); //Patient pat=Patients.GetPat(stmt.PatNum); //imageStore = ImageStore.GetImageStore(pat2); //Save to a temp pdf-------------------------------------------------------------------------- string tempPath=CodeBase.ODFileUtils.CombinePaths(Path.GetTempPath(),pat2.PatNum.ToString()+".pdf"); PrintDocument pd=new PrintDocument(); pd.DefaultPageSettings.Margins=new Margins(40,40,40,60); if(CultureInfo.CurrentCulture.Name.EndsWith("CH")) {//CH is for switzerland. eg de-CH //leave a big margin on the bottom for the routing slip pd.DefaultPageSettings.Margins=new Margins(40,40,40,440);//4.4" from bottom } //pd.OriginAtMargins=true; //fixes a bug if user has label printer as default printer on their computer: if(pd.DefaultPageSettings.PrintableArea.Height<1000 || pd.DefaultPageSettings.PrintableArea.Width<750) { pd.DefaultPageSettings.PaperSize=new PaperSize("default",850,1100); } MigraDoc.DocumentObjectModel.Document doc=CreateDocument(pd,fam,pat,dataSet); MigraDoc.Rendering.PdfDocumentRenderer pdfRenderer=new MigraDoc.Rendering.PdfDocumentRenderer(true,PdfFontEmbedding.Always); pdfRenderer.Document=doc; pdfRenderer.RenderDocument(); pdfRenderer.PdfDocument.Save(tempPath); //get the category----------------------------------------------------------------------------- long category=0; for(int i=0;i<DefC.Short[(int)DefCat.ImageCats].Length;i++){ if(Regex.IsMatch(DefC.Short[(int)DefCat.ImageCats][i].ItemValue,@"S")){ category=DefC.Short[(int)DefCat.ImageCats][i].DefNum; break; } } if(category==0){ category=DefC.Short[(int)DefCat.ImageCats][0].DefNum;//put it in the first category. } //create doc-------------------------------------------------------------------------------------- OpenDentBusiness.Document docc=null; try { docc=ImageStore.Import(tempPath,category,pat2); } catch { MsgBox.Show(this,"Error saving document."); //this.Cursor=Cursors.Default; return; } docc.ImgType=ImageType.Document; if(Stmt.IsInvoice) { docc.Description=Lan.g(this,"Invoice"); } else { if(Stmt.IsReceipt==true) { docc.Description=Lan.g(this,"Receipt"); } else { docc.Description=Lan.g(this,"Statement"); } } docc.DateCreated=stmt.DateSent; Documents.Update(docc); stmt.DocNum=docc.DocNum;//this signals the calling class that the pdf was created successfully. Statements.AttachDoc(stmt.StatementNum,docc.DocNum); }
private void butCreate_Click(object sender, System.EventArgs e) { if( textExcludeLessThan.errorProvider1.GetError(textExcludeLessThan)!="" || textLastStatement.errorProvider1.GetError(textLastStatement)!="" || textDateStart.errorProvider1.GetError(textDateStart)!="" || textDateEnd.errorProvider1.GetError(textDateEnd)!="" ) { MsgBox.Show(this,"Please fix data entry errors first."); return; } Ledgers.RunAging(); if(PrefC.GetBool(PrefName.AgingCalculatedMonthlyInsteadOfDaily) && PrefC.GetDate(PrefName.DateLastAging) < DateTime.Today.AddDays(-15)) { MsgBox.Show(this,"Last aging date seems old, so you will now be given a chance to update it. The billing process will continue whether or not aging gets updated."); FormAging FormA=new FormAging(); FormA.ShowDialog(); } DateTime lastStatement=PIn.Date(textLastStatement.Text); if(textLastStatement.Text=="") { lastStatement=DateTimeOD.Today; } string getAge=""; if(comboAge.SelectedIndex==1) getAge="30"; else if(comboAge.SelectedIndex==2) getAge="60"; else if(comboAge.SelectedIndex==3) getAge="90"; List<long> billingNums=new List<long>();//[listBillType.SelectedIndices.Count]; for(int i=0;i<listBillType.SelectedIndices.Count;i++){ if(listBillType.SelectedIndices[i]==0){//if (all) is selected, then ignore any other selections billingNums.Clear(); break; } billingNums.Add(DefC.Short[(int)DefCat.BillingTypes][listBillType.SelectedIndices[i]-1].DefNum); } List<long> listClinicNums=new List<long>(); if(!PrefC.GetBool(PrefName.EasyNoClinics)) {//Using clinics. if(comboClinic.SelectedIndex>1) { listClinicNums.Add(ListClinics[comboClinic.SelectedIndex-2].ClinicNum); } else { if(comboClinic.SelectedIndex==0) {//All for(int i=0;i<ListClinics.Count;i++) { listClinicNums.Add(ListClinics[i].ClinicNum); } } listClinicNums.Add(0);//Unassigned will always be used at this point. } } Cursor=Cursors.WaitCursor; List<PatAging> agingList=Patients.GetAgingList(getAge,lastStatement,billingNums,checkBadAddress.Checked, checkExcludeNegative.Checked,PIn.Double(textExcludeLessThan.Text), checkExcludeInactive.Checked,checkIncludeChanged.Checked,checkExcludeInsPending.Checked, checkExcludeIfProcs.Checked,checkIgnoreInPerson.Checked,listClinicNums); DateTime dateRangeFrom=DateTime.MinValue; DateTime dateRangeTo=DateTimeOD.Today;//Needed for payplan accuracy.//new DateTime(2200,1,1); if(textDateStart.Text!=""){ dateRangeFrom=PIn.Date(textDateStart.Text); } if(textDateEnd.Text!=""){ dateRangeTo=PIn.Date(textDateEnd.Text); } if(agingList.Count==0){ Cursor=Cursors.Default; MsgBox.Show(this,"List of created bills is empty."); return; } //if(agingList!=null){ Statement stmt; int ageAccount=0; YN insIsPending=YN.Unknown; Dunning dunning; Dunning[] dunList=Dunnings.Refresh(); for(int i=0;i<agingList.Count;i++){ stmt=new Statement(); stmt.DateRangeFrom=dateRangeFrom; stmt.DateRangeTo=dateRangeTo; stmt.DateSent=DateTimeOD.Today; stmt.DocNum=0; stmt.HidePayment=false; stmt.Intermingled=checkIntermingled.Checked; stmt.IsSent=false; if(PrefC.GetString(PrefName.BillingUseElectronic)=="1" || PrefC.GetString(PrefName.BillingUseElectronic)=="2" || PrefC.GetString(PrefName.BillingUseElectronic)=="3") { stmt.Mode_=StatementMode.Electronic; stmt.Intermingled=true; } else { stmt.Mode_=StatementMode.Mail; } if(DefC.GetDef(DefCat.BillingTypes,agingList[i].BillingType).ItemValue=="E"){ stmt.Mode_=StatementMode.Email; } InstallmentPlan installPlan=InstallmentPlans.GetOneForFam(agingList[i].PatNum); if(installPlan==null) { stmt.Note=textNote.Text; } else { stmt.Note=textNote.Text.Replace("[InstallmentPlanTerms]", "Installment Plan\r\n" +"Date First Payment: "+installPlan.DateFirstPayment.ToShortDateString()+"\r\n" +"Monthly Payment: "+installPlan.MonthlyPayment.ToString("c")+"\r\n" +"APR: "+(installPlan.APR/(float)100).ToString("P")+"\r\n" +"Note: "+installPlan.Note); } stmt.NoteBold=""; //appointment reminders are not handled here since it would be too slow. //set dunning messages here if(agingList[i].BalOver90>0){ ageAccount=90; } else if(agingList[i].Bal_61_90>0){ ageAccount=60; } else if(agingList[i].Bal_31_60>0){ ageAccount=30; } else{ ageAccount=0; } if(agingList[i].InsEst>0){ insIsPending=YN.Yes; } else{ insIsPending=YN.No; } dunning=Dunnings.GetDunning(dunList,agingList[i].BillingType,ageAccount,insIsPending); if(dunning!=null){ if(stmt.Note!=""){ stmt.Note+="\r\n\r\n";//leave one empty line } stmt.Note+=dunning.DunMessage; //if(stmt.Note!=""){//there will never be anything in NoteBold already // stmt.Note+="\r\n\r\n";//leave one empty line //} stmt.NoteBold+=dunning.MessageBold; stmt.EmailSubject=dunning.EmailSubject; stmt.EmailBody=dunning.EmailBody; } stmt.PatNum=agingList[i].PatNum; stmt.SinglePatient=false; Statements.Insert(stmt); } DialogResult=DialogResult.OK; }
private void menuItemStatementEmail_Click(object sender,EventArgs e) { Statement stmt=new Statement(); stmt.PatNum=PatCur.Guarantor; stmt.DateSent=DateTime.Today; stmt.IsSent=true; stmt.Mode_=StatementMode.Email; stmt.HidePayment=false; stmt.SinglePatient=false; stmt.Intermingled=false; stmt.IsReceipt=true; if(PrefC.GetBool(PrefName.IntermingleFamilyDefault)){ stmt.Intermingled=true; } stmt.DateRangeFrom=DateTime.MinValue; if(textDateStart.errorProvider1.GetError(textDateStart)==""){ if(textDateStart.Text!=""){ stmt.DateRangeFrom=PIn.Date(textDateStart.Text); } } stmt.DateRangeTo=new DateTime(2200,1,1); if(textDateEnd.errorProvider1.GetError(textDateEnd)==""){ if(textDateEnd.Text!=""){ stmt.DateRangeTo=PIn.Date(textDateEnd.Text); } } stmt.Note=""; stmt.NoteBold=""; PrintStatement(stmt); ModuleSelected(PatCur.PatNum); }