public void LoadSprint(JobSprint jobSprint, List <Job> listJobsAll) { if (_hasUnsavedChanges) { switch (MessageBox.Show("The current sprint has unsaved changes. Would you like to save them?", "", MessageBoxButtons.YesNoCancel)) { case DialogResult.Yes: if (!SaveJobSprint()) { return; } break; case DialogResult.No: _hasUnsavedChanges = false; break; case DialogResult.Cancel: return; default: return; } } //If this fails then the JM should also be failing _listJobPriorities = Defs.GetDefsForCategory(DefCat.JobPriorities); _jobSprintCur = jobSprint; _listJobSprintLinks = JobSprintLinks.GetForSprint(_jobSprintCur.JobSprintNum); _listJobsAll = listJobsAll; textTitle.Text = jobSprint.Title; textNote.Text = jobSprint.Note; textDateStart.Text = jobSprint.DateStart.ToShortDateString(); textDateEnd.Text = jobSprint.DateEndTarget.ToShortDateString(); textDateEndActual.Text = jobSprint.DateEndActual.ToShortDateString(); if (jobSprint.DateEndActual == DateTime.MinValue) { labelDateEndActual.Visible = false; textDateEndActual.Visible = false; } else { labelDateEndActual.Visible = true; textDateEndActual.Visible = true; } textEngJobPercent.Text = jobSprint.JobPercent.ToString(); textAvgDevelopmentHours.Text = jobSprint.HoursAverageDevelopment.ToString(); textBreakHours.Text = jobSprint.HoursAverageBreak.ToString(); //Reset _hasUnsavedChanges since setting the text cause it to set itself to true. _hasUnsavedChanges = false; FillGridJobs(); Enabled = true; }
///<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 }
private void gridSprints_MouseClick(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Right) { return; } ContextMenu menu = new ContextMenu(); menu.MenuItems.Add("Remove Sprint", (o, arg) => { int selectedIndex = gridSprints.GetSelectedIndex(); if (selectedIndex == -1) { return; //Nothing to remove. } if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "This will permanently delete this sprint. Continue?")) { return; } long sprintNum = ((JobSprint)gridSprints.ListGridRows[selectedIndex].Tag).JobSprintNum; userControlSprintManager.Enabled = false; JobSprints.Delete(sprintNum); FillGridSprints(); }); menu.MenuItems.Add("Copy Sprint", (o, arg) => { int selectedIndex = gridSprints.GetSelectedIndex(); if (selectedIndex == -1) { return; //Nothing to copy. } JobSprint sprint = ((JobSprint)gridSprints.ListGridRows[selectedIndex].Tag); sprint.Title += "_Copy"; List <JobSprintLink> listSprintLinks = JobSprintLinks.GetForSprint(sprint.JobSprintNum); JobSprints.Insert(sprint); foreach (JobSprintLink sprintLink in listSprintLinks) { sprintLink.JobSprintNum = sprint.JobSprintNum; JobSprintLinks.Insert(sprintLink); } FillGridSprints(); userControlSprintManager.LoadSprint(sprint, _listJobsAll); }); menu.MenuItems.Add("End Sprint", (o, arg) => { int selectedIndex = gridSprints.GetSelectedIndex(); if (selectedIndex == -1) { return; //Nothing to end. } if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "This will set the sprints actual end date to today. Continue?")) { return; } JobSprint sprint; //This gets the most recent sprint instance to save and unloads it so we can load it in if (!userControlSprintManager.Enabled || !userControlSprintManager.UnloadSprint(out sprint)) { return; } else { sprint = ((JobSprint)gridSprints.ListGridRows[selectedIndex].Tag); } sprint.DateEndActual = DateTime.Today; JobSprints.Update(sprint); FillGridSprints(); userControlSprintManager.LoadSprint(sprint, _listJobsAll); FillGridEngineers(userControlSprintManager.JobSprintCur); }); menu.Show(gridSprints, gridSprints.PointToClient(Cursor.Position)); }