示例#1
0
        public override List <TimeLog> LoadData(TimeLogReportingServiceContext context)
        {
            string iterationPath = context.IterationPath;
            //var estimatedEndDate = context.GetMilestone(CodeCompletionDate);

            var wiStore = Connect(context).GetService <WorkItemStore>();

            //get linked work items
            //http://blogs.msdn.com/b/jsocha/archive/2012/02/22/retrieving-tfs-results-from-a-tree-query.aspx
            Query treeQuery = PrepareTreeQuery(wiStore, iterationPath, context.Project.Title);

            WorkItemLinkInfo[] links         = treeQuery.RunLinkQuery();
            WorkItemCollection linkedResults = GetAssociatedWorkItems(wiStore, treeQuery, links);
            var linkedList  = ConvertToTimeTrackingDetails(linkedResults);
            var relationMap = BuildRelationMap(linkedList, links);

            //get unlinked workitems
            WorkItemCollection results = GetAllWorkItems(wiStore, iterationPath, context.Project.Title);
            var list   = ConvertToTimeTrackingDetails(results);
            var idList = relationMap.Select(q => q.WorkitemId).ToList();

            relationMap.AddRange(list.Where(p => !idList.Contains(p.WorkitemId)));

            SkipSpecificTitlePBIs(relationMap);
            return(relationMap);
        }
示例#2
0
        public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
        {
            if (string.Compare(workitem.Type, ProductBacklogItem, true) == 0)
            {
                //get atleast one "IMPACT ANALYSIS" task assigned to anyone
                const string AnalysisTaskTitle = "IMPACT ANALYSIS";
                var          analysisTasks     = workitem.Tasks.Where(q => q.Title.ToUpper().IndexOf(AnalysisTaskTitle) >= 0).ToList();
                if (analysisTasks.Count > 0)
                {
                    analysisTasks.ForEach(p => p.Owner = TaskOwnerType.Team);
                }
                else
                {
                    workitem.Observations.Add(new Observation
                    {
                        Code       = "Lifecycle checklist",
                        Title      = "Impact Analysis task not created yet",
                        AssignedTo = workitem.AssignedTo
                    });
                }

                //get atleast one "touch points" task assigned to anyone (optional)
                const string TouchPointTaskTitle = "TOUCH POINT";
                var          touchPointTasks     = workitem.Tasks.Where(q => q.Title.ToUpper().IndexOf(TouchPointTaskTitle) >= 0).ToList();
                if (touchPointTasks.Count > 0)
                {
                    touchPointTasks.ForEach(p => p.Owner = TaskOwnerType.Team);
                }
            }
        }
示例#3
0
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     if (workitem.PlannedDevEfforts == 0)
     {
         //get first developer
         var assignedToDev = workitem.Tasks.Where(p => p.Owner == TaskOwnerType.Developer).FirstOrDefault();
         workitem.Observations.Add(new Observation
         {
             Code       = "Lifecycle checklist",
             Title      = "Dev estimates are missing.",
             AssignedTo = assignedToDev != null ? assignedToDev.AssignedTo : string.Empty
         });
     }
     if (workitem.PlannedQAEfforts == 0)
     {
         //get first QA
         var assignedToQA = workitem.Tasks.Where(p => p.Owner == TaskOwnerType.Tester).FirstOrDefault();
         workitem.Observations.Add(new Observation
         {
             Code       = "Lifecycle checklist",
             Title      = "QA estimates are missing.",
             AssignedTo = assignedToQA != null ? assignedToQA.AssignedTo : string.Empty
         });
     }
 }
示例#4
0
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     ValidateByrole(context, workitem, TaskOwnerType.Architect, "Architect code review");
     ValidateByrole(context, workitem, TaskOwnerType.Peer, "Peer code review");
     ValidateByrole(context, workitem, TaskOwnerType.Developer, "Development");
     ValidateByrole(context, workitem, TaskOwnerType.Tester, "Testing");
     ValidateByrole(context, workitem, TaskOwnerType.Team, "Generic");
 }
