Пример #1
0
 private void butOK_Click(object sender, EventArgs e)
 {
     if (textDateAgreement.errorProvider1.GetError(textDateAgreement) != "" ||
         textDateFirstPay.errorProvider1.GetError(textDateFirstPay) != "")
     {
         MsgBox.Show(this, "Please enter valid dates.");
         return;
     }
     if (textMonthlyPayment.errorProvider1.GetError(textMonthlyPayment) != "")
     {
         MsgBox.Show(this, "Please enter a valid monthly payment.");
         return;
     }
     if (textAPR.errorProvider1.GetError(textAPR) != "")
     {
         MsgBox.Show(this, "Please enter a valid annual percentage rate (APR).");
         return;
     }
     InstallmentPlanCur.DateAgreement    = PIn.Date(textDateAgreement.Text);
     InstallmentPlanCur.DateFirstPayment = PIn.Date(textDateFirstPay.Text);
     InstallmentPlanCur.MonthlyPayment   = PIn.Double(textMonthlyPayment.Text);
     InstallmentPlanCur.APR  = PIn.Float(textAPR.Text);
     InstallmentPlanCur.Note = PIn.String(textNote.Text);
     if (IsNew)
     {
         InstallmentPlans.Insert(InstallmentPlanCur);
     }
     else
     {
         InstallmentPlans.Update(InstallmentPlanCur);
     }
     DialogResult = DialogResult.OK;
 }
Пример #2
0
        /// <summary>Returns true if a finance charge is added, false if one is not added</summary>
        private bool AddFinanceCharge(long PatNum, DateTime date, string APR, string atLeast, string ifOver, double OverallBalance, long PriProv, long adjType)
        {
            if (date > DateTime.Today && !PrefC.GetBool(PrefName.FutureTransDatesAllowed))
            {
                MsgBox.Show(this, "Adjustments cannot be made for future dates. Finance charge was not added.");
                return(false);
            }
            InstallmentPlan installPlan = InstallmentPlans.GetOneForFam(PatNum);

            if (installPlan != null)           //Patient has an installment plan so use that APR instead.
            {
                APR = installPlan.APR.ToString();
            }
            Adjustment AdjustmentCur = new Adjustment();

            AdjustmentCur.PatNum = PatNum;
            //AdjustmentCur.DateEntry=PIn.PDate(textDate.Text);//automatically handled
            AdjustmentCur.AdjDate  = date;
            AdjustmentCur.ProcDate = date;
            AdjustmentCur.AdjType  = adjType;
            AdjustmentCur.AdjNote  = "";           //"Finance Charge";
            AdjustmentCur.AdjAmt   = Math.Round(((PIn.Double(APR) * .01d / 12d) * OverallBalance), 2);
            if (AdjustmentCur.AdjAmt.IsZero() || AdjustmentCur.AdjAmt < PIn.Double(ifOver))
            {
                //Don't add the charge if it is less than FinanceChargeOnlyIfOver; if the charge is exactly equal to FinanceChargeOnlyIfOver,
                //the charge will be added. Ex., AdjAmt=2.00 and FinanceChargeOnlyIfOver=2.00, the charge will be added.
                //Unless AdjAmt=0.00, in which case don't add a $0.00 finance charge
                return(false);
            }
            //Add an amount that is at least the amount of FinanceChargeAtLeast
            AdjustmentCur.AdjAmt  = Math.Max(AdjustmentCur.AdjAmt, PIn.Double(atLeast));
            AdjustmentCur.ProvNum = PriProv;
            Adjustments.Insert(AdjustmentCur);
            return(true);
        }
Пример #3
0
 private void butDelete_Click(object sender, EventArgs e)
 {
     if (IsNew)
     {
         DialogResult = DialogResult.Cancel;
         return;
     }
     if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "Are you sure you would like to delete this installment plan?"))
     {
         return;
     }
     InstallmentPlans.Delete(InstallmentPlanCur.InstallmentPlanNum);
     DialogResult = DialogResult.Cancel;
 }
