private void FormBugSubmission_Load(object sender, EventArgs e) { try { RegistrationKey key = RegistrationKeys.GetByKey(_subCur.RegKey); _patCur = Patients.GetPat(key.PatNum); } catch (Exception ex) { ex.DoNothing(); _patCur = new Patient(); //Just in case, needed mostly for debug. } labelName.Text = _patCur?.GetNameLF() ?? ""; labelDateTime.Text = POut.DateT(_subCur.SubmissionDateTime); labelVersion.Text = _subCur.TryGetPrefValue(PrefName.ProgramVersion, "0.0.0.0"); labelHashNum.Text = POut.Long(_subCur.BugSubmissionHashNum); if (_subCur.BugId != 0) //Already associated to a bug { _bug = Bugs.GetOne(_subCur.BugId); butAddViewBug.Text = "View Bug"; } if (_bug != null) { _listLinks = JobLinks.GetForType(JobLinkType.Bug, _bug.BugId); if (_listLinks.Count == 1) { butAddViewJob.Text = "View Job"; } } Dictionary <string, Patient> dictPats = new Dictionary <string, Patient>(); dictPats.Add(_subCur.RegKey, _patCur); bugSubmissionControl.RefreshData(dictPats, -1, null); //New selelction, refresh control data. bugSubmissionControl.RefreshView(_subCur); }
private void TryViewTask(ODGrid grid) { int index = grid.GetSelectedIndex(); if (index == -1) { return; } Bug selectedBug = (Bug)grid.ListGridRows[index].Tag; List <long> listTaskNums = JobLinks.GetTaskNumsForBug(selectedBug.BugId); switch (listTaskNums.Count) { case 0: MsgBox.Show(this, "There are not task assocaited to a job for this bug."); return; case 1: FormTaskEdit formTaskEdit = new FormTaskEdit(Tasks.GetOne(listTaskNums[0])); formTaskEdit.Show(); break; default: FormTaskSearch formTaskSearch = new FormTaskSearch(listTaskNums); formTaskSearch.ShowDialog(); break; } }
private void butOK_Click(object sender, EventArgs e) { if (!ValidateTitle()) { return; } if (!ValidateJob()) { return; } _jobNew.JobVersion = textVersion.Text; _jobNew.Requirements = textConcept.MainRtf; long jobNum = Jobs.Insert(_jobNew); foreach (JobLink link in _listJobLinks) { link.JobNum = jobNum; JobLinks.Insert(link); } foreach (JobQuote quote in _listJobQuotes) { quote.JobNum = jobNum; JobQuotes.Insert(quote); } DialogResult = DialogResult.OK; }
private void ODEvent_Fired(ODEventArgs e) { //Make sure that this ODEvent is for the Job Manager and that the Tag is not null and is a string. if (e.Name != "Job Manager" || e.Tag == null || e.Tag.GetType() != typeof(string)) { return; } _jobLinks = JobLinks.GetJobLinks(_jobNum); FillGrid(); }
private void gridSubs_CellClick(object sender, UI.ODGridClickEventArgs e) { butAddJob.Text = "Add Job"; //Always reset if (e.Row == -1 || gridSubs.SelectedIndices.Length != 1) { bugSubmissionControl.ClearCustomerInfo(); _subCur = null; bugSubmissionControl.SetTextDevNoteEnabled(false); return; } bugSubmissionControl.SetTextDevNoteEnabled(true); _subCur = ((List <BugSubmission>)gridSubs.Rows[e.Row].Tag)[0]; if (_dictPatients.ContainsKey(_subCur.RegKey)) { _patCur = _dictPatients[_subCur.RegKey]; } else { try { RegistrationKey key = RegistrationKeys.GetByKey(_subCur.RegKey); _patCur = Patients.GetPat(key.PatNum); } catch (Exception ex) { ex.DoNothing(); _patCur = new Patient(); //Just in case, needed mostly for debug. } _dictPatients.Add(_subCur.RegKey, _patCur); } List <BugSubmission> listSubs = _listAllSubs; if (comboGrouping.SelectedIndex.In(1, 2, 3)) { listSubs = ((List <BugSubmission>)gridSubs.Rows[gridSubs.GetSelectedIndex()].Tag); } butAddJob.Tag = null; bugSubmissionControl.RefreshData(_dictPatients, comboGrouping.SelectedIndex, listSubs); //New selelction, refresh control data. bugSubmissionControl.RefreshView(_subCur); if (_subCur.BugId != 0) { List <JobLink> _listLinks = JobLinks.GetForType(JobLinkType.Bug, _subCur.BugId); if (_listLinks.Count == 1) { butAddJob.Text = "View Job"; butAddJob.Tag = _listLinks.First(); } } if (_viewMode.In(FormBugSubmissionMode.SelectionMode, FormBugSubmissionMode.ValidationMode)) { butAddJob.Text = "OK"; } }
private void butRemove_Click(object sender, EventArgs e) { if (gridMain.GetSelectedIndex() == -1) { MsgBox.Show(this, "Select a link to remove first."); return; } if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "Are you sure you want to remove this link?")) { return; } JobLinks.Delete((long)gridMain.ListGridRows[gridMain.GetSelectedIndex()].Tag); _hasChanged = true; _jobLinks.RemoveAt(gridMain.GetSelectedIndex()); FillGrid(); }
private void butLinkTask_Click(object sender, EventArgs e) { FormTaskSearch FormTS = new FormTaskSearch(); FormTS.IsSelectionMode = true; if (FormTS.ShowDialog() == DialogResult.OK) { JobLink jobLink = new JobLink(); jobLink.JobNum = _jobNum; jobLink.FKey = FormTS.SelectedTaskNum; jobLink.LinkType = JobLinkType.Task; JobLinks.Insert(jobLink); _jobLinks = JobLinks.GetJobLinks(_jobNum); _hasChanged = true; FillGrid(); } }
private void butLinkFeatReq_Click(object sender, EventArgs e) { FormFeatureRequest FormFR = new FormFeatureRequest(); FormFR.IsSelectionMode = true; FormFR.ShowDialog(); if (FormFR.DialogResult == DialogResult.OK) { JobLink jobLink = new JobLink(); jobLink.JobNum = _jobNum; jobLink.FKey = FormFR.SelectedFeatureNum; jobLink.LinkType = JobLinkType.Request; JobLinks.Insert(jobLink); _jobLinks = JobLinks.GetJobLinks(_jobNum); _hasChanged = true; FillGrid(); } }
private void FormBugSubmission_Load(object sender, EventArgs e) { textStack.Text = _sub.ExceptionMessageText + "\r\n" + _sub.ExceptionStackTrace; labelRegKey.Text = _sub.RegKey; labelDateTime.Text = POut.DateT(_sub.SubmissionDateTime); labelVersion.Text = _sub.Info.DictPrefValues[PrefName.ProgramVersion]; if (_sub.BugId != 0) //Already associated to a bug { _bug = Bugs.GetOne(_sub.BugId); butAddViewBug.Text = "View Bug"; } if (_bug != null) { _listLinks = JobLinks.GetForType(JobLinkType.Bug, _bug.BugId); if (_listLinks.Count == 1) { butAddViewJob.Text = "View Job"; } } FillOfficeInfoGrid(_sub); SetCustomerInfo(_sub); }
private void FillSubGrid(bool isRefreshNeeded = false, string grouping95 = "") { List <string> listSelectedVersions = listVersionsFilter.SelectedItems.OfType <string>().ToList(); if (listSelectedVersions.Contains("All")) { listSelectedVersions.Clear(); } if (isRefreshNeeded && listSelectedVersions.IsNullOrEmpty()) { if (!MsgBox.Show(MsgBoxButtons.YesNo, "All bug submissions are going to be downloaded...\r\nAre you sure about this?")) { return; } } Action loadingProgress = null; Cursor = Cursors.WaitCursor; #region gridSubs columns gridSubs.BeginUpdate(); gridSubs.ListGridColumns.Clear(); gridSubs.ListGridColumns.Add(new GridColumn("Submitter", 140)); gridSubs.ListGridColumns.Add(new GridColumn("Vers.", 55, GridSortingStrategy.VersionNumber)); if (comboGrouping.SelectedIndex == 0) //Group by 'None' { gridSubs.ListGridColumns.Add(new GridColumn("DateTime", 75, GridSortingStrategy.DateParse)); } else { gridSubs.ListGridColumns.Add(new GridColumn("#", 30, HorizontalAlignment.Right, GridSortingStrategy.AmountParse)); } gridSubs.ListGridColumns.Add(new GridColumn("Flag", 50, HorizontalAlignment.Center)); gridSubs.ListGridColumns.Add(new GridColumn("Msg Text", 0)); gridSubs.AllowSortingByColumn = true; gridSubs.ListGridRows.Clear(); #endregion bugSubmissionControl.ClearCustomerInfo(); bugSubmissionControl.SetTextDevNoteEnabled(false); if (isRefreshNeeded) { loadingProgress = ODProgress.Show(ODEventType.BugSubmission, typeof(BugSubmissionEvent), Lan.g(this, "Refreshing Data") + "..."); #region Refresh Logic if (_viewMode.In(FormBugSubmissionMode.ViewOnly, FormBugSubmissionMode.ValidationMode)) { _listAllSubs = ListViewedSubs; } else { BugSubmissionEvent.Fire(ODEventType.BugSubmission, Lan.g(this, "Refreshing Data: Bugs")); _listAllSubs = BugSubmissions.GetAllInRange(dateRangePicker.GetDateTimeFrom(), dateRangePicker.GetDateTimeTo(), listSelectedVersions); } try { BugSubmissionEvent.Fire(ODEventType.BugSubmission, Lan.g(this, "Refreshing Data: Patients")); _dictPatients = RegistrationKeys.GetPatientsByKeys(_listAllSubs.Select(x => x.RegKey).ToList()); } catch (Exception e) { e.DoNothing(); _dictPatients = new Dictionary <string, Patient>(); } BugSubmissionEvent.Fire(ODEventType.BugSubmission, Lan.g(this, "Refreshing Data: JobLinks")); _listJobLinks = JobLinks.GetManyForType(JobLinkType.Bug, _listAllSubs.Select(x => x.BugId).Where(x => x != 0).Distinct().ToList()); #endregion } #region Filter Logic BugSubmissionEvent.Fire(ODEventType.BugSubmission, "Filtering Data"); List <BugSubmission> listFilteredSubs = null; List <string> listSelectedRegKeys = comboRegKeys.ListSelectedItems.Select(x => (string)x).ToList(); if (listSelectedRegKeys.Contains("All")) { listSelectedRegKeys.Clear(); } List <string> listStackFilters = textStackFilter.Text.Split(',') .Where(x => !string.IsNullOrWhiteSpace(x)) .Select(x => x.ToLower()).ToList(); List <string> listPatNumFilters = textPatNums.Text.Split(',') .Where(x => !string.IsNullOrWhiteSpace(x)) .Select(x => x.ToLower()).ToList(); _listAllSubs.ForEach(x => x.TagCustom = null); List <string> listCategoryFilters = textCategoryFilters.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); string msgText = textMsgText.Text; string devNoteFilter = textDevNoteFilter.Text; DateTime dateTimeFrom = dateRangePicker.GetDateTimeFrom(); DateTime dateTimeTo = dateRangePicker.GetDateTimeTo(); //Filter the list of all bug submissions and then order it by program version and submission date time so that the grouping is predictable. listFilteredSubs = _listAllSubs.Where(x => PassesFilterValidation(x, listCategoryFilters, listSelectedRegKeys, listStackFilters, listPatNumFilters, listSelectedVersions, grouping95, msgText, devNoteFilter, dateTimeFrom, dateTimeTo) ) .OrderByDescending(x => new Version(x.ProgramVersion)) .ThenByDescending(x => x.SubmissionDateTime) .ToList(); if (isRefreshNeeded) { FillPatNameFilter(_listAllSubs); } #endregion #region Grouping Logic List <BugSubmission> listGridSubmissions = new List <BugSubmission>(); BugSubmissionEvent.Fire(ODEventType.BugSubmission, "Grouping Data"); switch (comboGrouping.SelectedIndex) { case 0: #region None foreach (BugSubmission bugSubmission in listFilteredSubs) { AddGroupedSubsToGridSubs(listGridSubmissions, new List <BugSubmission>() { bugSubmission }); } listShowHideOptions.SetSelected(3, false); //Deselect 'None' _minGroupingCount = -1; butAddJob.Enabled = true; #endregion break; case 1: #region RegKey/Ver/Stack listFilteredSubs.GroupBy(x => new { x.BugId, x.RegKey, x.ProgramVersion, x.ExceptionMessageText, x.ExceptionStackTrace }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = true; #endregion break; case 2: #region StackTrace listFilteredSubs.GroupBy(x => new { x.BugId, x.ExceptionMessageText, x.ExceptionStackTrace }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = true; #endregion break; case 3: #region 95% //At this point all bugSubmissions in listFilteredSubs is at least a 95% match. Group them all together in a single row. AddGroupedSubsToGridSubs(listGridSubmissions, listFilteredSubs); butAddJob.Enabled = true; #endregion break; case 4: #region StackSig listFilteredSubs.GroupBy(x => new { x.BugId, x.ExceptionMessageText, x.OdStackSignature }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = false; //Can not add jobs in this mode. #endregion break; case 5: #region StackSimple listFilteredSubs.GroupBy(x => new { x.BugId, x.ExceptionMessageText, x.SimplifiedStackTrace }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = false; //Can not add jobs in this mode. #endregion break; case 6: #region Hash listFilteredSubs.GroupBy(x => new { x.BugId, x.BugSubmissionHashNum }) .ToDictionary(x => x.Key, x => x.ToList()) .ForEach(x => AddGroupedSubsToGridSubs(listGridSubmissions, x.Value)); butAddJob.Enabled = false; //Can not add jobs in this mode. #endregion break; } if (_minGroupingCount > 0) { listGridSubmissions.RemoveAll(x => (x.TagCustom as List <BugSubmission>).Count < _minGroupingCount); } #endregion #region Sorting Logic BugSubmissionEvent.Fire(ODEventType.BugSubmission, "Sorting Data"); switch (comboSortBy.SelectedIndex) { case 0: listGridSubmissions = listGridSubmissions.OrderByDescending(x => new Version(x.ProgramVersion)) .ThenByDescending(x => GetGroupCount(x)) .ThenByDescending(x => x.SubmissionDateTime).ToList(); break; } #endregion #region Fill gridSubs BugSubmissionEvent.Fire(ODEventType.BugSubmission, "Filling Grid"); foreach (BugSubmission sub in listGridSubmissions) { gridSubs.ListGridRows.Add(GetODGridRowForSub(sub)); } gridSubs.EndUpdate(); #endregion loadingProgress?.Invoke(); Cursor = Cursors.Default; }
private void FormJobLinks_Load(object sender, EventArgs e) { _jobLinks = JobLinks.GetJobLinks(_jobNum); FillGrid(); }
private void FillGrids(bool isRefreshNeeded = true) { if (_patCur == null || gridBugsFixed == null) //Just in case. { return; } gridBugsInProgress.BeginUpdate(); gridBugsFixed.BeginUpdate(); gridBugSubmissions.BeginUpdate(); #region Init Columns if (gridBugsFixed.ListGridColumns.Count == 0) { gridBugsInProgress.ListGridColumns.Add(new GridColumn("Description", -1)); gridBugsInProgress.ListGridColumns.Add(new GridColumn("Expert", 55, HorizontalAlignment.Center)); gridBugsInProgress.ListGridColumns.Add(new GridColumn("Has Job", 55, HorizontalAlignment.Center)); gridBugsFixed.ListGridColumns.Add(new GridColumn("Description", -1)); gridBugsFixed.ListGridColumns.Add(new GridColumn("Vers.", 55, HorizontalAlignment.Center)); gridBugsFixed.ListGridColumns.Add(new GridColumn("Has Job", 55, HorizontalAlignment.Center)); gridBugSubmissions.ListGridColumns.Add(new GridColumn("Description", -1)); gridBugSubmissions.ListGridColumns.Add(new GridColumn("Vers.", 55, HorizontalAlignment.Center)); gridBugSubmissions.ListGridColumns.Add(new GridColumn("Has Job", 55, HorizontalAlignment.Center)); } #endregion if (isRefreshNeeded) { List <string> listKeys = RegistrationKeys.GetForPatient(_patCur.PatNum).Select(x => x.RegKey).ToList(); try { _listBugSubs = BugSubmissions.GetBugSubsForRegKeys(listKeys, datePickerHqBugSub.GetDateTimeFrom(), datePickerHqBugSub.GetDateTimeTo()); } catch (Exception ex) { //Should only occur if running in debug at HQ and no bugs database on local machine. ex.DoNothing(); label1.Text = "NO BUGS DB"; //Inform dev of issue. } _listJobLinks = JobLinks.GetManyForType(JobLinkType.Bug, _listBugSubs.Select(x => x.BugId).ToList()); List <long> listNewBugUserIds = _listBugSubs.Where(x => x.BugObj != null && !_dictHqBugSubNames.ContainsKey(x.BugObj.Submitter)) .Select(x => x.BugObj.Submitter).ToList(); if (listNewBugUserIds.Count > 0) { Bugs.GetDictSubmitterNames(listNewBugUserIds).ToList() .ForEach(x => _dictHqBugSubNames[x.Key] = x.Value); } } gridBugsInProgress.ListGridRows.Clear(); gridBugsFixed.ListGridRows.Clear(); gridBugSubmissions.ListGridRows.Clear(); List <long> listBugNums = new List <long>(); //Keep track of BubIds so that we do not show duplicates. foreach (BugSubmission sub in _listBugSubs) { bool hasJob = (_listJobLinks.Any(x => x.FKey == sub.BugObj?.BugId)); string expertName = (sub.BugObj == null ? "" : _dictHqBugSubNames[sub.BugObj.Submitter].ToUpperFirstOnly()); if (sub.BugObj != null && !listBugNums.Contains(sub.BugObj.BugId)) //BugSubmission has an associated bug and it is not a duplicate. { if (string.IsNullOrEmpty(sub.BugObj.VersionsFixed)) //Bug is not fixed { #region In Progress grid listBugNums.Add(sub.BugObj.BugId); GridRow rowBug = new GridRow(sub.BugObj.Description, expertName, (hasJob?"X":"") ); rowBug.Tag = sub.BugObj; gridBugsInProgress.ListGridRows.Add(rowBug); #endregion } else //Bug is fixed { #region Fixed grid listBugNums.Add(sub.BugObj.BugId); GridRow rowBug = new GridRow(sub.BugObj.Description + "\r\nEXPERT: " + expertName, sub.BugObj.VersionsFixed.Replace(';', '\n'), (hasJob?"X":"") ); rowBug.Tag = sub.BugObj; gridBugsFixed.ListGridRows.Add(rowBug); #endregion } } #region All grid GridRow rowSub = new GridRow(sub.ExceptionMessageText + "\r\n" + sub.SubmissionDateTime.ToString("MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture) + "\r\nEXPERT: " + expertName, sub.TryGetPrefValue(PrefName.ProgramVersion, "0.0.0.0"), (hasJob?"X":"") ); rowSub.Tag = sub; gridBugSubmissions.ListGridRows.Add(rowSub); #endregion } gridBugsInProgress.EndUpdate(); gridBugsFixed.EndUpdate(); gridBugSubmissions.EndUpdate(); }
public static Bug AddBugAndJob(ODForm form, List <BugSubmission> listSelectedSubs, Patient pat) { if (!JobPermissions.IsAuthorized(JobPerm.Concept, true) && !JobPermissions.IsAuthorized(JobPerm.NotifyCustomer, true) && !JobPermissions.IsAuthorized(JobPerm.FeatureManager, true) && !JobPermissions.IsAuthorized(JobPerm.Documentation, true)) { return(null); } if (listSelectedSubs.Count == 0) { MsgBox.Show(form, "You must select a bug submission to create a job for."); return(null); } Job jobNew = new Job(); jobNew.Category = JobCategory.Bug; InputBox titleBox = new InputBox("Provide a brief title for the job."); if (titleBox.ShowDialog() != DialogResult.OK) { return(null); } if (String.IsNullOrEmpty(titleBox.textResult.Text)) { MsgBox.Show(form, "You must type a title to create a job."); return(null); } List <Def> listJobPriorities = Defs.GetDefsForCategory(DefCat.JobPriorities, true); if (listJobPriorities.Count == 0) { MsgBox.Show(form, "You have no priorities setup in definitions."); return(null); } jobNew.Title = titleBox.textResult.Text; long priorityNum = 0; priorityNum = listJobPriorities.FirstOrDefault(x => x.ItemValue.Contains("BugDefault")).DefNum; jobNew.Priority = priorityNum == 0?listJobPriorities.First().DefNum:priorityNum; jobNew.PhaseCur = JobPhase.Concept; jobNew.UserNumConcept = Security.CurUser.UserNum; Bug bugNew = new Bug(); bugNew = Bugs.GetNewBugForUser(); InputBox bugDescription = new InputBox("Provide a brief description for the bug. This will appear in the bug tracker.", jobNew.Title); if (bugDescription.ShowDialog() != DialogResult.OK) { return(null); } if (String.IsNullOrEmpty(bugDescription.textResult.Text)) { MsgBox.Show(form, "You must type a description to create a bug."); return(null); } FormVersionPrompt FormVP = new FormVersionPrompt("Enter versions found"); FormVP.ShowDialog(); if (FormVP.DialogResult != DialogResult.OK || string.IsNullOrEmpty(FormVP.VersionText)) { MsgBox.Show(form, "You must enter a version to create a bug."); return(null); } bugNew.Status_ = BugStatus.Accepted; bugNew.VersionsFound = FormVP.VersionText; bugNew.Description = bugDescription.textResult.Text; BugSubmission sub = listSelectedSubs.First(); jobNew.Requirements = BugSubmissions.GetSubmissionDescription(pat, sub); Jobs.Insert(jobNew); JobLink jobLinkNew = new JobLink(); jobLinkNew.LinkType = JobLinkType.Bug; jobLinkNew.JobNum = jobNew.JobNum; jobLinkNew.FKey = Bugs.Insert(bugNew); JobLinks.Insert(jobLinkNew); BugSubmissions.UpdateBugIds(bugNew.BugId, listSelectedSubs.Select(x => x.BugSubmissionNum).ToList()); if (MsgBox.Show(form, MsgBoxButtons.YesNo, "Would you like to create a task too?")) { long taskNum = CreateTask(pat, sub); if (taskNum != 0) { jobLinkNew = new JobLink(); jobLinkNew.LinkType = JobLinkType.Task; jobLinkNew.JobNum = jobNew.JobNum; jobLinkNew.FKey = taskNum; JobLinks.Insert(jobLinkNew); } } Signalods.SetInvalid(InvalidType.Jobs, KeyType.Job, jobNew.JobNum); FormOpenDental.S_GoToJob(jobNew.JobNum); return(bugNew); }
///<summary></summary> public static bool TryAssociateSimilarBugSubmissions(List <BugSubmission> listAllSubs, Point pointFormLocaiton) { List <BugSubmission> listUnattachedSubs = listAllSubs.Where(x => x.BugId == 0).ToList(); if (listUnattachedSubs.Count == 0) { MsgBox.Show("FormBugSubmissions", "All submissions are associated to bugs already."); return(false); } //Dictionary where key is a BugId and the value is list of submissions associated to that BugID. //StackTraces are unique and if there are duplicate stack trace entries we select the one with the newest version. Dictionary <long, List <BugSubmission> > dictAttachedSubs = listAllSubs.Where(x => x.BugId != 0) .GroupBy(x => x.BugId) .ToDictionary(x => x.Key, x => x.GroupBy(y => y.ExceptionStackTrace) //Sub dictionary of unique ExceptionStackStraces as the key and the value is the submission from the highest version. .ToDictionary(y => y.Key, y => y.OrderByDescending(z => new Version(z.Info.DictPrefValues[PrefName.ProgramVersion])).First()) .Values.ToList() ); Dictionary <long, List <BugSubmission> > dictSimilarBugSubs = new Dictionary <long, List <BugSubmission> >(); List <long> listOrderedKeys = dictAttachedSubs.Keys.OrderByDescending(x => x).ToList(); foreach (long key in listOrderedKeys) //Loop through submissions that are already attached to bugs { dictSimilarBugSubs[key] = new List <BugSubmission>(); foreach (BugSubmission sub in dictAttachedSubs[key]) //Loop through the unique exception text from the submission with thie highest reported version. { List <BugSubmission> listSimilarBugSubs = listUnattachedSubs.Where(x => x.ExceptionStackTrace == sub.ExceptionStackTrace//Find submissions that are not attached to bugs with identical ExceptionStackTrace ).ToList(); if (listSimilarBugSubs.Count == 0) { continue; //All submissions with this stack trace are attached to a bug. } listUnattachedSubs.RemoveAll(x => listSimilarBugSubs.Contains(x)); dictSimilarBugSubs[key].AddRange(listSimilarBugSubs); } } if (dictSimilarBugSubs.All(x => x.Value.Count == 0)) { MsgBox.Show("FormBugSubmissions", "All similar submissions are already attached to bugs. No action needed."); return(false); } dictSimilarBugSubs = dictSimilarBugSubs.Where(x => x.Value.Count != 0).ToDictionary(x => x.Key, x => x.Value); bool isAutoAssign = (MsgBox.Show("FormBugSubmissions", MsgBoxButtons.YesNo, "Click Yes to auto attach duplicate submissions to bugs with identical stack traces?" + "\r\nClick No to manually validate all groupings found.")); List <long> listBugIds = listAllSubs.Where(x => x.BugId != 0).Select(x => x.BugId).ToList(); List <JobLink> listLinks = JobLinks.GetManyForType(JobLinkType.Bug, listBugIds); List <Bug> listBugs = Bugs.GetMany(listBugIds); foreach (KeyValuePair <long, List <BugSubmission> > pair in dictSimilarBugSubs) { Bug bugFixed = listBugs.FirstOrDefault(x => x.BugId == pair.Key && !string.IsNullOrEmpty(x.VersionsFixed)); if (bugFixed != null) { List <BugSubmission> listIssueSubs = pair.Value.Where(x => new Version(x.Info.DictPrefValues[PrefName.ProgramVersion]) >= new Version(bugFixed.VersionsFixed.Split(';').Last())).ToList(); if (listIssueSubs.Count > 0) { MsgBox.Show("FormBugSubmissions", "There appears to be a submission on a version that is newer than the previous fixed bug version (BugId: " + POut.Long(bugFixed.BugId) + "). " + "These will be excluded."); //TODO: Allow user to view these excluded submissions somehow. pair.Value.RemoveAll(x => listIssueSubs.Contains(x)); if (pair.Value.Count == 0) { continue; } } } if (!isAutoAssign) { FormBugSubmissions formGroupBugSubs = new FormBugSubmissions(viewMode: FormBugSubmissionMode.ValidationMode); formGroupBugSubs.ListViewedSubs = pair.Value; //Add unnattached submissions to grid formGroupBugSubs.ListViewedSubs.AddRange(dictAttachedSubs[pair.Key]); //Add already attached submissions to grid formGroupBugSubs.StartPosition = FormStartPosition.Manual; Point newLoc = pointFormLocaiton; newLoc.X += 10; //Offset newLoc.Y += 10; formGroupBugSubs.Location = newLoc; if (formGroupBugSubs.ShowDialog() != DialogResult.OK) { continue; } } BugSubmissions.UpdateBugIds(pair.Key, pair.Value.Select(x => x.BugSubmissionNum).ToList()); } MsgBox.Show("FormBugSubmissions", "Done."); return(true); }
public static bool TryAssociateSimilarBugSubmissions(Point pointFormLocaiton) { List <BugSubmission> listAllSubs = BugSubmissions.GetAll(); List <BugSubmission> listUnattachedSubs = listAllSubs.Where(x => x.BugId == 0).ToList(); if (listUnattachedSubs.Count == 0) { MsgBox.Show("FormBugSubmissions", "All submissions are associated to bugs already."); return(false); } //Dictionary where key is a BugId and the value is list of submissions associated to that BugID. //StackTraces are unique and if there are duplicate stack trace entries we select the one with the newest version. Dictionary <long, List <BugSubmission> > dictAttachedSubs = listAllSubs.Where(x => x.BugId != 0) .GroupBy(x => x.BugId) .ToDictionary(x => x.Key, x => x.GroupBy(y => y.ExceptionStackTrace) //Sub dictionary of unique ExceptionStackStraces as the key and the value is the submission from the highest version. .ToDictionary(y => y.Key, y => y.OrderByDescending(z => new Version(z.Info.DictPrefValues[PrefName.ProgramVersion])).First()) .Values.ToList() ); Dictionary <long, List <BugSubmission> > dictSimilarBugSubs = new Dictionary <long, List <BugSubmission> >(); List <long> listOrderedKeys = dictAttachedSubs.Keys.OrderByDescending(x => x).ToList(); foreach (long key in listOrderedKeys) //Loop through submissions that are already attached to bugs { dictSimilarBugSubs[key] = new List <BugSubmission>(); foreach (BugSubmission sub in dictAttachedSubs[key]) //Loop through the unique exception text from the submission with thie highest reported version. { List <BugSubmission> listSimilarBugSubs = listUnattachedSubs.Where(x => x.ExceptionStackTrace == sub.ExceptionStackTrace//Find submissions that are not attached to bugs with identical ExceptionStackTrace ).ToList(); if (listSimilarBugSubs.Count == 0) { continue; //All submissions with this stack trace are attached to a bug. } listUnattachedSubs.RemoveAll(x => listSimilarBugSubs.Contains(x)); dictSimilarBugSubs[key].AddRange(listSimilarBugSubs); } } if (dictSimilarBugSubs.All(x => x.Value.Count == 0)) { MsgBox.Show("FormBugSubmissions", "All similar submissions are already attached to bugs. No action needed."); return(false); } dictSimilarBugSubs = dictSimilarBugSubs.Where(x => x.Value.Count != 0).ToDictionary(x => x.Key, x => x.Value); bool isAutoAssign = (MsgBox.Show("FormBugSubmissions", MsgBoxButtons.YesNo, "Click Yes to auto attach duplicate submissions to bugs with identical stack traces?" + "\r\nClick No to manually validate all groupings found.")); List <long> listBugIds = listAllSubs.Where(x => x.BugId != 0).Select(x => x.BugId).ToList(); List <JobLink> listLinks = JobLinks.GetManyForType(JobLinkType.Bug, listBugIds); List <Bug> listBugs = Bugs.GetMany(listBugIds); StringBuilder issueSubmissionPrompt = new StringBuilder(); foreach (KeyValuePair <long, List <BugSubmission> > pair in dictSimilarBugSubs) { Bug bugFixed = listBugs.FirstOrDefault(x => x.BugId == pair.Key && !string.IsNullOrEmpty(x.VersionsFixed)); if (bugFixed != null) { List <BugSubmission> listIssueSubs = pair.Value.Where(x => new Version(x.Info.DictPrefValues[PrefName.ProgramVersion]) >= new Version(bugFixed.VersionsFixed.Split(';').Last())).ToList(); if (listIssueSubs.Count > 0) { List <JobLink> listBugJobLinks = listLinks.FindAll(x => x.FKey == bugFixed.BugId); List <Job> listBugJobs = Jobs.GetMany(listBugJobLinks.Select(x => x.JobNum).ToList()); if (issueSubmissionPrompt.Length == 0) { issueSubmissionPrompt.AppendLine("The following completed jobs have submissions from newer versions then the jobs reported fixed version: "); } listBugJobs.ForEach(x => issueSubmissionPrompt.AppendLine("- " + " (" + x.Category.ToString().Substring(0, 1) + x.JobNum + ")" + x.Title)); pair.Value.RemoveAll(x => listIssueSubs.Contains(x)); if (pair.Value.Count == 0) { continue; } } } if (!isAutoAssign) { FormBugSubmissions formGroupBugSubs = new FormBugSubmissions(viewMode: FormBugSubmissionMode.ValidationMode); formGroupBugSubs.ListViewedSubs = pair.Value; //Add unnattached submissions to grid formGroupBugSubs.ListViewedSubs.AddRange(dictAttachedSubs[pair.Key]); //Add already attached submissions to grid formGroupBugSubs.StartPosition = FormStartPosition.Manual; Point newLoc = pointFormLocaiton; newLoc.X += 10; //Offset newLoc.Y += 10; formGroupBugSubs.Location = newLoc; if (formGroupBugSubs.ShowDialog() != DialogResult.OK) { continue; } } BugSubmissions.UpdateBugIds(pair.Key, pair.Value.Select(x => x.BugSubmissionNum).ToList()); } string msg = ""; dictSimilarBugSubs.Keys.ToList().FindAll(x => dictSimilarBugSubs[x].Count > 0) .ForEach(x => msg += "Bug: " + x + " Found submissions: " + dictSimilarBugSubs[x].Count + "\r\n"); msg += issueSubmissionPrompt.ToString(); new MsgBoxCopyPaste(msg) { Text = "Done" }.ShowDialog(); return(true); }