示例#5
0
 //check if current assigned person is developer
 private static string GetAssignedToIfDeveloper(TimeLogReportingServiceContext context, string assignedTo)
 {
     if (context.TeamProfiles != null && context.TeamProfiles.Count > 0)
     {
         if (context.TeamProfiles.Where(p => string.Compare(p.Fullname, assignedTo, true) == 0 && string.Compare(p.Role, TaskOwnerType.Developer.ToString(), true) == 0).Any())
         {
             return(assignedTo);
         }
     }
     return(string.Empty);
 }
示例#6
0
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     if (string.IsNullOrEmpty(workitem.DevelopmentTracking) == true)
     {
         workitem.Observations.Add(new Observation
         {
             Code       = "Lifecycle checklist",
             Title      = "Development Tracking value not set.",
             AssignedTo = workitem.AssignedTo
         });
     }
 }
示例#7
0
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     if (workitem.Tasks.Where(q => string.IsNullOrEmpty(q.AssignedTo) == true).Any())
     {
         workitem.Observations.Add(new Observation
         {
             Code       = "Mismatch",
             Title      = "There are one or more unassigned tasks created for this workitem.",
             AssignedTo = workitem.AssignedTo   //TODO: Logic to identify assignedTo
         });
     }
 }
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     if (workitem.Tasks == null || workitem.Tasks.Count == 0)
     {
         workitem.Observations.Add(new Observation
         {
             Code       = "Lifecycle checklist",
             Title      = "Tasks not created under this PBI",
             AssignedTo = workitem.AssignedTo
         });
     }
 }
        public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
        {
            var query = workitem.Tasks.Where(p => p.IterationPath != workitem.IterationPath);

            if (workitem.Tasks == null || query.Any())
            {
                Rolewise(workitem, query, TaskOwnerType.Architect, "architect code review");
                Rolewise(workitem, query, TaskOwnerType.Peer, "peer code review");
                Rolewise(workitem, query, TaskOwnerType.Developer, "development");
                Rolewise(workitem, query, TaskOwnerType.Tester, "testing");
                Rolewise(workitem, query, TaskOwnerType.Team, "generic");
            }
        }
        public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
        {
            if (string.Compare(workitem.Type, ProductBacklogItem, true) == 0)
            {
                var codeCompletionDate   = context.GetMilestone("Code Completion Date");
                var reviewCompletionDate = context.GetMilestone("Code Review Completion Date");
                var qaCompletionDate     = context.GetMilestone("QA Completion Date");

                ValidateCodeCompleteMilestone(workitem, codeCompletionDate);
                ValidateCodeReviewMilestone(workitem, reviewCompletionDate);
                ValidateQAMilestone(workitem, qaCompletionDate);
            }
        }
示例#11
0
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     if (string.Compare(workitem.Type, ProductBacklogItem, true) == 0)
     {
         if (string.Compare(workitem.State, "Committed", true) != 0 && string.Compare(workitem.State, "Done", true) != 0)
         {
             workitem.Observations.Add(new Observation
             {
                 Code       = "Lifecycle checklist",
                 Title      = "The PBI is not marked Committed or Done.",
                 AssignedTo = workitem.AssignedTo
             });
         }
     }
 }
示例#12
0
        private void ValidateByrole(TimeLogReportingServiceContext context, TimeLog workitem, TaskOwnerType taskowner, string taskTypes)
        {
            var teamMembers = context.TeamProfiles.Where(p => string.Compare(p.Role, taskowner.ToString(), true) == 0).Select(p => p.Fullname.ToLower()).ToList();

            workitem.Tasks.Where(p => p.Owner == taskowner).ToList().ForEach(p =>
            {
                if (teamMembers.Where(q => teamMembers.Contains(q.ToLower()) == false).Any())
                {
                    workitem.Observations.Add(new Observation
                    {
                        Code       = "Lifecycle checklist",
                        Title      = string.Format("One or more {0} tasks are not assigned to respective {1}s", taskTypes, taskowner),
                        AssignedTo = workitem.AssignedTo
                    });
                }
            });
        }
