///<summary>Calculates the info for the dashboard</summary> private void RefreshAll() { //Validation if(_jobSprintCur.DateStart>_jobSprintCur.DateEndTarget) { return; } #region Variables _listJobSprintLinks=JobSprintLinks.GetForSprint(_jobSprintCur.JobSprintNum); _listAttachedJobs=_listJobsAll.FindAll(x => _listJobSprintLinks.Select(y => y.JobNum).Contains(x.JobNum) && x.Category.In(JobCategory.Feature,JobCategory.Enhancement,JobCategory.InternalRequest,JobCategory.HqRequest,JobCategory.ProgramBridge)); List<Job> listBugJobs=_listJobsAll.FindAll(x => x.Category==JobCategory.Bug); DateTime dateStart=_jobSprintCur.DateStart; DateTime dateProgress=DateTime.Today.Date; DateTime dateEnd=_jobSprintCur.DateEndTarget; List<Job> listCompletedBugJobs=listBugJobs.FindAll(x => x.PhaseCur.In(JobPhase.Documentation,JobPhase.Complete) && x.ListJobLinks.Count(y => y.LinkType==JobLinkType.Bug)>0 && DateTimeOD.Between(x.ListJobLogs.FirstOrDefault(y => y.Description.Contains("Job implemented"))?.DateTimeEntry??DateTime.MinValue,dateStart,dateEnd)); List<Job> listRemainingBugJobs=listBugJobs.FindAll(x => x.PhaseCur.In(JobPhase.Concept,JobPhase.Definition,JobPhase.Quote,JobPhase.Development) && x.ListJobLinks.Count(y => y.LinkType==JobLinkType.Bug)>0); double totalDays=(dateEnd - dateStart).TotalDays; double totalDaysElapsed=(dateProgress - dateStart).TotalDays; double totalDaysLeft=totalDays-totalDaysElapsed; int targetValuePercent=(int)(totalDaysElapsed/totalDays*100); double jobPercent=_jobSprintCur.JobPercent; double avgDevHours=_jobSprintCur.HoursAverageDevelopment; double avgBreakHours=_jobSprintCur.HoursAverageBreak; double totalAllocatedHours=0; double totalCompletedHours=0; double hoursComplete=_listAttachedJobs.Sum(x => x.HoursActual); double hoursTotal=_listAttachedJobs.Sum(x => x.HoursEstimate); double hoursRemaining=hoursTotal-hoursComplete>0?hoursTotal-hoursComplete:0; double totalJobsRemaining=_listAttachedJobs.Where(x => x.PhaseCur.In(JobPhase.Concept,JobPhase.Definition,JobPhase.Quote,JobPhase.Development)).Count()+listRemainingBugJobs.Count; double totalJobsCompleted=_listAttachedJobs.Where(x => x.PhaseCur.In(JobPhase.Documentation,JobPhase.Complete)).Count()+listCompletedBugJobs.Count(); #endregion #region Top Panel this.Text=_jobSprintCur.Title; textStartDate.Text=_jobSprintCur.DateStart.ToShortDateString(); textEndDate.Text=_jobSprintCur.DateEndTarget.ToShortDateString(); //Calculate hours for the list of jobs attached to the sprint foreach(Job job in _listAttachedJobs) { //Do not include "completed" jobs if(job.PhaseCur.In(JobPhase.Documentation,JobPhase.Complete,JobPhase.Cancelled)) { continue; } double estimate=job.HoursEstimate; if(job.HoursEstimateDevelopment==0) { estimate+=avgDevHours; } totalAllocatedHours+=estimate; totalAllocatedHours-=job.HoursActual; totalCompletedHours+=job.HoursActual; } //Calculate and Set Work Complete Percent double completionPercentage=0; completionPercentage=(totalCompletedHours/totalAllocatedHours)*100; if(Double.IsNaN(completionPercentage)) { completionPercentage=0; } completionPercentage=completionPercentage>=100?100:completionPercentage; //Set Progress Bar Value and TargetValue textCompletePercentage.Text=(int)completionPercentage+"%"; progressComplete.Value=(int)completionPercentage; progressComplete.TargetValue=(int)completionPercentage; textElapsedPercentage.Text=targetValuePercent+"%"; progressElapsed.Value=targetValuePercent; progressElapsed.TargetValue=targetValuePercent; //Set Days Left textDaysLeft.Text=totalDaysLeft+" Days Left"; //textScopeChange.Text=(_listAttachedJobs.Where(x => x.ListJobLogs.Exists(y => y.Description.Contains("Changes approved."))).Count()/_listAttachedJobs.Count*100)+"%"; #endregion #region Left Panel //Set all completed job percentages List<double> listCompletedPercents=new List<double>(); listCompletedPercents.Add(Math.Round((listCompletedBugJobs.Count()/totalJobsCompleted*100),2)); textCompletedBugsForRange.Text=listCompletedPercents.Last().ToString("0.00")+"%"; listCompletedPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.Feature && x.PhaseCur.In(JobPhase.Documentation,JobPhase.Complete)).Count()/totalJobsCompleted*100),2)); textCompletedFeaturesForRange.Text=listCompletedPercents.Last().ToString("0.00")+"%"; listCompletedPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.Enhancement && x.PhaseCur.In(JobPhase.Documentation,JobPhase.Complete)).Count()/totalJobsCompleted*100),2)); textCompletedEnhancementsForRange.Text=listCompletedPercents.Last().ToString("0.00")+"%"; listCompletedPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.InternalRequest && x.PhaseCur.In(JobPhase.Documentation,JobPhase.Complete)).Count()/totalJobsCompleted*100),2)); textCompletedInternalRequestsForRange.Text=listCompletedPercents.Last().ToString("0.00")+"%"; listCompletedPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.HqRequest && x.PhaseCur.In(JobPhase.Documentation,JobPhase.Complete)).Count()/totalJobsCompleted*100),2)); textCompletedHQRequestsForRange.Text=listCompletedPercents.Last().ToString("0.00")+"%"; listCompletedPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.ProgramBridge && x.PhaseCur.In(JobPhase.Documentation,JobPhase.Complete)).Count()/totalJobsCompleted*100),2)); textCompletedBridgesForRange.Text=listCompletedPercents.Last().ToString("0.00")+"%"; DrawCompletedPieChart(listCompletedPercents); textJobsComplete.Text=totalJobsCompleted.ToString(); #endregion #region Right Panel //Set all remaining job percentages List<double> listRemainingPercents=new List<double>(); listRemainingPercents.Add(Math.Round((listRemainingBugJobs.Count()/totalJobsRemaining*100),2)); textRemainingBugPercent.Text=listRemainingPercents.Last().ToString("0.00")+"%"; listRemainingPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.Feature && x.PhaseCur.In(JobPhase.Concept,JobPhase.Definition,JobPhase.Quote,JobPhase.Development)).Count()/totalJobsRemaining*100),2)); textRemainingFeaturePercent.Text=listRemainingPercents.Last().ToString("0.00")+"%"; listRemainingPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.Enhancement && x.PhaseCur.In(JobPhase.Concept,JobPhase.Definition,JobPhase.Quote,JobPhase.Development)).Count()/totalJobsRemaining*100),2)); textRemainingEnhancementPercent.Text=listRemainingPercents.Last().ToString("0.00")+"%"; listRemainingPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.InternalRequest && x.PhaseCur.In(JobPhase.Concept,JobPhase.Definition,JobPhase.Quote,JobPhase.Development)).Count()/totalJobsRemaining*100),2)); textRemainingInternalRequestPercent.Text=listRemainingPercents.Last().ToString("0.00")+"%"; listRemainingPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.HqRequest && x.PhaseCur.In(JobPhase.Concept,JobPhase.Definition,JobPhase.Quote,JobPhase.Development)).Count()/totalJobsRemaining*100),2)); textRemainingHQRequestPercent.Text=listRemainingPercents.Last().ToString("0.00")+"%"; listRemainingPercents.Add(Math.Round((_listAttachedJobs.Where(x => x.Category==JobCategory.ProgramBridge && x.PhaseCur.In(JobPhase.Concept,JobPhase.Definition,JobPhase.Quote,JobPhase.Development)).Count()/totalJobsRemaining*100),2)); textRemainingBridgePercent.Text=listRemainingPercents.Last().ToString("0.00")+"%"; DrawRemainingPieChart(listRemainingPercents); textJobsRemaining.Text=(totalJobsRemaining-listRemainingBugJobs.Count).ToString();//Don't count bugs here #endregion #region Bottom Panel List<Job> listStaleBugs=listRemainingBugJobs.FindAll(x => x.ListJobTimeLogs.Count>0?x.ListJobTimeLogs.Select(y => y.DateTStamp).Max()<DateTime.Today.AddDays(-5):x.DateTimeEntry<DateTime.Today.AddDays(-5)) .OrderBy(x => x.ListJobTimeLogs.Count>0?x.ListJobTimeLogs.Select(y => y.DateTStamp).Max():x.DateTimeEntry).ToList(); gridBugJobs.Title=listRemainingBugJobs.Count()+" Bugs ("+listStaleBugs.Count()+" Stale)"; FillGridOldBugs(listStaleBugs); #endregion }
///<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; }
private void RefreshTopPanel(List <Job> listJobs, DateTime dateStart, DateTime dateEnd) { //Calculate the three month average per day //listJobsNonBugEnhancement is used because we do not want to consider bugs/enhancements (Backport jobs) as part of this version List <Job> listCompletedJobs = listJobs.FindAll(x => x.PhaseCur.In(JobPhase.Documentation, JobPhase.Complete) && DateTimeOD.Between(x.ListJobLogs.FirstOrDefault(y => y.Description.Contains("Job implemented"))?.DateTimeEntry ?? DateTime.MinValue, dateStart, dateEnd)); //We only want incomplete jobs that are marked as current version. This disregards priority. List <Job> listRemainingJobs = listJobs.FindAll(x => x.PhaseCur.In(JobPhase.Concept, JobPhase.Definition, JobPhase.Quote, JobPhase.Development) && x.ProposedVersion == JobProposedVersion.Current); //Calculate the remaining hours for the version double totalRemainingHours = listRemainingJobs.Sum(x => x.HoursEstimate - x.HoursActual); totalRemainingHours = totalRemainingHours < 0 ? 0 : totalRemainingHours; //Completed hours is only the hours actual. Should not be negative, but I check for it just in case. double totalCompletedHours = listCompletedJobs.Sum(x => x.HoursActual); totalCompletedHours = totalCompletedHours < 0 ? 0 : totalCompletedHours; //Calculate the total hours value for the version. //We use the estimate from the remaining jobs since that is the perceived total amount of time it will take. //We use the hours actual from complete jobs because we know the job is done and will take no more time than what was taken. double totalVersionHours = totalCompletedHours + listRemainingJobs.Sum(x => x.HoursEstimate); totalVersionHours = totalVersionHours < 0 ? 0 : totalVersionHours; //Calculate work complete percent double completionPercentage = ((totalCompletedHours + listRemainingJobs.Sum(x => x.HoursActual)) / totalVersionHours) * 100; //Validate that the return is a valid percentage if (Double.IsNaN(completionPercentage)) { completionPercentage = 0; } completionPercentage = completionPercentage >= 100 ? 100 : completionPercentage; //Calculate day variables double totalDays = (dateEnd - dateStart).TotalDays; double totalDaysElapsed = (DateTime.Today.Date - dateStart).TotalDays; double totalDaysLeft = totalDays - totalDaysElapsed; //We don't need to display negative days left if (totalDaysLeft < 0) { totalDaysLeft = 0; } //Calculate target percent int targetValuePercent = (int)(totalDaysElapsed / totalDays * 100); if (targetValuePercent > 100) { targetValuePercent = 100; } if (targetValuePercent < 0) { targetValuePercent = 0; } //Calculate average hours/day of job time for the last 3 months double hoursLogged = listJobs.Sum(x => x.ListJobTimeLogs.Where(y => y.DateTStamp.Between(DateTime.Today.AddMonths(-3), DateTime.Today)).Sum(y => y.Hours)); //hoursReviewed is multiplied by 2 to denote that two engineers time was expended per review double hoursReviewed = listJobs.Sum(x => x.ListJobReviews.Where(y => y.DateTStamp.Between(DateTime.Today.AddMonths(-3), DateTime.Today)).Sum(y => y.Hours)) * 2; double hoursCompletePerDay = (hoursLogged + hoursReviewed) / (DateTime.Today - DateTime.Today.AddMonths(-3)).TotalDays; //Calculate days remaining double daysRemainingEstimate = Math.Round(totalRemainingHours / hoursCompletePerDay, 0); //If for some reason we just divided by 0... if (Double.IsNaN(daysRemainingEstimate)) { daysRemainingEstimate = 0; } //Set Panel's Controls //Dates textStartDate.Text = _jobSprintCur.DateStart.ToShortDateString(); textTargetDate.Text = _jobSprintCur.DateEndTarget.ToShortDateString() + " (" + totalDaysLeft + " days)"; textProjectedRelease.Text = DateTime.Today.AddDays(daysRemainingEstimate).ToShortDateString() + " (" + Math.Abs(daysRemainingEstimate) + " days)"; //Work Complete textCompletePercentage.Text = (int)completionPercentage + "%"; progressComplete.Value = (int)completionPercentage; progressComplete.TargetValue = (int)completionPercentage; //This could be changed to the target value percent if we want //Time elapsed textElapsedPercentage.Text = targetValuePercent + "%"; progressElapsed.Value = targetValuePercent; progressElapsed.TargetValue = targetValuePercent; }
///<summary>Calculates the info for the dashboard</summary> private void RefreshAll() { //Validation if (_jobSprintCur.DateStart > _jobSprintCur.DateEndTarget) { return; } this.Text = _jobSprintCur.Title; #region Variables DateTime dateStart = _jobSprintCur.DateStart; DateTime dateProgress = DateTime.Today.Date; DateTime dateEnd = _jobSprintCur.DateEndTarget; //Distill the _listJobsAll into two job subsets List <Job> listJobsNonBugEnhancement = _listJobsAll.FindAll(x => x.Category.In(JobCategory.Feature, JobCategory.InternalRequest, JobCategory.HqRequest, JobCategory.ProgramBridge)); List <Job> listJobsBugEnhancement = _listJobsAll.FindAll(x => x.Category.In(JobCategory.Bug, JobCategory.Enhancement)); //Make the actual lists we will be using List <Job> listJobsCompletedNonBugEnhancement = listJobsNonBugEnhancement.FindAll(x => x.PhaseCur.In(JobPhase.Documentation, JobPhase.Complete) && DateTimeOD.Between(x.ListJobLogs.FirstOrDefault(y => y.Description.Contains("Job implemented"))?.DateTimeEntry ?? DateTime.MinValue, dateStart, dateEnd)); List <Job> listCompletedNonBugJobsThreeMonths = _listJobsAll.FindAll(x => x.PhaseCur.In(JobPhase.Documentation, JobPhase.Complete) && x.Category.In(JobCategory.Feature, JobCategory.InternalRequest, JobCategory.HqRequest, JobCategory.ProgramBridge, JobCategory.Enhancement) && DateTimeOD.Between(x.ListJobLogs.FirstOrDefault(y => y.Description.Contains("Job implemented"))?.DateTimeEntry ?? DateTime.MinValue, DateTime.Today.AddMonths(-3), DateTime.Today)); List <Job> listRemainingNonBugJobs = listJobsNonBugEnhancement.FindAll(x => x.PhaseCur.In(JobPhase.Concept, JobPhase.Definition, JobPhase.Quote, JobPhase.Development) && x.ProposedVersion == JobProposedVersion.Current); List <Job> listCompletedBackportJobs = listJobsBugEnhancement.FindAll(x => x.PhaseCur.In(JobPhase.Documentation, JobPhase.Complete) && x.ListJobLinks.Count(y => y.LinkType == JobLinkType.Bug) > 0 && DateTimeOD.Between(x.ListJobLogs.FirstOrDefault(y => y.Description.Contains("Job implemented"))?.DateTimeEntry ?? DateTime.MinValue, dateStart, dateEnd)); List <Job> listRemainingBugJobs = listJobsBugEnhancement.FindAll(x => x.Category == JobCategory.Bug && x.PhaseCur.In(JobPhase.Concept, JobPhase.Definition, JobPhase.Quote, JobPhase.Development) && x.ListJobLinks.Count(y => y.LinkType == JobLinkType.Bug) > 0); List <Job> listRemainingEnhancementJobs = listJobsBugEnhancement.FindAll(x => x.Category == JobCategory.Enhancement && x.PhaseCur.In(JobPhase.Concept, JobPhase.Definition, JobPhase.Quote, JobPhase.Development) && x.ProposedVersion == JobProposedVersion.Current); double totalDays = (dateEnd - dateStart).TotalDays; double totalDaysElapsed = (dateProgress - dateStart).TotalDays; double totalDaysLeft = totalDays - totalDaysElapsed; double jobPercent = _jobSprintCur.JobPercent; double hoursComplete = listJobsCompletedNonBugEnhancement.Sum(x => x.HoursActual) + listRemainingNonBugJobs.Sum(x => x.HoursActual); double hoursTotal = listJobsCompletedNonBugEnhancement.Sum(x => x.HoursActual) + listRemainingNonBugJobs.Sum(x => x.HoursEstimate); double hoursRemaining = hoursTotal - hoursComplete > 0?hoursTotal - hoursComplete:0; #endregion RefreshTopPanel(listJobsNonBugEnhancement, dateStart, dateEnd); #region Left Upper Panel //Set all completed job percentages List <double> listCompletedPercents = new List <double>(); //Cast one to a double so the int doesn't truncate to 0. double percent = (double)(listJobsCompletedNonBugEnhancement.Where(x => x.Category == JobCategory.Feature).Count()) / listJobsCompletedNonBugEnhancement.Count() * 100; listCompletedPercents.Add(Math.Round(percent, 2)); textCompletedFeaturesForRange.Text = percent.ToString("0.00") + "%"; percent = (double)(listJobsCompletedNonBugEnhancement.Where(x => x.Category == JobCategory.HqRequest).Count()) / listJobsCompletedNonBugEnhancement.Count() * 100; listCompletedPercents.Add(Math.Round(percent, 2)); textCompletedHQRequestsForRange.Text = percent.ToString("0.00") + "%"; percent = (double)(listJobsCompletedNonBugEnhancement.Where(x => x.Category == JobCategory.InternalRequest).Count()) / listJobsCompletedNonBugEnhancement.Count() * 100; listCompletedPercents.Add(Math.Round(percent, 2)); textCompletedInternalRequestsForRange.Text = percent.ToString("0.00") + "%"; percent = (double)(listJobsCompletedNonBugEnhancement.Where(x => x.Category == JobCategory.ProgramBridge).Count()) / listJobsCompletedNonBugEnhancement.Count() * 100; listCompletedPercents.Add(Math.Round(percent, 2)); textCompletedBridgesForRange.Text = percent.ToString("0.00") + "%"; DrawCompletedPieChart(listCompletedPercents); textJobsComplete.Text = listJobsCompletedNonBugEnhancement.Count().ToString(); #endregion #region Right Upper Panel //Set all remaining job percentages List <double> listRemainingPercents = new List <double>(); percent = (double)(listRemainingNonBugJobs.Where(x => x.Category == JobCategory.Feature).Count()) / listRemainingNonBugJobs.Count() * 100; listRemainingPercents.Add(Math.Round(percent, 2)); textRemainingFeaturePercent.Text = percent.ToString("0.00") + "%"; percent = (double)(listRemainingNonBugJobs.Where(x => x.Category == JobCategory.HqRequest).Count()) / listRemainingNonBugJobs.Count() * 100; listRemainingPercents.Add(Math.Round(percent, 2)); textRemainingHQRequestPercent.Text = percent.ToString("0.00") + "%"; percent = (double)(listRemainingNonBugJobs.Where(x => x.Category == JobCategory.InternalRequest).Count()) / listRemainingNonBugJobs.Count() * 100; listRemainingPercents.Add(Math.Round(percent, 2)); textRemainingInternalRequestPercent.Text = percent.ToString("0.00") + "%"; percent = (double)(listRemainingNonBugJobs.Where(x => x.Category == JobCategory.ProgramBridge).Count()) / listRemainingNonBugJobs.Count() * 100; listRemainingPercents.Add(Math.Round(percent, 2)); textRemainingBridgePercent.Text = percent.ToString("0.00") + "%"; DrawRemainingPieChart(listRemainingPercents); textJobsRemaining.Text = listRemainingNonBugJobs.Count().ToString(); #endregion #region Left Lower Panel //Set all completed backport percentages List <double> listCompletedBackportPercents = new List <double>(); percent = (double)(listCompletedBackportJobs.FindAll(x => x.Category == JobCategory.Bug).Count()) / listCompletedBackportJobs.Count() * 100; listCompletedBackportPercents.Add(Math.Round(percent, 2)); textCompletedBugPercentage.Text = percent.ToString("0.00") + "%"; percent = (double)(listCompletedBackportJobs.FindAll(x => x.Category == JobCategory.Enhancement).Count()) / listCompletedBackportJobs.Count() * 100; listCompletedBackportPercents.Add(Math.Round(percent, 2)); textCompletedEnhancementPercentage.Text = percent.ToString("0.00") + "%"; DrawCompletedBackportPieChart(listCompletedBackportPercents); textCompletedBackports.Text = listCompletedBackportJobs.Count().ToString(); #endregion #region Right Lower Panel //Set all remaining backport percentages List <double> listRemainingBackportPercents = new List <double>(); int countBugEnhancement = listRemainingBugJobs.Count() + listRemainingEnhancementJobs.Count(); percent = (double)(listRemainingBugJobs.Count()) / countBugEnhancement * 100; listRemainingBackportPercents.Add(Math.Round(percent, 2)); textRemainingBugPercentage.Text = percent.ToString("0.00") + "%"; percent = (double)(listRemainingEnhancementJobs.Count()) / countBugEnhancement * 100; listRemainingBackportPercents.Add(Math.Round(percent, 2)); textRemainingEnhancementPercentage.Text = percent.ToString("0.00") + "%"; DrawRemainingBackportPieChart(listRemainingBackportPercents); textRemainingBackports.Text = countBugEnhancement.ToString(); #endregion #region Bottom Panel List <Job> listStaleBugs = listRemainingBugJobs.FindAll(x => x.ListJobTimeLogs.Count > 0 ? x.ListJobTimeLogs.Select(y => y.DateTStamp).Max() < DateTime.Today.AddDays(-7) : x.DateTimeEntry < DateTime.Today.AddDays(-7)) .OrderBy(x => x.ListJobTimeLogs.Count > 0 ? x.ListJobTimeLogs.Select(y => y.DateTStamp).Max() : x.DateTimeEntry).ToList(); List <Job> listStaleEnhancements = listRemainingEnhancementJobs.FindAll(x => x.ListJobTimeLogs.Count > 0 ? x.ListJobTimeLogs.Select(y => y.DateTStamp).Max() < DateTime.Today.AddDays(-7) : x.DateTimeEntry < DateTime.Today.AddDays(-7)) .OrderBy(x => x.ListJobTimeLogs.Count > 0 ? x.ListJobTimeLogs.Select(y => y.DateTStamp).Max() : x.DateTimeEntry).ToList(); gridBugJobs.Title = listRemainingBugJobs.Count() + " Bugs (" + listStaleBugs.Count() + " Stale)"; gridEnhancementJobs.Title = listRemainingEnhancementJobs.Count() + " Enhancements (" + listStaleEnhancements.Count() + " Stale)"; FillGridOldBugs(listStaleBugs); FillGridOldEnhancements(listStaleEnhancements); #endregion }
private void FillGrid() { long clinicNum = 0; //if clinics are not enabled, comboClinic.SelectedIndex will be -1, so clinicNum will be 0 and list will not be filtered by clinic if (Security.CurUser.ClinicIsRestricted && comboClinics.SelectedIndex > -1) { clinicNum = _listClinics[comboClinics.SelectedIndex].ClinicNum; } else if (comboClinics.SelectedIndex > 0) //if user is not restricted, clinicNum will be 0 and the query will get all clinic data { clinicNum = _listClinics[comboClinics.SelectedIndex - 1].ClinicNum; //if user is not restricted, comboClinic will contain "All" so minus 1 } int clinicWidth = 80; int patientWidth = 180; int carrierWidth = 220; if (PrefC.HasClinicsEnabled) { patientWidth = 140; carrierWidth = 200; } gridMain.BeginUpdate(); gridMain.Columns.Clear(); ODGridColumn col = new ODGridColumn(Lan.g("TableAutoOrthoClaims", "Patient"), patientWidth); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableAutoOrthoClaims", "Carrier"), carrierWidth); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableAutoOrthoClaims", "TxMonths"), 70); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableAutoOrthoClaims", "Banding"), 80, HorizontalAlignment.Center); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableAutoOrthoClaims", "MonthsRem"), 100); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableAutoOrthoClaims", "#Sent"), 60); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableAutoOrthoClaims", "LastSent"), 80, HorizontalAlignment.Center); gridMain.Columns.Add(col); col = new ODGridColumn(Lan.g("TableAutoOrthoClaims", "NextClaim"), 80, HorizontalAlignment.Center); gridMain.Columns.Add(col); if (PrefC.HasClinicsEnabled) //clinics is turned on { col = new ODGridColumn(Lan.g("TableAutoOrthoClaims", "Clinic"), clinicWidth, HorizontalAlignment.Center); gridMain.Columns.Add(col); } gridMain.Rows.Clear(); ODGridRow row; foreach (DataRow rowCur in _tableOutstandingAutoClaims.Rows) { //need a check for if clinics is on here if (PrefC.HasClinicsEnabled && //Clinics are enabled (Security.CurUser.ClinicIsRestricted || comboClinics.SelectedIndex != 0) && //"All" is not selected clinicNum != PIn.Long(rowCur["ClinicNum"].ToString())) //currently selected clinic doesn't match the row's clinic { continue; } row = new ODGridRow(); DateTime dateLastSeen = PIn.Date(rowCur["LastSent"].ToString()); DateTime dateBanding = PIn.Date(rowCur["DateBanding"].ToString()); DateTime dateNextClaim = PIn.Date(rowCur["OrthoAutoNextClaimDate"].ToString()); DateTimeOD dateTMonthsRem = new DateTimeOD(PIn.Date(rowCur["DateBanding"].ToString()).AddMonths(PIn.Int(rowCur["MonthsTreat"].ToString())), DateTimeOD.Today); row.Cells.Add(PIn.String(rowCur["Patient"].ToString())); row.Cells.Add(PIn.String(rowCur["CarrierName"].ToString())); row.Cells.Add(PIn.String(rowCur["MonthsTreat"].ToString())); row.Cells.Add(dateBanding.Year < 1880 ? "" : dateBanding.ToShortDateString()); //add blank if there is no banding if (dateBanding.Year < 1880) //add blank if there is no banding { row.Cells.Add(""); } else { row.Cells.Add(((dateTMonthsRem.YearsDiff * 12) + dateTMonthsRem.MonthsDiff) + " " + Lan.g(this, "months") + ", " + dateTMonthsRem.DaysDiff + " " + Lan.g(this, "days")); } row.Cells.Add(PIn.String(rowCur["NumSent"].ToString())); row.Cells.Add(dateLastSeen.Year < 1880 ? "" : dateLastSeen.ToShortDateString()); row.Cells.Add(dateNextClaim.Year < 1880 ? "" : dateNextClaim.ToShortDateString()); if (PrefC.HasClinicsEnabled) //clinics is turned on //Use the long list of clinics so that hidden clinics can be shown for unrestricted users. { row.Cells.Add(Clinics.GetAbbr(PIn.Long(rowCur["ClinicNum"].ToString()))); } row.Tag = rowCur; gridMain.Rows.Add(row); } gridMain.EndUpdate(); }
private void butGenerateClaims_Click(object sender, EventArgs e) { if (gridMain.SelectedIndices.Count() < 1) { MsgBox.Show(this, "Please select the rows for which you would like to create procedures and claims."); return; } if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "Are you sure you want to generate claims and procedures for all patients and insurance plans?")) { return; } List <long> listPlanNums = new List <long>(); List <long> listPatPlanNums = new List <long>(); List <long> listInsSubNums = new List <long>(); for (int i = 0; i < gridMain.SelectedIndices.Count(); i++) { DataRow rowCur = (DataRow)gridMain.Rows[gridMain.SelectedIndices[i]].Tag; listPlanNums.Add(PIn.Long(rowCur["PlanNum"].ToString())); listPatPlanNums.Add(PIn.Long(rowCur["PatPlanNum"].ToString())); listInsSubNums.Add(PIn.Long(rowCur["InsSubNum"].ToString())); } List <InsPlan> listSelectedInsPlans = InsPlans.GetPlans(listPlanNums); List <PatPlan> listSelectedPatPlans = PatPlans.GetPatPlans(listPatPlanNums); List <InsSub> listSelectedInsSubs = InsSubs.GetMany(listInsSubNums); List <DataRow> rowsSucceeded = new List <DataRow>(); int rowsFailed = 0; List <Benefit> listBenefitsAll = Benefits.Refresh(listSelectedPatPlans, listSelectedInsSubs); for (int i = 0; i < gridMain.SelectedIndices.Count(); i++) { try { DataRow rowCur = (DataRow)gridMain.Rows[gridMain.SelectedIndices[i]].Tag; long patNumCur = PIn.Long(rowCur["PatNum"].ToString()); Patient patCur = Patients.GetPat(patNumCur); PatientNote patNoteCur = PatientNotes.Refresh(patNumCur, patCur.Guarantor); long codeNumCur = PIn.Long(rowCur["AutoCodeNum"].ToString()); long provNumCur = PIn.Long(rowCur["ProvNum"].ToString()); long clinicNumCur = PIn.Long(rowCur["ClinicNum"].ToString()); long insPlanNumCur = PIn.Long(rowCur["PlanNum"].ToString()); long patPlanNumCur = PIn.Long(rowCur["PatPlanNum"].ToString()); long insSubNumCur = PIn.Long(rowCur["InsSubNum"].ToString()); int monthsTreat = PIn.Int(rowCur["MonthsTreat"].ToString()); DateTime dateDue = PIn.Date(rowCur["OrthoAutoNextClaimDate"].ToString()); //for each selected row //create a procedure //Procedures.CreateProcForPat(patNumCur,codeNumCur,"","",ProcStat.C,provNumCur); Procedure proc = Procedures.CreateOrthoAutoProcsForPat(patNumCur, codeNumCur, provNumCur, clinicNumCur, dateDue); InsPlan insPlanCur = InsPlans.GetPlan(insPlanNumCur, listSelectedInsPlans); PatPlan patPlanCur = listSelectedPatPlans.FirstOrDefault(x => x.PatPlanNum == patPlanNumCur); InsSub insSubCur = listSelectedInsSubs.FirstOrDefault(x => x.InsSubNum == insSubNumCur); List <Benefit> benefitList = listBenefitsAll.FindAll(x => x.PatPlanNum == patPlanCur.PatPlanNum || x.PlanNum == insSubCur.PlanNum); //create a claimproc List <ClaimProc> listClaimProcs = new List <ClaimProc>(); Procedures.ComputeEstimates(proc, patNumCur, ref listClaimProcs, true, new List <InsPlan> { insPlanCur }, new List <PatPlan> { patPlanCur }, benefitList, null, null, true, patCur.Age, new List <InsSub> { insSubCur }, isForOrtho: true); //make the feebilled == the insplan feebilled or patplan feebilled double feebilled = patPlanCur.OrthoAutoFeeBilledOverride == -1 ? insPlanCur.OrthoAutoFeeBilled : patPlanCur.OrthoAutoFeeBilledOverride; //create a claim with that claimproc string claimType = ""; switch (patPlanCur.Ordinal) { case 1: claimType = "P"; break; case 2: claimType = "S"; break; } DateTimeOD dateTMonthsRem = new DateTimeOD(PIn.Date(rowCur["DateBanding"].ToString()).AddMonths(PIn.Int(rowCur["MonthsTreat"].ToString())), DateTimeOD.Today); Claims.CreateClaimForOrthoProc(claimType, patPlanCur, insPlanCur, insSubCur, ClaimProcs.GetForProcWithOrdinal(proc.ProcNum, patPlanCur.Ordinal), proc, feebilled, PIn.Date(rowCur["DateBanding"].ToString()), PIn.Int(rowCur["MonthsTreat"].ToString()), ((dateTMonthsRem.YearsDiff * 12) + dateTMonthsRem.MonthsDiff)); PatPlans.IncrementOrthoNextClaimDates(patPlanCur, insPlanCur, monthsTreat, patNoteCur); rowsSucceeded.Add(rowCur); SecurityLogs.MakeLogEntry(Permissions.ProcComplCreate, patCur.PatNum , Lan.g(this, "Automatic ortho procedure and claim generated for") + " " + dateDue.ToShortDateString()); } catch (Exception) { rowsFailed++; } } string message = Lan.g(this, "Done.") + " " + Lan.g(this, "There were") + " " + rowsSucceeded.Count + " " + Lan.g(this, "claim(s) generated and") + " " + rowsFailed + " " + Lan.g(this, "failures") + "."; MessageBox.Show(message); foreach (DataRow row in rowsSucceeded) { _tableOutstandingAutoClaims.Rows.Remove(row); } FillGrid(); }
///<summary>Same as FillOrtho() in the ContrAccount.</summary> private void FillOrtho() { gridOrtho.BeginUpdate(); gridOrtho.Columns.Clear(); gridOrtho.Columns.Add(new ODGridColumn("", (gridOrtho.Width / 2) - 20, HorizontalAlignment.Right)); gridOrtho.Columns.Add(new ODGridColumn("", (gridOrtho.Width / 2) + 20, HorizontalAlignment.Left)); gridOrtho.Rows.Clear(); ODGridRow row = new ODGridRow(); DateTime firstOrthoProc = Procedures.GetFirstOrthoProcDate(_patNoteCur); if (firstOrthoProc != DateTime.MinValue) { row.Cells.Add(Lan.g(this, "Total Tx Time") + ": "); //Number of Years/Months/Days since the first ortho procedure on this account DateTimeOD dateTOD = new DateTimeOD(firstOrthoProc, DateTimeOD.Today); string strDateDiff = ""; if (dateTOD.YearsDiff != 0) { strDateDiff += dateTOD.YearsDiff + " " + Lan.g(this, "year" + (dateTOD.YearsDiff == 1 ? "" : "s")); } if (dateTOD.MonthsDiff != 0) { if (strDateDiff != "") { strDateDiff += ", "; } strDateDiff += dateTOD.MonthsDiff + " " + Lan.g(this, "month" + (dateTOD.MonthsDiff == 1 ? "" : "s")); } if (dateTOD.DaysDiff != 0 || strDateDiff == "") { if (strDateDiff != "") { strDateDiff += ", "; } strDateDiff += dateTOD.DaysDiff + " " + Lan.g(this, "day" + (dateTOD.DaysDiff == 1 ? "" : "s")); } row.Cells.Add(strDateDiff); gridOrtho.Rows.Add(row); row = new ODGridRow(); row.Cells.Add(Lan.g(this, "Date Start") + ": "); //Date of the first ortho procedure on this account row.Cells.Add(firstOrthoProc.ToShortDateString()); gridOrtho.Rows.Add(row); row = new ODGridRow(); row.Cells.Add(Lan.g(this, "Tx Months Total") + ": "); //this patient's OrthoClaimMonthsTreatment, or the practice default if 0. int txMonthsTotal = (_patNoteCur.OrthoMonthsTreatOverride == -1?PrefC.GetByte(PrefName.OrthoDefaultMonthsTreat):_patNoteCur.OrthoMonthsTreatOverride); row.Cells.Add(txMonthsTotal.ToString()); gridOrtho.Rows.Add(row); row = new ODGridRow(); int txTimeInMonths = dateTOD.YearsDiff * 12 + dateTOD.MonthsDiff + (dateTOD.DaysDiff < 15? 0: 1); row.Cells.Add(Lan.g(this, "Months in Treatment") + ": "); //idk what the difference between this and 'Total Tx Time' is. row.Cells.Add(txTimeInMonths.ToString()); gridOrtho.Rows.Add(row); row = new ODGridRow(); row.Cells.Add(Lan.g(this, "Months Rem") + ": "); //Months Total - Total Tx Time row.Cells.Add(Math.Max(0, txMonthsTotal - txTimeInMonths).ToString()); gridOrtho.Rows.Add(row); } else { row = new ODGridRow(); row.Cells.Add(""); //idk what the difference between this and 'Total Tx Time' is. row.Cells.Add(Lan.g(this, "No ortho procedures charted") + "."); gridOrtho.Rows.Add(row); } gridOrtho.EndUpdate(); }
///<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>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; } } } } } } }