public async Task <IActionResult> Display(int id)
        {
            var item = await repo.GetWorkItem(id);

            if (item == null)
            {
                return(NotFound());
            }

            return(PartialView("_SingleTaskView", Mappers.Map(item)));
        }
Esempio n. 2
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 7
0
        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));
 }
Esempio n. 9
0
        /// <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;
        }