示例#13
0
        public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
        {
            if (workitem.ActualDevEfforts - workitem.Tasks.Where(p => p.Owner == TaskOwnerType.Developer).Sum(q => q.ActualDevEfforts) != 0)
            {
                workitem.Observations.Add(new Observation
                {
                    Code       = "Mismatch",
                    Title      = "Workitem and task level actual efforts (Dev) do not match.",
                    AssignedTo = GetOwnerName(workitem, TaskOwnerType.Developer)
                });
            }
            if (workitem.PlannedDevEfforts - workitem.Tasks.Where(p => p.Owner == TaskOwnerType.Developer).Sum(q => q.PlannedDevEfforts) != 0)
            {
                workitem.Observations.Add(new Observation
                {
                    Code       = "Mismatch",
                    Title      = "Workitem and task level planned efforts (Dev) do not match.",
                    AssignedTo = GetOwnerName(workitem, TaskOwnerType.Developer)
                });
            }

            //Note task level efforts for QA and Dev are all set in the DevEfforts fields
            if (workitem.ActualQAEfforts - workitem.Tasks.Where(p => p.Owner == TaskOwnerType.Tester).Sum(q => q.ActualDevEfforts) != 0)
            {
                workitem.Observations.Add(new Observation
                {
                    Code       = "Mismatch",
                    Title      = "Workitem and task level planned efforts (QA) do not match.",
                    AssignedTo = GetOwnerName(workitem, TaskOwnerType.Tester)
                });
            }

            if (workitem.PlannedQAEfforts - workitem.Tasks.Where(p => p.Owner == TaskOwnerType.Tester).Sum(q => q.PlannedDevEfforts) != 0)
            {
                workitem.Observations.Add(new Observation
                {
                    Code       = "Mismatch",
                    Title      = "Workitem and task level planned efforts (QA) do not match.",
                    AssignedTo = GetOwnerName(workitem, TaskOwnerType.Tester)
                });
            }
        }
        public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
        {
            const string PeerCodeReviewTaskTitle = "PEER CODE REVIEW";
            //get atleast one "PEER CODE REVIEW" task assigned to anyone
            var peerCodeReviewTasks = workitem.Tasks.Where(q => q.Title.ToUpper().IndexOf(PeerCodeReviewTaskTitle) >= 0).ToList();

            if (peerCodeReviewTasks.Count > 0)
            {
                peerCodeReviewTasks.ForEach(p => p.Owner = TaskOwnerType.Peer);
            }
            else
            {
                workitem.Observations.Add(new Observation
                {
                    Code       = "Lifecycle checklist",
                    Title      = "Peer code review task not created yet. Please contact respective peer.",
                    AssignedTo = workitem.AssignedTo   //TODO: Logic to identify peer reviewer
                });
            }
        }
        public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
        {
            const string FunctionalTestingTaskTitle = "FUNCTIONAL TESTING";
            //get atleast one "FUNCTIONAL TESTING" task assigned to anyone
            var testingTasks = workitem.Tasks.Where(q => q.Title.ToUpper().IndexOf(FunctionalTestingTaskTitle) >= 0).ToList();

            if (testingTasks.Count > 0)
            {
                testingTasks.ForEach(p => p.Owner = TaskOwnerType.Tester);
            }
            else
            {
                workitem.Observations.Add(new Observation
                {
                    Code       = "Lifecycle checklist",
                    Title      = "Functional testing task not created yet. Please contact respective QA",
                    AssignedTo = GetAssignedToIfTester(context, workitem.AssignedTo)
                });
            }
        }
        public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
        {
            var taskDoneButNoTimeQuery = workitem.Tasks.Where(q => q.IsTaskMarkedAsDone == true && q.ActualDevEfforts == 0 && q.Owner != TaskOwnerType.Team);

            if (taskDoneButNoTimeQuery.Any())
            {
                workitem.Observations.Add(new Observation
                {
                    Code  = "Mismatch",
                    Title = "There is atleast one task marked completed, but no time logged under it."
                });
                taskDoneButNoTimeQuery.ToList().ForEach(p =>
                {
                    p.Observations.Add(new Observation
                    {
                        Code       = "Mismatch",
                        Title      = string.Format("Task #{0} is marked completed but has no time logged under it.", p.WorkitemId),
                        AssignedTo = p.AssignedTo
                    });
                });
            }

            var incompleteTaskNoRemainingTimeQuery = workitem.Tasks.Where(q => q.RemainingWork == null && q.IsTaskMarkedAsDone == false);

            if (incompleteTaskNoRemainingTimeQuery.Any())
            {
                workitem.Observations.Add(new Observation
                {
                    Code  = "Lifecycle checklist",
                    Title = "Atleast one of the incomplete task is missing remaining work"
                });
                incompleteTaskNoRemainingTimeQuery.ToList().ForEach(p => {
                    p.Observations.Add(new Observation
                    {
                        Code       = "Lifecycle checklist",
                        Title      = string.Format("Task #{0} is incomplete but does not have remaining work", p.WorkitemId),
                        AssignedTo = p.AssignedTo
                    });
                });
            }
        }
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     if (string.Compare(workitem.Type, ProductBacklogItem, true) == 0)
     {
         const string TestcaseWritingTaskTitle = "TC WRITING";
         var          testingTasks             = workitem.Tasks.Where(q => q.Title.ToUpper().IndexOf(TestcaseWritingTaskTitle) >= 0).ToList();
         if (testingTasks.Count > 0)
         {
             testingTasks.ForEach(p => p.Owner = TaskOwnerType.Tester);
         }
         else
         {
             workitem.Observations.Add(new Observation
             {
                 Code       = "Lifecycle checklist",
                 Title      = "TC Writing task not created yet. Please contact respective QA",
                 AssignedTo = workitem.AssignedTo   //TODO: Logic to identify tester
             });
         }
     }
 }
