///<summary>Go through the transaction dictionary created in CreateProcedureLogs() to edit repeat charges as needed. ///Returns the note for the newly generated repeat charge.</summary> private void ZeroOutRepeatingCharge(ProcedureCode procCur, List <AvaTax.TransQtyAmt> listCurTrans) { Commlog prepaymentCommlog = new Commlog(); prepaymentCommlog.PatNum = _patCur.PatNum; prepaymentCommlog.SentOrReceived = CommSentOrReceived.Received; prepaymentCommlog.CommDateTime = DateTime.Now; prepaymentCommlog.CommType = Commlogs.GetTypeAuto(CommItemTypeAuto.FIN); prepaymentCommlog.Mode_ = CommItemMode.None; prepaymentCommlog.Note = "";//Appended to below. prepaymentCommlog.UserNum = Security.CurUser.UserNum; string note = "From PrepaymentTool: \r\n"; bool hasBeenBilledThisMonth = (DateTimeOD.Today.Day >= _patCur.BillingCycleDay); //Get all applicable repeat charges. List <RepeatCharge> listRcForProc = _listRcForPat.FindAll(x => x.ProcCode == procCur.ProcCode && x.IsEnabled); //Get number of months new repeat charge will be for. int numMonths = listCurTrans.Sum(x => x.qty); //Create repeat charge, taken from ContrAccount.cs RepeatCharge rcNew = new RepeatCharge(); rcNew.PatNum = _patCur.PatNum; rcNew.ProcCode = procCur.ProcCode; rcNew.ChargeAmt = 0; rcNew.IsEnabled = true; rcNew.CopyNoteToProc = true; //Build dates using billing day so the patient doesn't have gaps in their repeat charges. DateTime dateBillThisMonth = DateTimeOD.GetMostRecentValidDate(DateTime.Today.Year, DateTime.Today.Month, _patCur.BillingCycleDay); if (hasBeenBilledThisMonth) { //Current month has been billed, push new repeat charge out a month. rcNew.DateStart = dateBillThisMonth.AddMonths(1); rcNew.DateStop = dateBillThisMonth.AddMonths(numMonths); } else { //Current month has not been billed yet, include on this repeat charge. rcNew.DateStart = dateBillThisMonth; rcNew.DateStop = dateBillThisMonth.AddMonths(numMonths - 1); } //Use the stop date to update the Note as requested by Accounting. DatePrepaidThrough = rcNew.DateStop.AddMonths(1).AddDays(-1); rcNew.Note = _prepaidThroughNote; //Edit exisiting repeat charge start/stop dates. foreach (RepeatCharge rcExisting in listRcForProc) { if (rcExisting.DateStop.Year > 1880 && rcExisting.DateStop < DateTimeOD.Today) { continue; //The charge has a stop date in the past (has been disabled). } if (rcExisting.DateStop.Year > 1880 && rcExisting.DateStop <= DateTimeOD.Today.AddMonths(numMonths)) { rcExisting.DateStop = DateTimeOD.Today; rcExisting.IsEnabled = false; //This repeat charge will never be used again due to the prepayment we are creating right now. Disable and add note to commlog for history. note += "Disabled repeat charge with Rate: " + POut.Double(rcExisting.ChargeAmt) + " for Code: " + POut.String(rcExisting.ProcCode) + " Start Date: " + POut.Date(rcExisting.DateStart) + " Stop Date: " + POut.Date(rcExisting.DateStop) + "\r\n"; RepeatCharges.Update(rcExisting); continue; } //Need to push start date of existing repeat charge forward one month past the new repeat charge (if charge months overlap). DateTime dateNext = rcNew.DateStop.AddMonths(1); if (dateNext > rcExisting.DateStart) //Only change if needed. { note += "Edited Start Date for repeat charge from: " + POut.Date(rcExisting.DateStart) + " to: " + POut.Date(dateNext) + " Code: " + POut.String(rcExisting.ProcCode) + " Rate: " + POut.Double(rcExisting.ChargeAmt) + "\r\n"; //Change to billing day to make sure it matches other repeat charges. rcExisting.DateStart = dateNext; RepeatCharges.Update(rcExisting); } } //Insert the new repeat charge. prepaymentCommlog.Note = note; Commlogs.Insert(prepaymentCommlog); RepeatCharges.Insert(rcNew); }
///<summary>The DataTable used to fill the grid will only be refreshed from the db if isFromDb is true. Otherwise the grid will be refilled using ///the existing table. Only get from the db on load or if the Refresh button is pressed, not when the user is selecting the clinic(s).</summary> private void FillGrid(bool isFromDb = false) { Cursor = Cursors.WaitCursor; if (isFromDb) { _charger.FillCharges(_listUserClinics); } List <long> listSelectedClinicNums = listClinics.SelectedIndices.OfType <int>().Select(x => _listUserClinics[x].ClinicNum).ToList(); List <RecurringChargeData> listChargesCur; if (PrefC.HasClinicsEnabled) { listChargesCur = _charger.ListRecurringChargeData.Where(x => listSelectedClinicNums.Contains(x.RecurringCharge.ClinicNum)).ToList(); } else { listChargesCur = _charger.ListRecurringChargeData; } gridMain.BeginUpdate(); gridMain.ListGridColumns.Clear(); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableRecurring", "PatNum"), 55)); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableRecurring", "Name"), PrefC.HasClinicsEnabled?190:220)); if (PrefC.HasClinicsEnabled) { gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableRecurring", "Clinic"), 65)); } gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableRecurring", "Date"), PrefC.HasClinicsEnabled?80:80, HorizontalAlignment.Right)); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableRecurring", "Family Bal"), PrefC.HasClinicsEnabled?70:85, HorizontalAlignment.Right)); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableRecurring", "PayPlan Due"), PrefC.HasClinicsEnabled?75:85, HorizontalAlignment.Right)); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableRecurring", "Total Due"), PrefC.HasClinicsEnabled?65:80, HorizontalAlignment.Right)); gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableRecurring", "Repeat Amt"), PrefC.HasClinicsEnabled?75:90, HorizontalAlignment.Right)); //RptChrgAmt gridMain.ListGridColumns.Add(new GridColumn(Lan.g("TableRecurring", "Charge Amt"), PrefC.HasClinicsEnabled?85:100, HorizontalAlignment.Right)); if (Programs.HasMultipleCreditCardProgramsEnabled()) { if (Programs.IsEnabled(ProgramName.Xcharge)) { gridMain.ListGridColumns.Add(new GridColumn("X-Charge", PrefC.HasClinicsEnabled ? 70 : 80, HorizontalAlignment.Center)); } if (Programs.IsEnabled(ProgramName.PayConnect)) { gridMain.ListGridColumns.Add(new GridColumn("PayConnect", PrefC.HasClinicsEnabled ? 85 : 95, HorizontalAlignment.Center)); } if (Programs.IsEnabled(ProgramName.PaySimple)) { gridMain.ListGridColumns.Add(new GridColumn("PaySimple", PrefC.HasClinicsEnabled ? 80 : 90, HorizontalAlignment.Center)); } } gridMain.ListGridRows.Clear(); GridRow row; foreach (RecurringChargeData chargeCur in listChargesCur) { row = new GridRow(); double famBalTotal = chargeCur.RecurringCharge.FamBal; //pat bal+payplan due, but if pat bal<0 and payplan due>0 then just payplan due double payPlanDue = chargeCur.RecurringCharge.PayPlanDue; double chargeAmt = chargeCur.RecurringCharge.ChargeAmt; double rptChargeAmt = chargeCur.RecurringCharge.RepeatAmt; //includes repeat charge (from procs if ODHQ) and attached payplan row.Cells.Add(chargeCur.RecurringCharge.PatNum.ToString()); row.Cells.Add(chargeCur.PatName); if (PrefC.HasClinicsEnabled) { Clinic clinicCur = _listUserClinics.FirstOrDefault(x => x.ClinicNum == chargeCur.RecurringCharge.ClinicNum); row.Cells.Add(clinicCur != null?clinicCur.Description:""); //get description from cache if clinics are enabled } int billingDay = 0; if (PrefC.GetBool(PrefName.BillingUseBillingCycleDay)) { billingDay = chargeCur.BillingCycleDay; } else { billingDay = chargeCur.RecurringChargeDate.Day; } DateTime startBillingCycle = DateTimeOD.GetMostRecentValidDate(DateTime.Today.Year, DateTime.Today.Month, billingDay); if (startBillingCycle > DateTime.Today) { startBillingCycle = startBillingCycle.AddMonths(-1); //Won't give a date with incorrect day. AddMonths will give the end of the month if needed. } DateTime dateExcludeIfBefore = PIn.Date(textDate.Text); //If entry is invalid, all charges will be included because this will be MinDate. if (startBillingCycle < dateExcludeIfBefore) { continue; //Don't show row in grid } row.Cells.Add(startBillingCycle.ToShortDateString()); row.Cells.Add(famBalTotal.ToString("c")); if (!payPlanDue.IsZero()) { row.Cells.Add(payPlanDue.ToString("c")); } else { row.Cells.Add(""); } row.Cells.Add(chargeCur.RecurringCharge.TotalDue.ToString("c")); row.Cells.Add(rptChargeAmt.ToString("c")); row.Cells.Add(chargeAmt.ToString("c")); if (!checkHideBold.Checked) { double diff = (Math.Max(famBalTotal, 0) + Math.Max(payPlanDue, 0)) - rptChargeAmt; if (diff.IsZero() || (diff < 0 && RecurringCharges.CanChargeWhenNoBal(chargeCur.CanChargeWhenNoBal))) { //don't bold anything } else if (diff > 0) { row.Cells[6].Bold = YN.Yes; //"Repeating Amt" row.Cells[7].Bold = YN.Yes; //"Charge Amt" } else if (diff < 0) { row.Cells[5].Bold = YN.Yes; //"Total Due" row.Cells[7].Bold = YN.Yes; //"Charge Amt" } } if (Programs.HasMultipleCreditCardProgramsEnabled()) { if (Programs.IsEnabled(ProgramName.Xcharge)) { row.Cells.Add(!string.IsNullOrEmpty(chargeCur.XChargeToken) ? "X" : ""); } if (Programs.IsEnabled(ProgramName.PayConnect)) { row.Cells.Add(!string.IsNullOrEmpty(chargeCur.PayConnectToken) ? "X" : ""); } if (Programs.IsEnabled(ProgramName.PaySimple)) { row.Cells.Add(!string.IsNullOrEmpty(chargeCur.PaySimpleToken) ? "X" : ""); } } row.Tag = chargeCur; gridMain.ListGridRows.Add(row); } gridMain.EndUpdate(); labelTotal.Text = Lan.g(this, "Total=") + gridMain.ListGridRows.Count.ToString(); labelSelected.Text = Lan.g(this, "Selected=") + gridMain.SelectedIndices.Length.ToString(); Cursor = Cursors.Default; }
///<summary>Looks in the patient's repeating charges for a rate to use. If the patient does not have a repeat charge setup ///for the procedurecode that is being added then a procedurecharge will not be created. ///This is then used to create one or more procedurecharges.</summary> private void CreateProcedureCharge(ProcedureCode ProcCode, int count, bool isNew = true) { List <RepeatCharge> listRcForProc = _listRcForPat.FindAll(x => x.ProcCode == ProcCode.ProcCode && x.IsEnabled); List <ProcedureCharge> listProcChargeInGrid = _listProcedureCharge.FindAll(x => x.ProcCode == ProcCode); if (listRcForProc.Count == 1) { //Discussed with accounting dept. If there is only one repeat charge for a proc on an account it should never have a stop date. //If for some reason there is a stop date, it is a very special case that we can't currently handle with the prepayment tool. int index = _listProcedureCharge.FindIndex(x => x.BaseFee == listRcForProc[0].ChargeAmt && x.ProcCode == ProcCode); //Does not exist in our list, make a new one. if (index == -1) { ProcedureCharge procCharge = new ProcedureCharge(ProcCode, listRcForProc.FirstOrDefault().ChargeAmt); procCharge.ProcCount = count; procCharge.Calc(); _listProcedureCharge.Add(procCharge); } else { _listProcedureCharge[index].ProcCount += count; } } else if (listRcForProc.Count >= 2) { int remainder = count; foreach (RepeatCharge charge in listRcForProc) { if (remainder <= 0) //Nothing left to add, kick out of loop. { break; } if (charge.DateStop.Year > 1880 && charge.DateStop < DateTimeOD.Today) { continue; //The charge has a stop date in the past (has been disabled). } //Look for existing procedurecharge. int index = _listProcedureCharge.FindIndex(x => x.BaseFee == charge.ChargeAmt && x.ProcCode == ProcCode && x.HasReachedStopDate == false); //Does not exist in our list, make a new one. if (index == -1) { ProcedureCharge procCharge = new ProcedureCharge(ProcCode, charge.ChargeAmt); //See if the months we are adding extends beyond this repeat charge's stop date. DateTime dateToUse = charge.DateStart; //Check if we should use start date or today. Prevent old charges. if (DateTimeOD.Today > charge.DateStart) { dateToUse = DateTimeOD.Today; } if (dateToUse.AddMonths(remainder) > charge.DateStop && charge.DateStop.Year > 1880) { procCharge.HasReachedStopDate = true; //Difference is number of months between today and the stop date, this will become the count for our current procedurecharge int difference = ((charge.DateStop.Year - dateToUse.Year) * 12) + (charge.DateStop.Month - dateToUse.Month); if (DateTimeOD.Today < DateTimeOD.GetMostRecentValidDate(dateToUse.Year, dateToUse.Month, _patCur.BillingCycleDay)) { difference += 1; } procCharge.ProcCount = difference; remainder = remainder - difference; } //Stop date was not reached else { procCharge.ProcCount = remainder; remainder = 0; } procCharge.Calc(); _listProcedureCharge.Add(procCharge); } //Found a matching procedurecharge. else { if (_listProcedureCharge[index].HasReachedStopDate) { //Already hit stopdate for this repeat charge so continue on to the next one. continue; } //See if stop date is mindate, if it is then we can add to the count and exit the loop. if (charge.DateStop.Year < 1880) { _listProcedureCharge[index].ProcCount += remainder; remainder = 0; continue; } //Has a stop date, see if we hit it. else { //See if we should use today or the start date. if (DateTimeOD.Today > charge.DateStart) { //See if the count exceeds the difference between today and stop date of this repeat charge. int difference = ((charge.DateStop.Year - DateTimeOD.Today.Year) * 12) + (charge.DateStop.Month - DateTimeOD.Today.Month); if (DateTimeOD.Today.Day < _patCur.BillingCycleDay) { difference += 1; } int combinedCount = _listProcedureCharge[index].ProcCount + remainder; if (DateTimeOD.Today.AddMonths(combinedCount) >= charge.DateStop) { //Hit the stop date. _listProcedureCharge[index].HasReachedStopDate = true; remainder = combinedCount - difference; _listProcedureCharge[index].ProcCount = difference; } else { _listProcedureCharge[index].ProcCount += remainder; remainder = 0; } } else //Start date in future. //See if the count exceeds the difference between the start and stop date of this repeat charge. { int difference = ((charge.DateStop.Year - charge.DateStart.Year) * 12) + (charge.DateStop.Month - charge.DateStart.Month); int combinedCount = _listProcedureCharge[index].ProcCount + remainder; if (combinedCount > difference) { //Hit the stop date. _listProcedureCharge[index].HasReachedStopDate = true; remainder = combinedCount - difference; _listProcedureCharge[index].ProcCount = difference; } else { _listProcedureCharge[index].ProcCount += remainder; remainder = 0; } } } } } } }