// UC 6: Create a TR based on a Bug. // Return if the bug is updated or not. private void createTR( Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem, WorkItemChangedEvent notification, String user, ref Status status) { // Create the ECR callCreateTR(ECRMapper.mapFromWorkitem(workItem, null, ECRMapper.ACTION_CREATE), user, ref status); if (!status.OK) { return; } // UC 3 (one case): Update all changed attributes before handling any state change // Note: If adding an entry in History on create this should propagate to Progress Info, but // this caused Bug to appear dirty after Save, see issue 79. Given almost all fields are used on // create, it does not make sense to make extra update as below. TBD if we should re-add in a // changed form. //EnterpriseChangeRequest updatedEcr = ECRMapper.mapFromUpdatedWorkitem(workItem, status.TRAbout, notification); //if (updatedEcr != null) //{ // // Note: Failure to update will be Warning not Error, so status still OK. // callUpdateTR(updatedEcr, user, null, ref status); //} // Set the ECR in state Registered EnterpriseChangeRequest ecr = ECRMapper.mapFromWorkitem(workItem, status.TRAbout, ECRMapper.ACTION_REGISTER_ROUTE); callUpdateTR(ecr, user, ECRMapper.TR_STATE_REGISTERED_S, ref status); if (!status.OK) { return; } // Set the ECR in state Assigned if we have a defined owner ecr = ECRMapper.mapFromWorkitem(workItem, status.TRAbout, ECRMapper.ACTION_ASSIGN); if (ecr.GetOwner() != null && ecr.GetOwner().Length > 0) { callUpdateTR(ecr, user, ECRMapper.TR_STATE_ASSIGNED_S, ref status); if (!status.OK) { return; } } if (status.OK) { HandlerSettings.LogMessage( String.Format("Created TR based on workitem named: {0}", workItem.Title), HandlerSettings.LoggingLevel.INFO); } }
// Update the connected TR State. Return if the bug is updated or not. private void updateTRState( Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem, String oldState, String newState, String user, Uri about, ref Status status) { status.TRState = ECRMapper.getTRState(workItem); if (oldState.Equals(ECRMapper.BUG_STATE_ACTIVE, StringComparison.OrdinalIgnoreCase) && newState.Equals(ECRMapper.BUG_STATE_RESOLVED, StringComparison.OrdinalIgnoreCase)) { // UC 4: Updated TR based on the Bug's Active -> Resolve state change EnterpriseChangeRequest ecr = null; if (status.TRState.Equals(ECRMapper.TR_STATE_ASSIGNED)) { ecr = ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_PROPOSE); callUpdateTR(ecr, user, ECRMapper.TR_STATE_PROPOSED_S, ref status); if (!status.OK) { return; } } if (status.TRState.Equals(ECRMapper.TR_STATE_PROPOSED)) { String answerCode = ""; if (ecr != null) { answerCode = ecr.GetAnswerCode(); } else { answerCode = AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_ANSWER_CODE, workItem); } if (answerCode.Contains("A") || answerCode.Contains("D") || answerCode.Contains("B11")) { // In case Answer Code = A*, D*, or B11 go directly to Answer callUpdateTR(ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_ANSWER), user, ECRMapper.TR_STATE_TECH_ANSW_PROV_S, ref status); return; } else { callUpdateTR(ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_APPROVE), user, ECRMapper.TR_STATE_PROP_APPROV_S, ref status); } } String expectedState = ECRMapper.TR_STATE_PROP_APPROV; if (!status.TRState.Equals(expectedState)) { // Incorrect pre condition HandlerSettings.LogMessage( String.Format("Expected TR State: {0}, current TR state: {1}", expectedState, status.TRState), HandlerSettings.LoggingLevel.WARN); } // Note: Here we assume we are in trState PA, as we accepted AS, PP and PA. If we have not failed // before, this is where we will fail if any assumption was wrong -> error message. if (status.OK) { callUpdateTR(ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_VERIFY), user, ECRMapper.TR_STATE_TECH_ANSW_PROV_S, ref status); } } else if (oldState.Equals(ECRMapper.BUG_STATE_RESOLVED, StringComparison.OrdinalIgnoreCase) && newState.Equals(ECRMapper.BUG_STATE_CLOSED, StringComparison.OrdinalIgnoreCase)) { // Update a TR based on Close of the Bug's Resolve -> Close state change String expectedState = ECRMapper.TR_STATE_TECH_ANSW_PROV; if (!status.TRState.Equals(expectedState)) { // Incorrect pre condition HandlerSettings.LogMessage( String.Format("Expected TR State: {0}, current TR state: {1}", expectedState, status.TRState), HandlerSettings.LoggingLevel.WARN); } // TODO: Put the condition in configuration file etc. String answerCode = AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_ANSWER_CODE, workItem); if (answerCode.Equals("D4")) { // UC 9.3 - Bug set as Postponed callUpdateTR(ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_ACCEPT), user, ECRMapper.TR_STATE_POSTPONED_S, ref status); } else if (answerCode.Equals("Duplicate")) { // UC 9.4 - Bug set as Duplicate callUpdateTR(ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_DUPLICATE), user, null, ref status); } else { // UC 9.1 - Close of Bug from TFS callUpdateTR(ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_FINISH), user, ECRMapper.TR_STATE_FINISHED_S, ref status); } } else if (oldState.Equals(ECRMapper.BUG_STATE_RESOLVED, StringComparison.OrdinalIgnoreCase) && newState.Equals(ECRMapper.BUG_STATE_ACTIVE, StringComparison.OrdinalIgnoreCase)) { // UC 9.2: Update a TR based the Bug's Resolved -> Active state change callUpdateTR(ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_REJECT), user, ECRMapper.TR_STATE_REGISTERED_S, ref status); if (!status.OK) { return; } // If Bug is assigned to a user we need to drive change back to Assigned state EnterpriseChangeRequest ecr = ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_ASSIGN); if (ecr.GetOwner() != null && ecr.GetOwner().Length > 0) { callUpdateTR(ecr, user, ECRMapper.TR_STATE_ASSIGNED_S, ref status); } } else if (oldState.Equals(ECRMapper.BUG_STATE_CLOSED, StringComparison.OrdinalIgnoreCase) && newState.Equals(ECRMapper.BUG_STATE_ACTIVE, StringComparison.OrdinalIgnoreCase)) { // UC 9.2: Update a TR based the Bug's Closed -> Active state change // In case of Closed -> Active, this is only allowed for the "no action" answer codes // in MHWeb, so OK for this to fail if selecting the incorrect answer code. // Could block in Bug.xml if we want to prevent some cases. callUpdateTR(ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_REACTIVATE), user, ECRMapper.TR_STATE_REGISTERED_S, ref status); if (!status.OK) { return; } // If Bug is assigned to a user we need to drive change back to Assigned state EnterpriseChangeRequest ecr = ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_ASSIGN); if (ecr.GetOwner() != null && ecr.GetOwner().Length > 0) { callUpdateTR(ecr, user, ECRMapper.TR_STATE_ASSIGNED_S, ref status); } } else if (oldState.Equals(ECRMapper.BUG_STATE_ACTIVE, StringComparison.OrdinalIgnoreCase) && newState.Equals(ECRMapper.BUG_STATE_ACTIVE, StringComparison.OrdinalIgnoreCase)) { // UC 3 (one case): Handle Assign case - state change for TR, attribute change for Bug // Incorrect pre condition String expectedState = ECRMapper.TR_STATE_REGISTERED; if (!status.TRState.Equals(expectedState)) { HandlerSettings.LogMessage( String.Format("Expected TR State: {0}, current TR state: {1}", expectedState, status.TRState), HandlerSettings.LoggingLevel.WARN); } // Handle case when we are in state PR if (status.TRState.Equals(ECRMapper.TR_STATE_PRIVATE)) { callUpdateTR(ECRMapper.mapFromWorkitem( workItem, about, ECRMapper.ACTION_REGISTER_ROUTE), user, ECRMapper.TR_STATE_REGISTERED_S, ref status); } callUpdateTR(ECRMapper.mapFromWorkitem( workItem, about, ECRMapper.ACTION_ASSIGN), user, ECRMapper.TR_STATE_ASSIGNED_S, ref status); } }