/// <summary>Hit when the user wants to merge their changes with the concurrent task.</summary> /// <param name="sender">btnConcurrencyMergeYes</param> /// <param name="e">RoutedEventArgs</param> private void btnConcurrencyMergeYes_Click(object sender, RoutedEventArgs e) { try { e.Handled = true; //Get the client. ImportExportClient client = ((dynamic)sender).Tag as ImportExportClient; if (client != null) { //Switch screens again... this.display_SetOverlayWindow(this.panelSaving, System.Windows.Visibility.Visible); this.display_SetOverlayWindow(this.panelError, System.Windows.Visibility.Hidden); this.barSavingReq.Value--; //Re-launch the saving.. RemoteRequirement reqMerged = StaticFuncs.MergeWithConcurrency(this.save_GetFromFields(), this._Requirement, this._RequirementConcurrent); this._clientNumSaving++; client.Requirement_UpdateAsync(reqMerged, this._clientNum++); } } catch (Exception ex) { Logger.LogMessage(ex, "btnConcurrencyMergeYes_Click()"); MessageBox.Show(StaticFuncs.getCultureResource.GetString("app_General_UnexpectedError"), StaticFuncs.getCultureResource.GetString("app_General_ApplicationShortName"), MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary>Hit if we hit a concurrency issue, and have to compare values.</summary> /// <param name="sender">ImportExportClient</param> /// <param name="e">Incident_RetrieveByIdCompletedEventArgs</param> private void client_Requirement_RetrieveByIdCompleted(object sender, Requirement_RetrieveByIdCompletedEventArgs e) { const string METHOD = CLASS + "client_Requirement_RetrieveByIdCompleted()"; Logger.LogTrace_EnterMethod(METHOD + " " + this._clientNumSaving.ToString() + " clients running."); try { ImportExportClient client = (sender as ImportExportClient); this._clientNumSaving--; this.barSavingReq.Value++; if (!e.Cancelled) { if (e.Error == null) { //We got new information here. Let's see if it can be merged. bool canBeMerged = this.save_CheckIfConcurrencyCanBeMerged(e.Result); this._RequirementConcurrent = e.Result; if (canBeMerged) { this.gridLoadingError.Visibility = System.Windows.Visibility.Collapsed; this.gridSavingConcurrencyMerge.Visibility = System.Windows.Visibility.Visible; this.gridSavingConcurrencyNoMerge.Visibility = System.Windows.Visibility.Collapsed; this.display_SetOverlayWindow(this.panelSaving, System.Windows.Visibility.Hidden); this.display_SetOverlayWindow(this.panelError, System.Windows.Visibility.Visible); //Save the client to the 'Merge' button. this.btnConcurrencyMergeYes.Tag = sender; } else { //TODO: Display error message here, tell users they must refresh their data. this.gridLoadingError.Visibility = System.Windows.Visibility.Collapsed; this.gridSavingConcurrencyMerge.Visibility = System.Windows.Visibility.Collapsed; this.gridSavingConcurrencyNoMerge.Visibility = System.Windows.Visibility.Visible; this.display_SetOverlayWindow(this.panelSaving, System.Windows.Visibility.Hidden); this.display_SetOverlayWindow(this.panelError, System.Windows.Visibility.Visible); } } else { //We even errored on retrieving information. Somethin's really wrong here. //Display error. Logger.LogMessage(e.Error, "Getting updated Concurrency Incident"); } } } catch (Exception ex) { Logger.LogMessage(ex, METHOD); MessageBox.Show(StaticFuncs.getCultureResource.GetString("app_General_UnexpectedError"), StaticFuncs.getCultureResource.GetString("app_General_ApplicationShortName"), MessageBoxButton.OK, MessageBoxImage.Error); } Logger.LogTrace_ExitMethod(METHOD + " " + this._clientNumSaving.ToString() + " clients left."); }
/// <summary>Copies over our values from the form into an Incident object.</summary> /// <returns>A new RemoteIncident, or Null if error.</returns> private RemoteRequirement save_GetFromFields() { const string METHOD = CLASS + "save_GetFromFields()"; RemoteRequirement retRequirement = null; try { retRequirement = new RemoteRequirement(); //Standard fields.. retRequirement.ConcurrencyDate = this._Requirement.ConcurrencyDate; retRequirement.CoverageCountBlocked = this._Requirement.CoverageCountBlocked; retRequirement.CoverageCountCaution = this._Requirement.CoverageCountCaution; retRequirement.CoverageCountFailed = this._Requirement.CoverageCountFailed; retRequirement.CoverageCountPassed = this._Requirement.CoverageCountPassed; retRequirement.CoverageCountTotal = this._Requirement.CoverageCountTotal; retRequirement.CreationDate = this._Requirement.CreationDate.ToUniversalTime(); retRequirement.IndentLevel = this._Requirement.IndentLevel; retRequirement.LastUpdateDate = this._Requirement.LastUpdateDate.ToUniversalTime(); retRequirement.ProjectId = this._Requirement.ProjectId; retRequirement.RequirementId = this._Requirement.RequirementId; retRequirement.Summary = this._Requirement.Summary; retRequirement.TaskActualEffort = this._Requirement.TaskActualEffort; retRequirement.TaskCount = this._Requirement.TaskCount; retRequirement.TaskEstimatedEffort = this._Requirement.TaskEstimatedEffort; retRequirement.AuthorId = ((RemoteUser)this.cntrlCreatedBy.SelectedItem).UserId; if (this._isDescChanged) { retRequirement.Description = this.cntrlDescription.HTMLText; } else { retRequirement.Description = this._Requirement.Description; } retRequirement.ImportanceId = ((RequirementPriority)this.cntrlImportance.SelectedItem).PriorityId; retRequirement.Name = this.cntrlName.Text.Trim(); retRequirement.OwnerId = ((RemoteUser)this.cntrlOwnedBy.SelectedItem).UserId; retRequirement.PlannedEffort = StaticFuncs.GetMinutesFromValues(this.cntrlPlnEffortH.Text, this.cntrlPlnEffortM.Text); retRequirement.ReleaseId = ((RemoteRelease)this.cntrlRelease.SelectedItem).ReleaseId; retRequirement.StatusId = ((RequirementStatus)this.cntrlStatus.SelectedItem).StatusId; //Custom Properties retRequirement.CustomProperties = this.cntCustomProps.GetCustomProperties(); } catch (Exception ex) { Logger.LogMessage(ex, METHOD); MessageBox.Show(StaticFuncs.getCultureResource.GetString("app_General_UnexpectedError"), StaticFuncs.getCultureResource.GetString("app_General_ApplicationShortName"), MessageBoxButton.OK, MessageBoxImage.Error); retRequirement = null; } //Return return(retRequirement); }
/// <summary>Hit when the user wants to save the task.</summary> /// <param name="sender">The save button.</param> /// <param name="e">RoutedEventArgs</param> private void btnSave_Click(object sender, RoutedEventArgs e) { try { e.Handled = true; } catch { } try { this.barSavingReq.Value = -5; this.barSavingReq.Maximum = 0; this.barSavingReq.Minimum = -5; if (this._isFieldChanged || this._isResChanged || this._isDescChanged) { //Set working flag. this.IsSaving = true; //Get the new values from the form.. RemoteRequirement newRequirement = this.save_GetFromFields(); if (newRequirement != null) { //Create a client, and save task and resolution.. ImportExportClient clientSave = StaticFuncs.CreateClient(((SpiraProject)this._ArtifactDetails.ArtifactParentProject.ArtifactTag).ServerURL.ToString()); clientSave.Connection_Authenticate2Completed += clientSave_Connection_Authenticate2Completed; clientSave.Connection_ConnectToProjectCompleted += clientSave_Connection_ConnectToProjectCompleted; clientSave.Requirement_UpdateCompleted += clientSave_Requirement_UpdateCompleted; clientSave.Requirement_CreateCommentCompleted += clientSave_Requirement_CreateCommentCompleted; clientSave.Connection_DisconnectCompleted += clientSave_Connection_DisconnectCompleted; //Fire off the connection. this._clientNumSaving = 1; clientSave.Connection_Authenticate2Async(((SpiraProject)this._ArtifactDetails.ArtifactParentProject.ArtifactTag).UserName, ((SpiraProject)this._ArtifactDetails.ArtifactParentProject.ArtifactTag).UserPass, StaticFuncs.getCultureResource.GetString("app_ReportName"), this._clientNum++); } else { //Display message saying that some required fields aren't filled out. MessageBox.Show(StaticFuncs.getCultureResource.GetString("app_General_RequiredFieldsMessage"), StaticFuncs.getCultureResource.GetString("app_General_RequiredFields"), MessageBoxButton.OK, MessageBoxImage.Error); } } } catch (Exception ex) { Logger.LogMessage(ex, "btnSave_Click()"); MessageBox.Show(StaticFuncs.getCultureResource.GetString("app_General_UnexpectedError"), StaticFuncs.getCultureResource.GetString("app_General_ApplicationShortName"), MessageBoxButton.OK, MessageBoxImage.Error); } if (this._clientNumSaving == 0) { this.IsSaving = false; } }
public static RemoteRequirement MergeWithConcurrency(RemoteRequirement userSaved, RemoteRequirement original, RemoteRequirement serverModded) { //If the field was not changed by the user (reqUserSaved == reqOriginal), then use the reqConcurrent. (Assuming that the // reqConcurrent has a possible updated value. //Otherwise, use the reqUserSaved value. try { RemoteRequirement retRequirement = new RemoteRequirement(); //Let do fixed fields first. retRequirement.CoverageCountBlocked = serverModded.CoverageCountBlocked; retRequirement.CoverageCountCaution = serverModded.CoverageCountCaution; retRequirement.CoverageCountFailed = serverModded.CoverageCountFailed; retRequirement.CoverageCountPassed = serverModded.CoverageCountPassed; retRequirement.CoverageCountTotal = serverModded.CoverageCountTotal; retRequirement.CreationDate = serverModded.CreationDate; retRequirement.IndentLevel = serverModded.IndentLevel; retRequirement.LastUpdateDate = serverModded.LastUpdateDate; retRequirement.ProjectId = serverModded.ProjectId; retRequirement.RequirementId = serverModded.RequirementId; retRequirement.Summary = serverModded.Summary; retRequirement.TaskActualEffort = serverModded.TaskActualEffort; retRequirement.TaskCount = serverModded.TaskCount; retRequirement.TaskEstimatedEffort = serverModded.TaskEstimatedEffort; //Now the user fields.. retRequirement.AuthorId = ((userSaved.AuthorId == original.AuthorId) ? serverModded.AuthorId : userSaved.AuthorId); string strDescUser = StaticFuncs.StripTagsCharArray(userSaved.Description); string strDescOrig = StaticFuncs.StripTagsCharArray(original.Description); retRequirement.Description = ((strDescOrig.TrimEquals(strDescOrig)) ? serverModded.Description : userSaved.Description); retRequirement.ImportanceId = ((userSaved.ImportanceId == original.ImportanceId) ? serverModded.ImportanceId : userSaved.ImportanceId); retRequirement.Name = ((userSaved.Name == original.Name) ? serverModded.Name : userSaved.Name); retRequirement.OwnerId = ((userSaved.OwnerId == original.OwnerId) ? serverModded.OwnerId : userSaved.OwnerId); retRequirement.PlannedEffort = ((userSaved.PlannedEffort == original.PlannedEffort) ? serverModded.PlannedEffort : userSaved.PlannedEffort); retRequirement.ReleaseId = ((userSaved.ReleaseId == original.ReleaseId) ? serverModded.ReleaseId : userSaved.ReleaseId); retRequirement.StatusId = ((userSaved.StatusId == original.StatusId) ? serverModded.StatusId : userSaved.StatusId); //Custom Properties retRequirement.CustomProperties = MergeCustomFieldsWithConcurrency(userSaved, original, serverModded); //Return our new task. return(retRequirement); } catch (Exception ex) { Logger.LogMessage(ex, "save_MergeConcurrency()"); MessageBox.Show(StaticFuncs.getCultureResource.GetString("app_General_UnexpectedError"), StaticFuncs.getCultureResource.GetString("app_General_ApplicationShortName"), MessageBoxButton.OK, MessageBoxImage.Error); return(null); } }
/// <summary>Checks the given properties on the artifact the user is modifying against the given artifact to report wether the fields can be merged or not.</summary> /// <param name="originalTask">The original artifact before any edits.</param> /// <param name="serverModdedTask">The new artifact form the server - edited by someone else.</param> /// <param name="userEnteredTask">The modified artifact from our user.</param> /// <returns>True if fields can be merged. False otherwise.</returns> public static bool CanBeMergedWith(this RemoteRequirement userEnteredReq, RemoteRequirement originalReq, RemoteRequirement serverModdedReq) { bool retValue = false; //Check the standard fields, first.. if (userEnteredReq.AuthorId != originalReq.AuthorId) { retValue = (originalReq.AuthorId == serverModdedReq.AuthorId); } if (!retValue) { if (StripTagsCharArray(userEnteredReq.Description).ToLowerInvariant().Trim() != StripTagsCharArray(originalReq.Description).ToLowerInvariant().Trim()) { retValue = (StripTagsCharArray(originalReq.Description).ToLowerInvariant().Trim() == StripTagsCharArray(serverModdedReq.Description).ToLowerInvariant().Trim()); } } if (!retValue && userEnteredReq.ImportanceId != originalReq.ImportanceId) { retValue = (originalReq.ImportanceId == serverModdedReq.ImportanceId); } if (!retValue && userEnteredReq.Name.Equals(originalReq.Name)) { retValue = (originalReq.Name.Equals(serverModdedReq.ImportanceId)); } if (!retValue && userEnteredReq.OwnerId != originalReq.OwnerId) { retValue = (originalReq.OwnerId == serverModdedReq.OwnerId); } if (!retValue && userEnteredReq.PlannedEffort != originalReq.PlannedEffort) { retValue = (originalReq.PlannedEffort == serverModdedReq.PlannedEffort); } if (!retValue && userEnteredReq.ReleaseId != originalReq.ReleaseId) { retValue = (originalReq.ReleaseId == serverModdedReq.ReleaseId); } if (!retValue && userEnteredReq.StatusId != originalReq.StatusId) { retValue = (originalReq.StatusId == serverModdedReq.StatusId); } //Check custom values. if (!retValue) { retValue = CanCustomPropertiesBeMergedWith(userEnteredReq, originalReq, serverModdedReq); } return(retValue); }
/// <summary>Returns whether the given Concurrent Requirement can be safely merged with the user's values.</summary> /// <param name="moddedTask">The concurrent Requirement.</param> private bool save_CheckIfConcurrencyCanBeMerged(RemoteRequirement moddedRequirement) { bool retValue = false; try { //Get current values.. RemoteRequirement userRequirement = this.save_GetFromFields(); retValue = userRequirement.CanBeMergedWith(this._Requirement, moddedRequirement); } catch (Exception ex) { Logger.LogMessage(ex, "save_CheckIfConcurrencyCanBeMerged()"); MessageBox.Show(StaticFuncs.getCultureResource.GetString("app_General_UnexpectedError"), StaticFuncs.getCultureResource.GetString("app_General_ApplicationShortName"), MessageBoxButton.OK, MessageBoxImage.Error); retValue = false; } return(retValue); }
/// <summary>Hit when we're finished connecting to the project.</summary> /// <param name="sender">ImportExportClient</param> /// <param name="e">Connection_ConnectToProjectCompletedEventArgs</param> private void clientSave_Connection_ConnectToProjectCompleted(object sender, Connection_ConnectToProjectCompletedEventArgs e) { const string METHOD = CLASS + "clientSave_Connection_ConnectToProjectCompleted()"; Logger.LogTrace_EnterMethod(METHOD + " " + this._clientNumSaving.ToString() + " clients running."); try { ImportExportClient client = (sender as ImportExportClient); this._clientNumSaving--; this.barSavingReq.Value++; if (!e.Cancelled) { if (e.Error == null) { if (e.Result) { //Get the new RemoteIncident RemoteRequirement newRequirement = this.save_GetFromFields(); if (newRequirement != null) { //Fire off our update calls. this._clientNumSaving++; client.Requirement_UpdateAsync(newRequirement, this._clientNum++); } else { //TODO: Show Error. //Cancel calls. this._clientNumSaving++; client.Connection_DisconnectAsync(this._clientNum++); } } else { //TODO: Show Error. //Cancel calls. this._clientNumSaving++; client.Connection_DisconnectAsync(this._clientNum++); } } else { //TODO: Show Error. //Cancel calls. this._clientNumSaving++; client.Connection_DisconnectAsync(this._clientNum++); } } //See if it's okay to reload. this.save_CheckIfOkayToLoad(); } catch (Exception ex) { Logger.LogMessage(ex, METHOD); MessageBox.Show(StaticFuncs.getCultureResource.GetString("app_General_UnexpectedError"), StaticFuncs.getCultureResource.GetString("app_General_ApplicationShortName"), MessageBoxButton.OK, MessageBoxImage.Error); } Logger.LogTrace_ExitMethod(METHOD + " " + this._clientNumSaving.ToString() + " clients left."); }