private void FormProcSelect_Load(object sender, System.EventArgs e) { if (_isMultiSelect) { gridMain.SelectionMode = OpenDental.UI.GridSelectionMode.MultiExtended; } _listSelectedProcs = new List <Procedure>(); _listProcedures = Procedures.GetCompleteForPats(new List <long> { _patNumCur }); _listAdjustments = Adjustments.GetAdjustForPats(new List <long> { _patNumCur }); _listPayPlanCharges = PayPlanCharges.GetDueForPayPlans(PayPlans.GetForPats(null, _patNumCur), _patNumCur).ToList(); //Does not get charges for the future. _listPaySplits = PaySplits.GetForPats(new List <long> { _patNumCur }); //Might contain payplan payments. _listInsPayAsTotal = ClaimProcs.GetByTotForPats(new List <long> { _patNumCur }); _listClaimProcs = ClaimProcs.GetForProcs(_listProcedures.Select(x => x.ProcNum).ToList()); labelUnallocated.Visible = _doShowUnallocatedLabel; if (PrefC.GetInt(PrefName.RigorousAdjustments) == (int)RigorousAdjustments.DontEnforce) { radioIncludeAllCredits.Checked = true; } else { radioOnlyAllocatedCredits.Checked = true; } FillGrid(); }
private void FormPayPlanCredits_Load(object sender, EventArgs e) { _listPatNums = new List <long>(); _listPatNums.Add(_patCur.PatNum); _listAdjustments = Adjustments.GetAdjustForPats(_listPatNums); _listProcs = Procedures.GetCompAndTpForPats(_listPatNums); List <PayPlan> listPayPlans = PayPlans.GetForPats(_listPatNums, _patCur.PatNum); //Used to figure out how much we need to pay off procs with, also contains insurance payplans. _listPayPlanCharges = new List <PayPlanCharge>(); if (listPayPlans.Count > 0) { //get all current payplan charges for plans already on the patient, excluding the current one. _listPayPlanCharges = PayPlanCharges.GetDueForPayPlans(listPayPlans, _patCur.PatNum) //Does not get charges for the future. .Where(x => !(x.PayPlanNum == _payPlanCur.PayPlanNum && x.ChargeType == PayPlanChargeType.Credit)).ToList(); //do not get credits for current payplan } List <PaySplit> tempListPaySplits = PaySplits.GetForPats(_listPatNums).Where(x => x.UnearnedType == 0).ToList(); //Might contain payplan payments. Do not include unearned. _listPaySplits = tempListPaySplits.FindAll(x => x.PayPlanNum == 0 || listPayPlans.Exists(y => y.PayPlanNum == x.PayPlanNum)); _listPayments = Payments.GetNonSplitForPats(_listPatNums); _listInsPayAsTotal = ClaimProcs.GetByTotForPats(_listPatNums); //Claimprocs paid as total, might contain ins payplan payments. _listClaimProcs = ClaimProcs.GetForProcs(_listProcs.Select(x => x.ProcNum).ToList()); textCode.Text = Lan.g(this, "None"); FillGrid(); if (!Security.IsAuthorized(Permissions.PayPlanEdit, true)) { this.DisableForm(butCancel, checkHideUnattached, checkShowImplicit, butPrint, gridMain); } }
private void FormProcSelect_Load(object sender, System.EventArgs e) { if (_isMultiSelect) { gridMain.SelectionMode = OpenDental.UI.GridSelectionMode.MultiExtended; } _listSelectedProcs = new List <Procedure>(); _listProcedures = Procedures.GetCompleteForPats(new List <long> { _patNumCur }); if (ShowTpProcs) { _listProcedures.AddRange(Procedures.GetTpForPats(new List <long> { _patNumCur })); } _listAdjustments = Adjustments.GetAdjustForPats(new List <long> { _patNumCur }); _listPayPlanCharges = PayPlanCharges.GetDueForPayPlans(PayPlans.GetForPats(null, _patNumCur), _patNumCur).ToList(); //Does not get charges for the future. _listPaySplits = PaySplits.GetForPats(new List <long> { _patNumCur }); //Might contain payplan payments. foreach (PaySplit split in ListSplitsCur) { //If this is a new payment, its paysplits will not be in the database yet, so we need to add them manually. We might also need to set the //ProcNum on the pay split if it has changed and has not been saved to the database. PaySplit splitDb = _listPaySplits.FirstOrDefault(x => x.IsSame(split)); if (splitDb == null) { _listPaySplits.Add(split); } else { splitDb.ProcNum = split.ProcNum; } } _listInsPayAsTotal = ClaimProcs.GetByTotForPats(new List <long> { _patNumCur }); _listClaimProcs = ClaimProcs.GetForProcs(_listProcedures.Select(x => x.ProcNum).ToList()); labelUnallocated.Visible = _doShowUnallocatedLabel; if (PrefC.GetInt(PrefName.RigorousAdjustments) == (int)RigorousAdjustments.DontEnforce) { radioIncludeAllCredits.Checked = true; } else { radioOnlyAllocatedCredits.Checked = true; } FillGrid(); }
///<summary>This method converts the AccountEntry objects we get back from AccountModules.GetListUnpaidAccountCharges() to MultiAdjEntry objects. ///These are used to fill the grid and do all relevant logic in this form. This method will return a fresh list of procedures and will not show ///any existing adjustments that may have been made in this form already. Called on load and when checkShowImplicit is clicked. ///When called from checkShowImplicit any existing adjustments made will not be shown.(Ask Andrew about this functionality)</summary> private List <MultiAdjEntry> FillListGridEntries(CreditCalcType calc) { List <MultiAdjEntry> retVal = new List <MultiAdjEntry>(); #region Get required data List <Procedure> listProcedures = Procedures.GetCompleteForPats(new List <long> { _patCur.PatNum }); //Does not get charges for the future. List <PaySplit> listPaySplits = PaySplits.GetForPats(new List <long> { _patCur.PatNum }).Where(x => x.UnearnedType == 0).ToList(); List <Adjustment> listAdjustments = Adjustments.GetAdjustForPats(new List <long> { _patCur.PatNum }); //Might contain payplan payments. Do not include unearned. List <PayPlanCharge> listPayPlanCharges = PayPlanCharges.GetDueForPayPlans(PayPlans.GetForPats(null, _patCur.PatNum), _patCur.PatNum).ToList(); List <ClaimProc> listInsPayAsTotal = ClaimProcs.GetByTotForPats(new List <long> { _patCur.PatNum }); List <ClaimProc> listClaimProcs = ClaimProcs.GetForProcs(listProcedures.Select(x => x.ProcNum).ToList()); #endregion List <AccountEntry> listAccountCharges = AccountModules.GetListUnpaidAccountCharges(listProcedures, listAdjustments , listPaySplits, listClaimProcs, listPayPlanCharges, listInsPayAsTotal, calc, new List <PaySplit>()); List <AccountEntry> listAccountChargesIncludeAll = null; if (calc == CreditCalcType.ExcludeAll) { //We need to get all credits so that our AmtRemBefore can reflect what has truly been allocated to the procedure. listAccountChargesIncludeAll = AccountModules.GetListUnpaidAccountCharges(listProcedures, listAdjustments , listPaySplits, listClaimProcs, listPayPlanCharges, listInsPayAsTotal, CreditCalcType.IncludeAll, new List <PaySplit>()); } MultiAdjEntry multiEntry = null; foreach (AccountEntry entry in listAccountCharges) { //We only want AccountEntries that are completed procedures. if (entry.GetType() != typeof(ProcExtended)) { continue; } ProcExtended procEntry = (ProcExtended)entry.Tag; if ((_listSelectedProcs != null && _listSelectedProcs.Any(x => x.ProcNum == procEntry.Proc.ProcNum)) || //Allow selected procs to show if paid off entry.AmountEnd != 0) //All unpaid procedures should always show up per Nathan { double amtRemBefore = (double)(listAccountChargesIncludeAll?.FirstOrDefault(x => x.Tag.GetType() == typeof(ProcExtended) && ((ProcExtended)x.Tag).Proc.ProcNum == procEntry.Proc.ProcNum) ?? entry).AmountStart; multiEntry = new MultiAdjEntry(procEntry.Proc, (double)entry.AmountStart, (double)entry.AmountEnd, amtRemBefore); retVal.Add(multiEntry); } } OrderListGridEntries(); return(retVal); }
private void FillGrid() { gridRemainTimeUnits.BeginUpdate(); gridRemainTimeUnits.ListGridRows.Clear(); List <PatPlan> listPatPlans = PatPlans.Refresh(_patCur.PatNum); List <InsSub> listInsSubs = InsSubs.GetMany(listPatPlans.Select(x => x.InsSubNum).ToList()); List <Benefit> listPatBenefits = Benefits.Refresh(listPatPlans, listInsSubs); if (listPatBenefits.IsNullOrEmpty()) { gridRemainTimeUnits.EndUpdate(); return; } List <InsPlan> listInsPlans = InsPlans.GetByInsSubs(listInsSubs.Select(x => x.InsSubNum).ToList()); List <Carrier> listCarriers = Carriers.GetCarriers(listInsPlans.Select(x => x.CarrierNum).ToList()); //Get the LIM information for all potential subscribers. List <Patient> listSubscribers = Patients.GetLimForPats(listInsSubs.Select(x => x.Subscriber).ToList()); GridRow gridRow; //Get the last year of completed procedures because there is no current TimePeriod for benefits that will care about older procedures. //A subset of these procedures will be used for each specific benefit in order to correctly represent the time units remaining. List <Procedure> listCompletedProcs = Procedures.GetCompletedForDateRange( DateTime.Today.AddYears(-1), DateTimeOD.Today, listPatNums: new List <long> { _patCur.PatNum }); //Get all of the claimprocs associated to the completed procedures in order to link procedures to insurance plans. List <ClaimProc> listClaimProcs = ClaimProcs.GetForProcs(listCompletedProcs.Select(x => x.ProcNum).ToList()); foreach (Benefit benefit in listPatBenefits) { if (benefit.CovCatNum == 0 || //no category benefit.BenefitType != InsBenefitType.Limitations || //benefit type is not limitations (benefit.TimePeriod != BenefitTimePeriod.CalendarYear && //neither calendar year, serviceyear, or 12 months benefit.TimePeriod != BenefitTimePeriod.ServiceYear && benefit.TimePeriod != BenefitTimePeriod.NumberInLast12Months) || benefit.Quantity < 0 || //quantity is negative (negatives are allowed in FormBenefitEdit) benefit.QuantityQualifier != BenefitQuantity.NumberOfServices || //qualifier us not the number of services (benefit.CoverageLevel != BenefitCoverageLevel.Family && //neither individual nor family coverage level benefit.CoverageLevel != BenefitCoverageLevel.Individual)) { continue; } List <Procedure> listProcs; //for calendar year, get completed procs from January.01.CurYear ~ Curdate if (benefit.TimePeriod == BenefitTimePeriod.CalendarYear) { //01/01/CurYear. is there a better way? listProcs = listCompletedProcs.FindAll(x => x.ProcDate >= new DateTime(DateTimeOD.Today.Year, 1, 1)); } else if (benefit.TimePeriod == BenefitTimePeriod.NumberInLast12Months) { //today - 12 months - 1 day. Procedures exactly 1 year ago are not counted in the range listProcs = listCompletedProcs.FindAll(x => x.ProcDate >= DateTimeOD.Today.AddYears(-1).AddDays(1)); } else //if not calendar year, then it must be service year { int monthRenew = InsPlans.RefreshOne(benefit.PlanNum).MonthRenew; //monthrenew only stores the month as an int. if (DateTimeOD.Today.Month >= monthRenew) //if the the current date is past the renewal month, use the current year { listProcs = listCompletedProcs.FindAll(x => x.ProcDate >= new DateTime(DateTimeOD.Today.Year, monthRenew, 1)); } else //otherwise use the previous year { listProcs = listCompletedProcs.FindAll(x => x.ProcDate >= new DateTime(DateTimeOD.Today.Year - 1, monthRenew, 1)); } } Dictionary <long, List <ClaimProc> > dictClaimProcsPerSub; if (benefit.PatPlanNum != 0) { //The list of benefits that we are looping through was filled via listPatPlans so this will never fail. //If this line fails then it means that there was a valid PlanNum AND a valid PatPlanNum set on the benefit which is invalid ATM. dictClaimProcsPerSub = listClaimProcs.FindAll(x => x.InsSubNum == listPatPlans.First(y => y.PatPlanNum == benefit.PatPlanNum).InsSubNum) .GroupBy(x => x.InsSubNum) .ToDictionary(x => x.Key, x => x.ToList()); } else //benefit.PatPlanNum was not set so benefit.PlanNum must be set. { dictClaimProcsPerSub = listClaimProcs.FindAll(x => x.PlanNum == benefit.PlanNum) .GroupBy(x => x.InsSubNum) .ToDictionary(x => x.Key, x => x.ToList()); } foreach (long insSubNum in dictClaimProcsPerSub.Keys) { //The insSubNum should have a corresponding entry within listInsSubs. InsSub insSub = listInsSubs.FirstOrDefault(x => x.InsSubNum == insSubNum); if (insSub == null) { continue; //If not found then there are claimprocs associated to an inssub that is associated to a dropped or missing plan. } InsPlan insPlan = listInsPlans.FirstOrDefault(x => x.PlanNum == insSub.PlanNum); Carrier carrier = listCarriers.FirstOrDefault(x => x.CarrierNum == insPlan.CarrierNum); Patient subscriber = listSubscribers.FirstOrDefault(x => x.PatNum == insSub.Subscriber); CovCat category = CovCats.GetCovCat(benefit.CovCatNum); //Filter out any procedures that are not associated to the insurance plan of the current benefit. List <Procedure> listFilterProcs = listProcs.FindAll(x => x.ProcNum.In(dictClaimProcsPerSub[insSubNum].Select(y => y.ProcNum))); //Calculate the amount used for one benefit. double amtUsed = CovCats.GetAmtUsedForCat(listFilterProcs, category); double amtRemain = benefit.Quantity - amtUsed; gridRow = new GridRow((carrier == null) ? "Unknown" : carrier.CarrierName, (subscriber == null) ? "Unknown" : subscriber.GetNameFL(), category.Description.ToString(), benefit.Quantity.ToString(), amtUsed.ToString("F"), (amtRemain > 0) ? amtRemain.ToString("F") : "0"); gridRemainTimeUnits.ListGridRows.Add(gridRow); } } gridRemainTimeUnits.EndUpdate(); }
///<summary>This method converts the AccountEntry objects we get back from AccountModules.GetListUnpaidAccountCharges() to MultiAdjEntry objects. ///These are used to fill the grid and do all relevant logic in this form. This method will return a fresh list of procedures and will not show ///any existing adjustments that may have been made in this form already. Called on load and when checkShowImplicit is clicked. ///When called from checkShowImplicit any existing adjustments made will not be shown.(Ask Andrew about this functionality)</summary> private List <MultiAdjEntry> FillListGridEntries(CreditCalcType calc) { //CONSIDER ANY CHANGES MADE HERE MAY ALSO NEED TO BE ADDED TO FormProcSelect. List <MultiAdjEntry> retVal = new List <MultiAdjEntry>(); #region Get required data List <Procedure> listProcedures = Procedures.GetCompleteForPats(new List <long> { _patCur.PatNum }); //Does not get charges for the future. List <PaySplit> listPaySplits = PaySplits.GetForPats(new List <long> { _patCur.PatNum }).Where(x => x.UnearnedType == 0).ToList(); List <Adjustment> listAdjustments = Adjustments.GetAdjustForPats(new List <long> { _patCur.PatNum }); //Might contain payplan payments. Do not include unearned. List <PayPlanCharge> listPayPlanCharges = PayPlanCharges.GetDueForPayPlans(PayPlans.GetForPats(null, _patCur.PatNum), _patCur.PatNum).ToList(); List <ClaimProc> listInsPayAsTotal = ClaimProcs.GetByTotForPats(new List <long> { _patCur.PatNum }); List <ClaimProc> listClaimProcs = ClaimProcs.GetForProcs(listProcedures.Select(x => x.ProcNum).ToList()); #endregion List <AccountEntry> listAccountCharges = AccountModules.GetListUnpaidAccountCharges(listProcedures, listAdjustments, listPaySplits, listClaimProcs , listPayPlanCharges, listInsPayAsTotal, calc, new List <PaySplit>()); List <AccountEntry> listAccountChargesIncludeAll = null; if (calc == CreditCalcType.ExcludeAll) { //We need to get all credits so that our AmtRemBefore can reflect what has truly been allocated to the procedure. listAccountChargesIncludeAll = AccountModules.GetListUnpaidAccountCharges(listProcedures, listAdjustments , listPaySplits, listClaimProcs, listPayPlanCharges, listInsPayAsTotal, CreditCalcType.IncludeAll, new List <PaySplit>()); } MultiAdjEntry multiEntry = null; foreach (AccountEntry entry in listAccountCharges) { //We only want AccountEntries that are completed procedures. if (entry.GetType() != typeof(ProcExtended)) { continue; } ProcExtended procEntry = (ProcExtended)entry.Tag; bool isProcSelectedInAccount = false; if (_listSelectedProcs != null && _listSelectedProcs.Any(x => x.ProcNum == procEntry.Proc.ProcNum)) { isProcSelectedInAccount = true; } if (calc == CreditCalcType.ExcludeAll) //show everything. Regardless of procs loading window or amount remaining. { double amtRemBefore = (double)(listAccountChargesIncludeAll?.FirstOrDefault(x => x.Tag.GetType() == typeof(ProcExtended) && ((ProcExtended)x.Tag).Proc.ProcNum == procEntry.Proc.ProcNum) ?? entry).AmountStart; multiEntry = new MultiAdjEntry(procEntry.Proc, (double)entry.AmountStart, (double)entry.AmountEnd, amtRemBefore); retVal.Add(multiEntry); } else if (calc.In(CreditCalcType.IncludeAll, CreditCalcType.AllocatedOnly) && (entry.AmountEnd != 0 || isProcSelectedInAccount)) { //Unpaid procedures should always show per Nathan. If proc was specifically selected before entering window, show it anyways. multiEntry = new MultiAdjEntry(procEntry.Proc, (double)entry.AmountStart, (double)entry.AmountEnd, (double)entry.AmountStart); retVal.Add(multiEntry); } } OrderListGridEntries(); return(retVal); }