示例#18
0
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     if (string.Compare(workitem.Type, Bug, true) == 0)
     {
         const string CodingTaskTitle = "CODING";
         var          unitTestTasks   = workitem.Tasks.Where(q => q.Title.ToUpper().IndexOf(CodingTaskTitle) >= 0).ToList();
         if (unitTestTasks.Count > 0)
         {
             unitTestTasks.ForEach(p => p.Owner = TaskOwnerType.Developer);
         }
         else
         {
             workitem.Observations.Add(new Observation
             {
                 Code       = "Lifecycle checklist",
                 Title      = "Coding task not created yet.",
                 AssignedTo = GetAssignedToIfDeveloper(context, workitem.AssignedTo)
             });
         }
     }
 }
示例#19
0
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     if (string.Compare(workitem.Type, ProductBacklogItem, true) == 0)
     {
         const string ArchitectReviewTaskTitle = "ARCHITECT CODE REVIEW";
         //get atleast one "ARCHITECT CODE REVIEW" task assigned to anyone
         var architectCodeReviewTasks = workitem.Tasks.Where(q => q.Title.ToUpper().IndexOf(ArchitectReviewTaskTitle) >= 0).ToList();
         if (architectCodeReviewTasks.Count > 0)
         {
             architectCodeReviewTasks.ForEach(p => p.Owner = TaskOwnerType.Architect);
         }
         else
         {
             workitem.Observations.Add(new Observation
             {
                 Code       = "Lifecycle checklist",
                 Title      = "Architect code review task not created yet. Please contact respective architect/Lead",
                 AssignedTo = workitem.AssignedTo   //TODO: Logic to identify architect
             });
         }
     }
 }
示例#20
0
 public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
 {
     if (string.Compare(workitem.Type, ProductBacklogItem, true) == 0)
     {
         const string UnitTestingTaskTitle = "UNIT TESTING";
         //get atleast one "UNIT TESTING" task assigned to ME
         var unitTestTasks = workitem.Tasks.Where(q => q.Title.ToUpper().IndexOf(UnitTestingTaskTitle) >= 0).ToList();
         if (unitTestTasks.Count > 0)
         {
             unitTestTasks.ForEach(p => p.Owner = TaskOwnerType.Developer);
         }
         else
         {
             workitem.Observations.Add(new Observation
             {
                 Code       = "Lifecycle checklist",
                 Title      = "Unit testing task not created yet.",
                 AssignedTo = workitem.AssignedTo
             });
         }
     }
 }
