/// <summary> /// Clone Bug /// </summary> /// <param name="bugId"></param> /// <param name="targetConnectDomain"></param> /// <param name="targetProductName"></param> public void CloneBug(int bugId, string targetConnectDomain, string targetProductName) { DatastoreItem psItem = null; DatastoreItem psCloneItem = null; ProductStudio.Directory psTargetDirectory = null; Product psTargetProduct = null; Datastore psTargetDataStore = null; try { if (targetConnectDomain != null && targetProductName != null) { psTargetDirectory = new ProductStudio.Directory(); psTargetDirectory.Connect(targetConnectDomain, "", ""); psTargetProduct = psTargetDirectory.GetProductByName(targetProductName); psTargetDataStore = psTargetProduct.Connect("", "", ""); } else { psTargetDataStore = this.psDataStore; } psItem = this.psDataStore.GetDatastoreItem(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs, bugId, null); psItem.Edit(PsItemEditActionEnum.psDatastoreItemEditActionReadOnly, null, PsApplyRulesMask.psApplyRulesAll); // Clone the item to the targetDataStore psCloneItem = psItem.Clone(psTargetDataStore); // Save the new item psCloneItem.Save(true); } catch (Exception e) { throw new Exception(String.Format("Failed to clone bug {0} to {1} database.", bugId, targetProductName), e); } finally { if (psTargetDirectory != null) { psTargetDirectory.Disconnect(); } } }
/// <summary> /// Update Bug in PS using the PS SDK /// </summary> /// <param name="bugChangeList"></param> /// <param name="bugFieldMappingCollection"></param> /// <param name="updateAction"></param> public void UpdateBug(PSBugChangeList psBugChangeList) { DatastoreItem psItem = null; bool hasInvalidField = false; try { psItem = this.psDataStore.GetDatastoreItem(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs, psBugChangeList.BugId, null); switch (psBugChangeList.Action) { case PSUpdateAction.Update: psItem.Edit(PsItemEditActionEnum.psDatastoreItemEditActionEdit, null, PsApplyRulesMask.psApplyRulesAll); break; case PSUpdateAction.Resolve: psItem.Edit(PsItemEditActionEnum.psBugEditActionResolve, null, PsApplyRulesMask.psApplyRulesAll); break; case PSUpdateAction.Close: psItem.Edit(PsItemEditActionEnum.psBugEditActionClose, null, PsApplyRulesMask.psApplyRulesAll); break; case PSUpdateAction.Activate: psItem.Edit(PsItemEditActionEnum.psBugEditActionActivate, null, PsApplyRulesMask.psApplyRulesAll); break; } foreach (string psFieldName in psBugChangeList.BugChanges.Keys) { // We need to skip these values as they are auto filled by PS. if (string.Compare(psFieldName, "Closed By", true) == 0 || string.Compare(psFieldName, "Resolved By", true) == 0 || string.Compare(psFieldName, "Changed By", true) == 0) { continue; } Field psField = null; // PendingChangelist doesn't have mapping value in DB because Sync Service doesn't handle it, so we have to map it to a PS value manually. if (string.Compare(psFieldName, BugFields.PendingChangelist.ToString(), true) == 0) { psField = psItem.Fields["ChangelistInfo"]; } else { psField = psItem.Fields[psFieldName]; } if (psField == null) { throw new Exception("Failed to find property [" + psFieldName + "]"); } else if (psField.IsReadOnly) { // We need to do some logging here as we skip some read-only psField when doing update //throw new Exception("Failed to update read-only property [" + psFieldName + "]"); continue; } else { // SLA Date in PS is string, but in SysBugItem is DateTime, there comes is datetime string or null if (string.Compare(psField.Name, "SLA Date", true) == 0) { DateTime slaDate; if (DateTime.TryParse(psBugChangeList.BugChanges[psFieldName].ToString(), out slaDate) == true) { psField.Value = string.Format("{0:MM/dd/yyyy}", slaDate); } else { psField.Value = null; } } // PendingChangelist doesn't have mapping value in DB because Sync Service doesn't handle it, so we have to map it to a PS value manually. else if (string.Compare(psField.Name, "ChangelistInfo", true) == 0) { Dictionary <string, ChangelistInfo> changelistDict = new Dictionary <string, ChangelistInfo>(StringComparer.OrdinalIgnoreCase); string changeListInfos = psField.Value; ChangelistInfo newPendingChangelist = psBugChangeList.BugChanges[psFieldName] as ChangelistInfo; if (string.IsNullOrEmpty(changeListInfos) == false && changeListInfos.Length > 0) { Regex r = new Regex(@"^\s*\d+,.+,.+,.+,.+,.*$"); string[] split = changeListInfos.Split("\r".ToCharArray()); foreach (string s in split) { // 722: Handle changelist with linefeed in description if (r.IsMatch(s.Trim("\n".ToCharArray()))) { ChangelistInfo info = new ChangelistInfo(s.Trim("\n".ToCharArray())); // If the changelist is related and it also ends with $$SEPortal$$, we will discard them, not adding them into the dictionary if (string.Compare(info.Relation, "related", true) == 0 && info.Description.EndsWith("$$SEPortal$$") == true) { continue; } // If the changelist has the same id as the new changelist, we will discard it, not adding it into the dictionary if (newPendingChangelist != null && string.Compare(info.ChangelistId, newPendingChangelist.ChangelistId, true) == 0) { continue; } // Add the changelist to the dictionary if it is not already added if (changelistDict.ContainsKey(info.ChangelistId) == false) { changelistDict.Add(info.ChangelistId, info); } } } } if (newPendingChangelist != null) { changelistDict.Add(newPendingChangelist.ChangelistId, newPendingChangelist); } string pendingChangelistStr = string.Empty; foreach (ChangelistInfo changelistInfo in changelistDict.Values) { if (newPendingChangelist != null && string.Compare(newPendingChangelist.Relation, "Related", true) == 0 && string.Compare(newPendingChangelist.ChangelistId, changelistInfo.ChangelistId, true) == 0) { pendingChangelistStr += changelistInfo.ToString() + " $$SEPortal$$\r"; } else { pendingChangelistStr += changelistInfo.ToString() + "\r"; } } psField.Value = pendingChangelistStr; } else { if (psBugChangeList.BugChanges[psFieldName] != null) { psField.Value = psBugChangeList.BugChanges[psFieldName].ToString(); } else { psField.Value = null; } } } } // Verify that all fields are valid before saving foreach (ProductStudio.Field field in psItem.Fields) { if (field.Validity != PsFieldStatusEnum.psFieldStatusValid) { hasInvalidField = true; throw new Exception("Updating Field (" + field.Name + ") with Value (" + field.Value + ") is invalid. Counld not edit bug " + psBugChangeList.BugId.ToString()); } } // Commit the save if there is no invalid field if (hasInvalidField) { throw new Exception("Invalid Field(s) were found. Could not edit bug " + psBugChangeList.BugId.ToString()); } else { psItem.Save(); } } catch (Exception e) { throw new Exception(String.Format("Failed to update bug {0} in {1} database.", psBugChangeList.BugId, this.productName), e); } }