public FormJobManagerDashboard(List <Job> listJobsAll, JobSprint sprint) { _listJobsAll = listJobsAll; _jobSprintCur = sprint; InitializeComponent(); Lan.F(this); }
private void timerRefreshAll_Tick(object sender, EventArgs e) { timerRefreshAll.Stop(); _jobSprintCur = JobSprints.GetOne(_jobSprintCur.JobSprintNum); //Get the latest version from the database RefreshAll(); timerRefreshAll.Start(); }
public bool UnloadSprint(out JobSprint jobSprint) { jobSprint = _jobSprintCur; if (_hasUnsavedChanges) { switch (MessageBox.Show("The current sprint has unsaved changes. Would you like to save them?", "", MessageBoxButtons.YesNoCancel)) { case DialogResult.Yes: if (!SaveJobSprint()) { //Reset jobSprint to get the new changes jobSprint = _jobSprintCur; Enabled = false; return(true); } break; case DialogResult.No: Enabled = false; _hasUnsavedChanges = false; return(true); case DialogResult.Cancel: return(false); default: return(false); } } return(true); }
private void butOK_Click(object sender, EventArgs e) { if (gridMain.GetSelectedIndex() < 0) { MsgBox.Show(this, "A sprint must be selected before opening the dashboard."); return; } SelectedJobSprint = gridMain.SelectedTag <JobSprint>(); DialogResult = DialogResult.OK; }
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>Updates one JobSprint in the database.</summary> public static void Update(JobSprint jobSprint) { string command = "UPDATE jobsprint SET " + "Title = '" + POut.String(jobSprint.Title) + "', " + "Note = '" + POut.String(jobSprint.Note) + "', " + "DateStart = " + POut.Date(jobSprint.DateStart) + ", " + "DateEndTarget = " + POut.Date(jobSprint.DateEndTarget) + ", " + "DateEndActual = " + POut.Date(jobSprint.DateEndActual) + ", " + "JobPercent = '" + POut.Double(jobSprint.JobPercent) + "', " + "HoursAverageDevelopment= '" + POut.Double(jobSprint.HoursAverageDevelopment) + "', " + "HoursAverageBreak = '" + POut.Double(jobSprint.HoursAverageBreak) + "' " + "WHERE JobSprintNum = " + POut.Long(jobSprint.JobSprintNum); Db.NonQ(command); }
private void gridSprints_TitleAddClick(object sender, EventArgs e) { JobSprint jobSprintNew = new JobSprint(); jobSprintNew.Title = "Version"; jobSprintNew.Note = ""; jobSprintNew.DateStart = DateTime.Today; jobSprintNew.DateEndTarget = DateTime.Today.AddDays(70);//Add 10 weeks jobSprintNew.DateEndActual = DateTime.MinValue; jobSprintNew.JobPercent = 0.173; jobSprintNew.HoursAverageDevelopment = 9.43; jobSprintNew.HoursAverageBreak = 0.85; JobSprints.Insert(jobSprintNew); FillGridSprints(); userControlSprintManager.LoadSprint(jobSprintNew, _listJobsAll); FillGridEngineers(userControlSprintManager.JobSprintCur); }
///<summary>Converts a DataTable to a list of objects.</summary> public static List <JobSprint> TableToList(DataTable table) { List <JobSprint> retVal = new List <JobSprint>(); JobSprint jobSprint; foreach (DataRow row in table.Rows) { jobSprint = new JobSprint(); jobSprint.JobSprintNum = PIn.Long(row["JobSprintNum"].ToString()); jobSprint.Title = PIn.String(row["Title"].ToString()); jobSprint.Note = PIn.String(row["Note"].ToString()); jobSprint.DateStart = PIn.Date(row["DateStart"].ToString()); jobSprint.DateEndTarget = PIn.Date(row["DateEndTarget"].ToString()); jobSprint.DateEndActual = PIn.Date(row["DateEndActual"].ToString()); jobSprint.JobPercent = PIn.Double(row["JobPercent"].ToString()); jobSprint.HoursAverageDevelopment = PIn.Double(row["HoursAverageDevelopment"].ToString()); jobSprint.HoursAverageBreak = PIn.Double(row["HoursAverageBreak"].ToString()); retVal.Add(jobSprint); } return(retVal); }
///<summary>Inserts one JobSprint into the database. Provides option to use the existing priKey. Doesn't use the cache.</summary> public static long InsertNoCache(JobSprint jobSprint, bool useExistingPK) { bool isRandomKeys = Prefs.GetBoolNoCache(PrefName.RandomPrimaryKeys); string command = "INSERT INTO jobsprint ("; if (!useExistingPK && isRandomKeys) { jobSprint.JobSprintNum = ReplicationServers.GetKeyNoCache("jobsprint", "JobSprintNum"); } if (isRandomKeys || useExistingPK) { command += "JobSprintNum,"; } command += "Title,Note,DateStart,DateEndTarget,DateEndActual,JobPercent,HoursAverageDevelopment,HoursAverageBreak) VALUES("; if (isRandomKeys || useExistingPK) { command += POut.Long(jobSprint.JobSprintNum) + ","; } command += "'" + POut.String(jobSprint.Title) + "'," + "'" + POut.String(jobSprint.Note) + "'," + POut.Date(jobSprint.DateStart) + "," + POut.Date(jobSprint.DateEndTarget) + "," + POut.Date(jobSprint.DateEndActual) + "," + "'" + POut.Double(jobSprint.JobPercent) + "'," + "'" + POut.Double(jobSprint.HoursAverageDevelopment) + "'," + "'" + POut.Double(jobSprint.HoursAverageBreak) + "')"; if (useExistingPK || isRandomKeys) { Db.NonQ(command); } else { jobSprint.JobSprintNum = Db.NonQ(command, true, "JobSprintNum", "jobSprint"); } return(jobSprint.JobSprintNum); }
///<summary>Returns true if Update(JobSprint,JobSprint) would make changes to the database. ///Does not make any changes to the database and can be called before remoting role is checked.</summary> public static bool UpdateComparison(JobSprint jobSprint, JobSprint oldJobSprint) { if (jobSprint.Title != oldJobSprint.Title) { return(true); } if (jobSprint.Note != oldJobSprint.Note) { return(true); } if (jobSprint.DateStart.Date != oldJobSprint.DateStart.Date) { return(true); } if (jobSprint.DateEndTarget.Date != oldJobSprint.DateEndTarget.Date) { return(true); } if (jobSprint.DateEndActual.Date != oldJobSprint.DateEndActual.Date) { return(true); } if (jobSprint.JobPercent != oldJobSprint.JobPercent) { return(true); } if (jobSprint.HoursAverageDevelopment != oldJobSprint.HoursAverageDevelopment) { return(true); } if (jobSprint.HoursAverageBreak != oldJobSprint.HoursAverageBreak) { return(true); } return(false); }
///<summary>Updates one JobSprint in the database. Uses an old object to compare to, and only alters changed fields. This prevents collisions and concurrency problems in heavily used tables. Returns true if an update occurred.</summary> public static bool Update(JobSprint jobSprint, JobSprint oldJobSprint) { string command = ""; if (jobSprint.Title != oldJobSprint.Title) { if (command != "") { command += ","; } command += "Title = '" + POut.String(jobSprint.Title) + "'"; } if (jobSprint.Note != oldJobSprint.Note) { if (command != "") { command += ","; } command += "Note = '" + POut.String(jobSprint.Note) + "'"; } if (jobSprint.DateStart.Date != oldJobSprint.DateStart.Date) { if (command != "") { command += ","; } command += "DateStart = " + POut.Date(jobSprint.DateStart) + ""; } if (jobSprint.DateEndTarget.Date != oldJobSprint.DateEndTarget.Date) { if (command != "") { command += ","; } command += "DateEndTarget = " + POut.Date(jobSprint.DateEndTarget) + ""; } if (jobSprint.DateEndActual.Date != oldJobSprint.DateEndActual.Date) { if (command != "") { command += ","; } command += "DateEndActual = " + POut.Date(jobSprint.DateEndActual) + ""; } if (jobSprint.JobPercent != oldJobSprint.JobPercent) { if (command != "") { command += ","; } command += "JobPercent = '" + POut.Double(jobSprint.JobPercent) + "'"; } if (jobSprint.HoursAverageDevelopment != oldJobSprint.HoursAverageDevelopment) { if (command != "") { command += ","; } command += "HoursAverageDevelopment = '" + POut.Double(jobSprint.HoursAverageDevelopment) + "'"; } if (jobSprint.HoursAverageBreak != oldJobSprint.HoursAverageBreak) { if (command != "") { command += ","; } command += "HoursAverageBreak = '" + POut.Double(jobSprint.HoursAverageBreak) + "'"; } if (command == "") { return(false); } command = "UPDATE jobsprint SET " + command + " WHERE JobSprintNum = " + POut.Long(jobSprint.JobSprintNum); Db.NonQ(command); return(true); }
///<summary>Inserts one JobSprint into the database. Returns the new priKey. Doesn't use the cache.</summary> public static long InsertNoCache(JobSprint jobSprint) { return(InsertNoCache(jobSprint, false)); }
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)); }
private void FillGridEngineers(JobSprint jobSprint) { gridEngineers.BeginUpdate(); gridEngineers.ListGridColumns.Clear(); gridEngineers.ListGridColumns.Add(new GridColumn("Engineer", 0)); gridEngineers.ListGridColumns.Add(new GridColumn("Scheduled Hrs", 150) { TextAlign = HorizontalAlignment.Center, SortingStrategy = GridSortingStrategy.AmountParse }); gridEngineers.ListGridColumns.Add(new GridColumn("- Est. Breaks", 150) { TextAlign = HorizontalAlignment.Center, SortingStrategy = GridSortingStrategy.AmountParse }); gridEngineers.ListGridColumns.Add(new GridColumn("= Hrs Total", 150) { TextAlign = HorizontalAlignment.Center, SortingStrategy = GridSortingStrategy.AmountParse }); gridEngineers.ListGridColumns.Add(new GridColumn("Assigned Dev Hrs", 150) { TextAlign = HorizontalAlignment.Center, SortingStrategy = GridSortingStrategy.AmountParse }); gridEngineers.ListGridColumns.Add(new GridColumn("Free Dev Hrs", 150) { TextAlign = HorizontalAlignment.Center, SortingStrategy = GridSortingStrategy.AmountParse }); gridEngineers.ListGridColumns.Add(new GridColumn("Completed Hrs", 150) { TextAlign = HorizontalAlignment.Center, SortingStrategy = GridSortingStrategy.AmountParse }); gridEngineers.ListGridRows.Clear(); double jobPercent = jobSprint.JobPercent; double avgDevHours = jobSprint.HoursAverageDevelopment; double avgBreakHours = jobSprint.HoursAverageBreak; List <Schedule> listEngSchedules = Schedules.RefreshPeriodForEmps(jobSprint.DateStart, jobSprint.DateEndTarget, JobHelper.ListEngineerEmployeeNums); foreach (Userod userEng in JobHelper.ListEngineerUsers) { double schedHoursTotal = 0; double schedHoursBreaksTotal = 0; double schedHoursPercentTotal = 0; double allocatableHours = 0; foreach (Schedule sched in listEngSchedules.FindAll(x => x.EmployeeNum == userEng.EmployeeNum)) { //Calculate actual scheduled time double schedHours = (sched.StopTime - sched.StartTime).TotalHours; schedHoursTotal += schedHours; //Remove average break time schedHours -= avgBreakHours; schedHoursBreaksTotal += schedHours; //Multiply the scheduled time by the percentage of coding time for the jobs we care about schedHours = schedHours * jobPercent; schedHoursPercentTotal += schedHours; //Add the sched hours to the allocatable hours allocatableHours += schedHours; } double totalAllocatedHours = 0; double totalCompletedHours = 0; //TODO: OwnerNum is not a good enough check here. //Make a method to get a sublist of jobs that legit apply to an engineer (In their writeup/development, not waiting for approval) List <Job> listEngJobs = _listJobsAll.FindAll(x => !x.IsApprovalNeeded && ((x.PhaseCur == JobPhase.Development && x.UserNumEngineer == userEng.UserNum) || (x.PhaseCur == JobPhase.Definition && x.UserNumExpert == userEng.UserNum))); foreach (Job job in listEngJobs) { double estimate = job.HoursEstimate; if (job.HoursEstimateDevelopment == 0) { estimate += avgDevHours; } totalAllocatedHours += estimate; totalAllocatedHours -= job.HoursActual; totalCompletedHours += job.HoursActual; } GridRow row = new GridRow() { Tag = userEng }; row.Cells.Add(userEng.UserName); row.Cells.Add(Math.Round(schedHoursTotal).ToString()); row.Cells.Add(Math.Round(schedHoursTotal - schedHoursBreaksTotal).ToString()); row.Cells.Add(Math.Round(schedHoursBreaksTotal).ToString()); row.Cells.Add(Math.Round(totalAllocatedHours).ToString()); double freeHrs = Math.Round(schedHoursBreaksTotal - totalAllocatedHours); GridCell cell = new GridCell(freeHrs.ToString()); cell.ColorBackG = freeHrs < 20?Color.LightSalmon:Color.LightGreen; //Arbitrary 20 hours. row.Cells.Add(cell); row.Cells.Add(Math.Round(totalCompletedHours).ToString()); gridEngineers.ListGridRows.Add(row); } gridEngineers.EndUpdate(); }
private void gridMain_CellDoubleClick(object sender, ODGridClickEventArgs e) { SelectedJobSprint = gridMain.SelectedTag <JobSprint>(); DialogResult = DialogResult.OK; }