public async Task <IActionResult> Display(int id) { var item = await repo.GetWorkItem(id); if (item == null) { return(NotFound()); } return(PartialView("_SingleTaskView", Mappers.Map(item))); }
public async Task <ActionResult <WorkItemDto> > GetWorkItem(Guid iterationId, Guid id) { var workItem = await _workItemRepository.GetWorkItem(id); if (workItem == null) { return(NotFound("Work Item Not Found")); } var result = _mapper.Map <WorkItemDto>(workItem); return(Ok(result)); }
/// <summary> /// Gets the children of a work item /// </summary> public static IEnumerable <IWorkItem> GetChildrenFromListOrStore(this IWorkItem parent, IEnumerable <IWorkItem> workItemList, IWorkItemRepository store) { var decendants = new List <IWorkItem>(); // Go through all the links for the work item passed in (parent) foreach (TFS.WorkItemLink link in parent.WorkItemLinks) { IWorkItem childWorkItem; // Find all the child links if (link.LinkTypeEnd.Name == "Child") { // If this child link is in the list of items then add it to the result set if (workItemList.Select(x => x.Id).Contains(link.TargetId)) { var linkClosure = link; childWorkItem = workItemList.Where(x => x.Id == linkClosure.TargetId).FirstOrDefault(); } // if the item was not in our list then get it from the store else { childWorkItem = store.GetWorkItem(link.TargetId); } decendants.Add(childWorkItem); } } return(decendants); }
private IWorkItemRepository SetupFakeRepository() { repository = Substitute.For <IWorkItemRepository>(); workItem = Substitute.For <IWorkItem>(); //workItem.Fields.Returns(Substitute.For<IFieldCollectionWrapper>()); var estWorkField = Substitute.For <IFieldWrapper>(); workItem.Fields["EstimatedWork"] = estWorkField; workItem.Id.Returns(1); double fieldValue = 0.0D; var f = workItem.Fields; var x = workItem.Fields["Estimated Work"]; workItem.Fields["Estimated Work"].Value = fieldValue; workItem.When(w => w[Arg.Any <string>()] = Arg.Any <Double>()) .Do(c => { workItem.Fields[(string)c[0]].Value = (double)c[1]; }); workItem.GetField("Estimated Dev Work", 0.0D).Returns(1.0D); workItem.GetField("Estimated Test Work", 0.0D).Returns(2.0D); workItem.TypeName.Returns("Task"); workItem.IsValid().Returns(true); repository.GetWorkItem(1).Returns(workItem); return(repository); }
public IActionResult GetWorkItem(int ID) { if (ID <= 0) { return(base.BadRequest("ID have to be grater than 0!")); } WorkItemPublic workItem = mRepository.GetWorkItem(ID); if (workItem == null) { base.NotFound(workItem); } return(base.Ok(workItem)); }
/// <summary> /// Gets the workItem's parent from the list (if it is in there) or it will load /// it from the tfs store. We want to use the list if we can so that we can save only /// one time. (if not we could get conflicts in TFS for several updates to the same item. /// </summary> public static IWorkItem GetParentFromListOrStore(this IWorkItem childItem, IEnumerable <IWorkItem> workItemList, IWorkItemRepository store) { IWorkItem parent; // See if the parent work item is already in our workItemList (if so just use that one). int targetWorkItemId = (from TFS.WorkItemLink workItemLink in childItem.WorkItemLinks where workItemLink.LinkTypeEnd.Name == "Parent" select workItemLink.TargetId).FirstOrDefault(); parent = workItemList.Where(workItem => workItem.Id == targetWorkItemId).FirstOrDefault(); if (parent == null) { parent = (from TFS.WorkItemLink workItemLink in childItem.WorkItemLinks where workItemLink.LinkTypeEnd.Name == "Parent" select store.GetWorkItem(workItemLink.TargetId)).FirstOrDefault(); } return(parent); }
public async Task CompleteWorkItem(int workItemId, int userId, string workNotes, int?onBehalfOfUserId = null, bool force = false) { var workItem = await _workItemRepository.GetWorkItem(workItemId); var assignments = await _workItemRepository.GetWorkItemAssignments(workItemId); if (workItem.CompletedAt.HasValue) { return; } //sanitize work note markup if (!string.IsNullOrEmpty(workNotes)) { workNotes = SanitizeHtml(workNotes); } //administrative completion if (force) { await this.CompleteWorkItemAdminOnly(workItem, assignments, userId, workNotes, onBehalfOfUserId); } else if (workItem.CompletionMode == CompletionMode.AdminOnly) { await this.CompleteWorkItemAdminOnly(workItem, assignments, userId, workNotes, onBehalfOfUserId); } else if (workItem.CompletionMode == CompletionMode.AllAssigned) { await this.CompleteWorkItemAllAssigned(workItem, assignments, onBehalfOfUserId ?? userId, workNotes); } else if (workItem.CompletionMode == CompletionMode.Any) { await this.CompleteWorkItemAny(workItem, assignments, onBehalfOfUserId ?? userId, workNotes); } else if (workItem.CompletionMode == CompletionMode.AnyAssigned) { await this.CompleteWorkItemAnyAssigned(workItem, assignments, onBehalfOfUserId ?? userId, workNotes); } }
public WorkItem GetWorkItem(string id) { return(_workItemRepsitory.GetWorkItem(id)); }
/// <summary> /// This is the one where all the magic starts. Main() so to speak. I will load the settings, connect to tfs and apply the aggregation rules. /// </summary> public ProcessingResult ProcessEvent(IRequestContext requestContext, INotification notification) { var result = new ProcessingResult(); int currentAggregationId = 0; int workItemId = 0; string currentAggregationName = string.Empty; try { // Get the id of the work item that was just changed by the user. workItemId = notification.WorkItemId; // Download the work item so we can update it (if needed) var eventWorkItem = store.GetWorkItem(workItemId); var workItemTypeName = eventWorkItem.TypeName; var workItemsToSave = new List<IWorkItem>(); if (TFSAggregatorSettings.LoggingIsEnabled) { MiscHelpers.LogMessage(String.Format("Change detected to {0} [{1}]", workItemTypeName, workItemId)); MiscHelpers.LogMessage(String.Format("{0}Processing {1} AggregationItems", " ", TFSAggregatorSettings.ConfigAggregatorItems.Count.ToString())); } // Apply the aggregation rules to the work item foreach (ConfigAggregatorItem configAggregatorItem in TFSAggregatorSettings.ConfigAggregatorItems) { List<IWorkItem> sourceWorkItems = null; IWorkItem targetWorkItem = null; currentAggregationName = configAggregatorItem.Name; var matchableWorkItemTypes = configAggregatorItem.WorkItemType.Split(';'); // Check to make sure that the rule applies to the work item type we have if (matchableWorkItemTypes.Contains(eventWorkItem.TypeName)) { if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}[Entry {2}] Aggregation '{3}' applies to {1} work items", " ", workItemTypeName, currentAggregationId, currentAggregationName)); // Use the link type to see what the work item we are updating is if (configAggregatorItem.LinkType == ConfigLinkTypeEnum.Self) { // We are updating the same workitem that was sent in the event. sourceWorkItems = new List<IWorkItem> { eventWorkItem }; targetWorkItem = eventWorkItem; if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}{0}Aggregation applies to SELF. ({1} {2})", " ", workItemTypeName, workItemId)); // Make sure that all conditions are true before we do the aggregation // If any fail then we don't do this aggregation. if (!configAggregatorItem.Conditions.AreAllConditionsMet(targetWorkItem)) { if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for aggregation are not met.", " ")); currentAggregationId++; continue; } if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for aggregation are met.", " ")); } // We are aggregating to the parent else if (configAggregatorItem.LinkType == ConfigLinkTypeEnum.Parent) { bool parentLevelFound = true; // Go up the tree till we find the level of parent that we are looking for. var parentWorkItem = eventWorkItem; for (int i = 0; i < configAggregatorItem.LinkLevel; i++) { // Load the parent from the saved list (if we have it in there) or just load it from the store. IWorkItem tempWorkItem = parentWorkItem.GetParentFromListOrStore(workItemsToSave, store); // if (tempWorkItem != null) parentWorkItem = tempWorkItem; else parentLevelFound = false; } // If we did not find the correct parent then we are done with this aggregation. if (!parentLevelFound) { if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}{0}Couldn't find a PARENT {2} {4} up from {3} [{1}]. This aggregation will not continue.", " ", workItemId, configAggregatorItem.LinkLevel, workItemTypeName, configAggregatorItem.LinkLevel > 1 ? "levels" : "level")); currentAggregationId++; continue; } if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}{0}Found {1} [{2}] {3} {4} up from {5} [{6}]. Aggregation continues.", " ", parentWorkItem.TypeName, parentWorkItem.Id, configAggregatorItem.LinkLevel, configAggregatorItem.LinkLevel > 1 ? "levels" : "level", workItemTypeName, workItemId)); targetWorkItem = parentWorkItem; // Make sure that all conditions are true before we do the aggregation // If any fail then we don't do this aggregation. if (!configAggregatorItem.Conditions.AreAllConditionsMet(eventWorkItem, targetWorkItem)) { if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for parent aggregation are not met", " ")); currentAggregationId++; continue; } if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for parent aggregation are met", " ")); // Get the children down how ever many link levels were specified. var iterateFromParents = new List<IWorkItem> { targetWorkItem }; for (int i = 0; i < configAggregatorItem.LinkLevel; i++) { var thisLevelOfKids = new List<IWorkItem>(); // Iterate all the parents to find the children of current set of parents foreach (var iterateFromParent in iterateFromParents) { thisLevelOfKids.AddRange(iterateFromParent.GetChildrenFromListOrStore(workItemsToSave, store)); } iterateFromParents = thisLevelOfKids; } // remove the kids that are not the right type that we are working with iterateFromParents.RemoveAll(x => !matchableWorkItemTypes.Contains(x.TypeName)); sourceWorkItems = iterateFromParents; } // We are aggregating to the children else if (configAggregatorItem.LinkType == ConfigLinkTypeEnum.Children) { var parentWorkItem = eventWorkItem; var targetWorkItemTypes = configAggregatorItem.TargetWorkItemType.Split(';'); // Get the children down how ever many link levels were specified. // Start at the parent level and then iterate down the work item tree var currentLevelWorkItems = new List<IWorkItem> { parentWorkItem }; for (int i = 0; i < configAggregatorItem.LinkLevel; i++) { var thisLevelOfKids = new List<IWorkItem>(); // Iterate all the parents to find the children of current set of parents foreach (var iterateFromParent in currentLevelWorkItems) { thisLevelOfKids.AddRange(iterateFromParent.GetChildrenFromListOrStore(workItemsToSave, store)); } currentLevelWorkItems = thisLevelOfKids; } // remove the kids that are not of the type we want to change. currentLevelWorkItems.RemoveAll(x => !targetWorkItemTypes.Contains(x.TypeName)); sourceWorkItems = currentLevelWorkItems; // Make sure that all conditions are true before we do the aggregation // In a copyTo operation, the conditions are evaluated per child workitem. // If any fail then we don't do this aggregation. bool processItems = true; foreach (var childItem in sourceWorkItems) { if (!configAggregatorItem.Conditions.AreAllConditionsMet(childItem, parentWorkItem)) { if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for parent aggregation are not met", " ")); continue; } if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for parent aggregation are met", " ")); var changedWorkItem = Aggregator.Aggregate(eventWorkItem, null, childItem, configAggregatorItem); // If we made a change then add this work item to the list of items to save. if (changedWorkItem != null) { // Add the changed work item to the list of work items to save. workItemsToSave.AddIfUnique(changedWorkItem); } } } // Do the actual aggregation now if (configAggregatorItem.OperationType != OperationTypeEnum.CopyTo) { var changedWorkItem = Aggregator.Aggregate(eventWorkItem, sourceWorkItems, targetWorkItem, configAggregatorItem); // If we made a change then add this work item to the list of items to save. if (changedWorkItem != null) { // Add the changed work item to the list of work items to save. workItemsToSave.AddIfUnique(changedWorkItem); } } } else { if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}[Entry {2}] Aggregation '{3}' does not apply to {1} work items", " ", workItemTypeName, currentAggregationId, currentAggregationName)); } currentAggregationId++; } // Save any changes to the target work items. workItemsToSave.ForEach(x => { bool isValid = x.IsValid(); if (TFSAggregatorSettings.LoggingIsEnabled) { MiscHelpers.LogMessage(String.Format("{0}{0}{0}{1} [{2}] {3} valid to save. {4}", " ", x.TypeName, x.Id, isValid ? "IS" : "IS NOT", String.Format("\n{0}{0}{0}{0}Invalid fields: {1}", " ", MiscHelpers.GetInvalidWorkItemFieldsList(x).ToString()))); } if (isValid) { x.PartialOpen(); x.Save(); } }); MiscHelpers.AddRunSeparatorToLog(); } catch (Exception e) { string message = String.Format("Exception encountered processing Work Item [{2}]: {0} \nStack Trace:{1}", e.Message, e.StackTrace, workItemId); if (e.InnerException != null) { message += String.Format("\n Inner Exception: {0} \nStack Trace:{1}", e.InnerException.Message, e.InnerException.StackTrace); } MiscHelpers.LogMessage(message, true); } return result; }