Пример #4
0
        private void AddFinanceCharge(long PatNum, DateTime date, string APR, double OverallBalance, long PriProv)
        {
            InstallmentPlan installPlan = InstallmentPlans.GetOneForFam(PatNum);

            if (installPlan != null)           //Patient has an installment plan so use that APR instead.
            {
                APR = installPlan.APR.ToString();
            }
            Adjustment AdjustmentCur = new Adjustment();

            AdjustmentCur.PatNum = PatNum;
            //AdjustmentCur.DateEntry=PIn.PDate(textDate.Text);//automatically handled
            AdjustmentCur.AdjDate  = date;
            AdjustmentCur.ProcDate = date;
            AdjustmentCur.AdjType  = PrefC.GetLong(PrefName.FinanceChargeAdjustmentType);
            AdjustmentCur.AdjNote  = "";           //"Finance Charge";
            AdjustmentCur.AdjAmt   = Math.Round(((PIn.Double(APR) * .01d / 12d) * OverallBalance), 2);
            AdjustmentCur.ProvNum  = PriProv;
            Adjustments.Insert(AdjustmentCur);
        }
Пример #5
0
        ///<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", "");                         //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"));
            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
        }
Пример #6
0
        ///<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)
        {
            DataTable tableMisc    = dataSet.Tables["misc"];
            DataTable tableAccount = dataSet.Tables.OfType <DataTable>().FirstOrDefault(x => x.TableName.StartsWith("account"));
            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);
            writer.WriteElementString("EMail", guar.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 = tableMisc.Rows.OfType <DataRow>().Where(x => x["descript"].ToString() == "balanceForward")
                                    .Select(x => PIn.Double(x["value"].ToString())).FirstOrDefault();//defaults to 0

            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
            double charges = tableAccount.Rows.OfType <DataRow>().Sum(x => PIn.Double(x["chargesDouble"].ToString()));

            writer.WriteElementString("NewCharges", charges.ToString("F2")); //optional
            writer.WriteElementString("FinanceCharges", "");                 //for future use
            double credits = tableAccount.Rows.OfType <DataRow>().Sum(x => PIn.Double(x["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 due to payplan 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;

            if (PrefC.GetInt(PrefName.PayPlansVersion) == 1)           //with version 2, payplan debits/credits are aged individually and are included in guar.BalTotal
            {
                amountDue += tableMisc.Rows.OfType <DataRow>().Where(x => x["descript"].ToString() == "payPlanDue")
                             .Select(x => PIn.Double(x["value"].ToString())).DefaultIfEmpty(0).Sum();           //add payplan(s) due amt
            }
            double insEst = 0;

            if (!PrefC.GetBool(PrefName.BalancesDontSubtractIns))             //this is typical
            {
                insEst = guar.InsEst;
            }
            InstallmentPlan installPlan = InstallmentPlans.GetOneForFam(guar.PatNum);

            if (installPlan != null && installPlan.MonthlyPayment < (amountDue - insEst))
            {
                amountDue = installPlan.MonthlyPayment;
                insEst    = 0;
            }
            writer.WriteElementString("EstInsPayments", insEst.ToString("F2"));    //optional.
            writer.WriteElementString("PatientShare", (amountDue - insEst).ToString("F2"));
            writer.WriteElementString("CurrentBalance", amountDue.ToString("F2")); //this is ambiguous.  It seems to be AmountDue, but it could 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.WriteCData(stmt.NoteBold.Left(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.WriteCData(stmt.Note.Left(500)); //Limit of 500 char on notes.
                writer.WriteEndElement();               //Note
            }
            writer.WriteEndElement();                   //Notes
            //Detail items------------------------------------------------------------------------------
            writer.WriteStartElement("DetailItems");
            List <string> lines;
            int           seq = 0;
            //Jessica at DentalXchange says limit is 120.  Specs say limit is 30.
            //If we send more than 50 characters, DentalXChange will break the line at the 50th character, even if it is in the middle of a word, and wrap
            //the rest of the line, so up to 70 chars onto line 2, which could easily extend past the end of the description field.  The wrapped line will
            //also have a different line spacing than if sent as a separate xml element.  See the examples in
            //...\Programmers Documents\eClaims Clearinghouse and Carrier Specific Details\DentalXChange ClaimConnect\ClaimConnect - EHG - WebClaim\EHG Statements\Examples
            //Example: original description:
            //line 1: 'D6103 5  bone graft for repair of periimplant defect - does not include flap entry and closure.  Placement of a barrier membrane or biologic materials to aid in osseous regeneration are reported separately'
            //version 16.2 sent as:
            //line 1: 'D6103 5  bone graft for repair of periimplant defect - does not include flap entry and closure.  Placement of a barrier '
            //line 2: 'membrane or biologic materials to aid in osseous regeneration are reported separately'
            //DentalXChange displayed lines as (with line 2 extended past the end of the description field):
            //line 1: 'D6103 5 bone graft for repair of periimplant defe -'
            //line 2: 'ct - does not include flap entry and closure. Placement of a barrier'
            //line 3: 'membrane or biologic materials to aid in osseous r -'
            //line 4: 'egeneration are reported separately'
            //version 16.3 and up sent and displayed as:
            //line 1: 'D6103 5  bone graft for repair of periimplant'
            //line 2: 'defect - does not include flap entry and closure.'
            //line 3: 'Placement of a barrier membrane or biologic'
            //line 4: 'materials to aid in osseous regeneration are'
            //line 5: 'reported separately'
            const int lineMaxLen = 50;
            int       firstIndexNewLine;
            string    lineCur;

            foreach (DataRow rowCur in tableAccount.Rows)
            {
                //There are frequently CRs within a procedure description for things like ins est.
                lines = string.Join(" ", new[] { rowCur["ProcCode"].ToString(), rowCur["tth"].ToString(), rowCur["description"].ToString() })
                        .Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();
                for (int li = 0; li < lines.Count; li++)
                {
                    lineCur = lines[li];
                    if (lineCur.Length < 1 || lineCur.All(x => char.IsWhiteSpace(x)))                   //nothing to write
                    {
                        continue;
                    }
                    writer.WriteStartElement("DetailItem");                    //has a child item. We won't add optional child note
                    writer.WriteAttributeString("sequence", seq.ToString());
                    writer.WriteStartElement("Item");
                    writer.WriteElementString("Date", li == 0?PIn.Date(rowCur["DateTime"].ToString()).ToString("MM/dd/yyyy"):"");
                    writer.WriteElementString("PatientName", li == 0?rowCur["patient"].ToString():"");
                    if (lineCur.Length > lineMaxLen)
                    {
                        firstIndexNewLine = lineMaxLen;
                        for (int c = lineMaxLen - 2; c > -1; c--)                 //-2, 1 for length to index and 1 so we can safely check index and index+1
                        {
                            if (!char.IsWhiteSpace(lineCur[c]) && char.IsWhiteSpace(lineCur[c + 1]))
                            {
                                firstIndexNewLine = c + 1;
                                break;
                            }
                        }
                        lines.Insert(li + 1, lineCur.Substring(firstIndexNewLine).Trim());
                        lines[li] = lineCur.Left(firstIndexNewLine);
                    }
                    writer.WriteStartElement("Description");
                    writer.WriteCData(lines[li]);                //CData to allow any string, including punctuation, syntax characters and special characters.
                    writer.WriteEndElement();                    //Description
                    writer.WriteElementString("Charges", li == 0?rowCur["charges"].ToString():"");
                    writer.WriteElementString("Credits", li == 0?rowCur["credits"].ToString():"");
                    writer.WriteElementString("Balance", li == 0?rowCur["balance"].ToString():"");
                    writer.WriteEndElement();                    //Item
                    writer.WriteEndElement();                    //DetailItem
                    seq++;
                }
                #region Notes Don't Display On Statements

                /*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
                 * }*/
                #endregion Notes Don't Display On Statements
            }
            writer.WriteEndElement();            //DetailItems
            writer.WriteEndElement();            //Patient
            writer.WriteEndElement();            //EisStatement
        }
Пример #7
0
        ///<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 = Defs.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("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();
                fulldesc  = procCode + " " + tth + " " + descript;
                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.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
        }
Пример #8
0
        ///<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
        }