示例#21
0
        public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
        {
            var query = workitem.Tasks.Where(q => q.Title.StartsWith(workitem.WorkitemId.ToString()) == false);

            if (query.Any())
            {
                workitem.Observations.Add(new Observation
                {
                    Code  = "Naming convention",
                    Title = "At least one task title does not start with PBI number.",
                });

                query.ToList().ForEach(p =>
                {
                    p.Observations.Add(new Observation
                    {
                        Code       = "Naming convention",
                        Title      = string.Format("Title of task #{0} does not start with PBI number.", p.WorkitemId),
                        AssignedTo = p.AssignedTo
                    });
                });
            }
        }
示例#22
0
        public override void Analyze(TimeLogReportingServiceContext context, TimeLog workitem)
        {
            //development tasks
            var query = workitem.Tasks.Where(p => p.Owner == TaskOwnerType.Developer && string.Compare(p.Activity, "Development", true) != 0);

            if (query.Any())
            {
                workitem.Observations.Add(new Observation
                {
                    Code  = "Lifecycle checklist",
                    Title = "One or more developer tasks do not have the right \"Activity\" (Development)."
                });

                query.ToList().ForEach(p =>
                {
                    p.Observations.Add(new Observation
                    {
                        Code       = "Lifecycle checklist",
                        Title      = string.Format("Developer task #{0} does not have the right \"Activity\" (Development).", p.WorkitemId),
                        AssignedTo = p.AssignedTo,
                        WorkitemId = p.WorkitemId
                    });
                });
            }

            //QA tasks
            query = workitem.Tasks.Where(p => p.Owner == TaskOwnerType.Tester && string.Compare(p.Activity, "Testing", true) != 0);
            if (query.Any())
            {
                workitem.Observations.Add(new Observation
                {
                    Code  = "Lifecycle checklist",
                    Title = "One or more tester tasks do not have the right \"Activity\" (Testing)."
                });

                query.ToList().ForEach(p =>
                {
                    p.Observations.Add(new Observation
                    {
                        Code       = "Lifecycle checklist",
                        Title      = string.Format("Testing task #{0} does not have the right \"Activity\" (Testing).", p.WorkitemId),
                        AssignedTo = p.AssignedTo,
                        WorkitemId = p.WorkitemId
                    });
                });
            }

            //peer review task
            query = workitem.Tasks.Where(p => (p.Owner == TaskOwnerType.Peer) && string.Compare(p.Activity, "Design", true) != 0);
            if (query.Any())
            {
                workitem.Observations.Add(new Observation
                {
                    Code  = "Lifecycle checklist",
                    Title = "Peer review task does not have the right \"Activity\" (Design)."
                });
                query.ToList().ForEach(p =>
                {
                    p.Observations.Add(new Observation
                    {
                        Code       = "Lifecycle checklist",
                        Title      = string.Format("Peer review task #{0} does not have the right \"Activity\" (Design).", p.WorkitemId),
                        AssignedTo = p.AssignedTo,
                        WorkitemId = p.WorkitemId
                    });
                });
            }

            //architect review task
            query = workitem.Tasks.Where(p => (p.Owner == TaskOwnerType.Architect) && string.Compare(p.Activity, "Design", true) != 0);
            if (query.Any())
            {
                workitem.Observations.Add(new Observation
                {
                    Code  = "Lifecycle checklist",
                    Title = "Architect review task does not have the right \"Activity\" (Design)."
                });
                query.ToList().ForEach(p =>
                {
                    p.Observations.Add(new Observation
                    {
                        Code       = "Lifecycle checklist",
                        Title      = string.Format("Architect review task #{0} does not have the right \"Activity\" (Design).", p.WorkitemId),
                        AssignedTo = p.AssignedTo,
                        WorkitemId = p.WorkitemId
                    });
                });
            }
        }