コード例 #1
0
        private static List <StoryCountProgessItem> GetAllStoryProgressData()
        {
            var currentSprint = App.GetReleaseScrumData().CurrentSprintProxy.CurrentSprint;
            var result        = new List <StoryCountProgessItem>();

            foreach (var story in currentSprint.Stories)
            {
                var engName       = NameUtil.ConvertToEngName(story.Owner);
                var currentPerson = result.FirstOrDefault(t => t.Name == engName);
                if (currentPerson == null)
                {
                    currentPerson = new StoryCountProgessItem()
                    {
                        Name = engName
                    };
                    result.Add(currentPerson);
                }

                currentPerson.Total++;
                if (story.IsComplete())
                {
                    currentPerson.Left++;
                }
            }

            return(result.OrderBy(t => t.Name).ToList());
        }
コード例 #2
0
        public static Dictionary <string, int> TaskWallOfPersonTasks()
        {
            var personToTaskCount = new Dictionary <string, int>();
            var currentSprint     = App.GetReleaseScrumData().CurrentSprintProxy.GetInCompleteTasks();

            foreach (var task in currentSprint)
            {
                string engName = NameUtil.ConvertToEngName(task.Owner);
                if (!personToTaskCount.ContainsKey(engName))
                {
                    personToTaskCount[engName] = 1;
                }
                else
                {
                    personToTaskCount[engName]++;
                }
            }

            foreach (var task in App.GetReleaseScrumData().CurrentSprintProxy.GetCompletedTasks())
            {
                string engName = NameUtil.ConvertToEngName(task.Owner);
                if (!personToTaskCount.ContainsKey(engName))
                {
                    personToTaskCount[engName] = 0;
                }
            }

            return(personToTaskCount);
        }
コード例 #3
0
ファイル: SprintProxy.cs プロジェクト: yuanzhitang/Trend
        private void AnalyzeStoryTaskWithException()
        {
            foreach (var story in CurrentSprint.GetUnCompletedStories())
            {
                var     errorDesc = string.Empty;
                var     errorType = string.Empty;
                var     errorImg  = string.Empty;
                decimal diffDesc  = 0;

                if (IsSizeMismatch(story, ref errorType, ref errorDesc, ref errorImg, ref diffDesc))
                {
                    var exItem = new ExceptionItem()
                    {
                        Owner             = NameUtil.ConvertToEngName(story.Owner),
                        Item              = story.Type + " " + story.ID + " " + story.Title,
                        ExceptionCategory = errorType,
                        ExceptionImg      = errorImg,
                        ExceptionDetail   = errorDesc,
                        Diff              = diffDesc
                    };
                    StoriesInException.Add(exItem);
                }

                foreach (var task in story.GetInCompleteTasks())
                {
                    if (NameUtil.ConvertToEngName(task.Owner) == NameUtil.NoOwner)
                    {
                        var exItem = new ExceptionItem()
                        {
                            Owner             = NameUtil.ConvertToEngName(task.Owner),
                            Item              = "Task " + task.ID + " " + task.Description,
                            ExceptionCategory = "No Owner",
                            ExceptionImg      = "No Owner",
                            ExceptionDetail   = "This task has no owner. It belongs to " + story.Type + " " + story.GetBreifDesc()
                        };
                        TasksInException.Add(exItem);
                    }
                    else if (task.Estimate == 0)
                    {
                        var exItem = new ExceptionItem()
                        {
                            Owner             = NameUtil.ConvertToEngName(task.Owner),
                            Item              = "Task " + task.ID + " " + task.Description,
                            ExceptionCategory = "This task's estimation is 0",
                            ExceptionImg      = "Zero",
                            ExceptionDetail   = "This task's estimation is 0. It belongs to " + story.Type + " " + story.GetBreifDesc()
                        };
                        TasksInException.Add(exItem);
                    }
                }

                //Michael Task or Story size is 0/
            }
        }
コード例 #4
0
        public static List <TaskWallOfStory> GetTaskWallOfStorySummary(string personName)
        {
            var result = new List <TaskWallOfStory>();

            foreach (var story in App.GetReleaseScrumData().CurrentSprintProxy.CurrentSprint.Stories)
            {
                var storyItem = new TaskWallOfStory();

                var englishName = NameUtil.ConvertToEngName(story.Owner);
                if (string.IsNullOrEmpty(personName) || englishName == personName)
                {
                    storyItem.Story = story;
                    storyItem.Tasks = new List <TaskWallOfTask>();

                    foreach (var task in story.Tasks)
                    {
                        var taskItem = new TaskWallOfTask();
                        taskItem.Task = task;
                        //var progress = $"size:{task.WorkDone + task.WorkToDo}";
                        int percent = 100;
                        if (!task.IsComplete())
                        {
                            if ((task.WorkDone + task.WorkToDo) != 0)
                            {
                                percent = (int)((task.WorkDone / (task.WorkDone + task.WorkToDo)) * 100);
                            }
                        }

                        taskItem.Percent = percent;

                        storyItem.Tasks.Add(taskItem);


                        //var englishName = NameUtil.ConvertToEngName(currentTask.Owner);

                        //if (string.IsNullOrEmpty(personName) || personName == englishName)
                        //{
                        //	taskDetail.Add(string.Format(taskDetailFormat, "#" + currentTask.ID, englishName, currentTask.Description, progress, percent, colorSetting.Item1, colorSetting.Item2));
                        //}
                    }

                    result.Add(storyItem);
                }
            }

            return(result);
        }
コード例 #5
0
ファイル: SprintProxy.cs プロジェクト: yuanzhitang/Trend
        private void AnalyzeHighRiskForPersonByTask()
        {
            Dictionary <string, List <UTrackTask> > personToTasks    = new Dictionary <string, List <UTrackTask> >();
            Dictionary <string, List <decimal> >    personToWorkToDo = new Dictionary <string, List <decimal> >();

            foreach (var story in Stories)
            {
                foreach (var task in story.Tasks)
                {
                    string ownerEngName = NameUtil.ConvertToEngName(task.Owner);

                    if (!personToWorkToDo.ContainsKey(ownerEngName))
                    {
                        personToWorkToDo[ownerEngName] = new List <decimal>();
                        personToTasks[ownerEngName]    = new List <UTrackTask>();
                    }

                    personToWorkToDo[ownerEngName].Add(task.WorkToDo);
                    personToTasks[ownerEngName].Add(task);
                }
            }

            int availableDays = DateTimeUtil.GetWorkingDays(DateTime.Now, CurrentSprint.EndTime);

            foreach (var item in personToWorkToDo)
            {
                decimal totalWorkToDoInDays = 0;
                item.Value.ForEach(t => totalWorkToDoInDays += t);
                totalWorkToDoInDays = totalWorkToDoInDays / 8;

                if (totalWorkToDoInDays > availableDays)
                {
                    string errorDesc       = $"This member has a total of {item.Value.Count} task(s). They still need {totalWorkToDoInDays} day(s), but there are only {availableDays} day(s) left in the sprint";
                    var    owningTasks     = personToTasks[item.Key].Select(t => t.Type + " " + t.ID + " " + t.Description + " - Size:" + t.Estimate);
                    var    persionRiskItem = new PersonRiskItem()
                    {
                        Owner = item.Key, ExceedDay = totalWorkToDoInDays - availableDays, OwningStories = string.Join("\n", owningTasks), RiskDetail = errorDesc
                    };
                    if (!HighRiskPersons.Any(t => t.Owner == persionRiskItem.Owner))
                    {
                        HighRiskPersons.Add(persionRiskItem);
                    }
                }
            }
        }
コード例 #6
0
ファイル: SprintProxy.cs プロジェクト: yuanzhitang/Trend
        private void InitAllMembers()
        {
            foreach (var story in Stories)
            {
                string engName = NameUtil.ConvertToEngName(story.Owner);
                if (!Members.Contains(engName))
                {
                    Members.Add(engName);
                }

                foreach (var tsk in story.Tasks)
                {
                    engName = NameUtil.ConvertToEngName(tsk.Owner);
                    if (!Members.Contains(engName))
                    {
                        Members.Add(engName);
                    }
                }
            }
        }
コード例 #7
0
ファイル: AwardAnalyzer.cs プロジェクト: yuanzhitang/Trend
        public static IEnumerable <string> GetPersonOfWarrior()
        {
            var appData = App.GetReleaseScrumData();

            var currentSprint    = appData.ReleaseData.CurrentSprint;
            var personToWorkDone = new Dictionary <string, decimal>();

            foreach (var story in currentSprint.Stories)
            {
                foreach (var task in story.Tasks.Where(tsk => tsk.WorkDone != 0))
                {
                    var engName       = NameUtil.ConvertToEngName(task.Owner);
                    var currentPerson = personToWorkDone.FirstOrDefault(t => t.Key == engName);
                    if (!personToWorkDone.ContainsKey(engName))
                    {
                        personToWorkDone.Add(engName, task.WorkDone);
                    }
                    else
                    {
                        personToWorkDone[engName] += task.WorkDone;
                    }
                }
            }

            personToWorkDone = personToWorkDone.OrderByDescending(t => t.Value).ToDictionary(t => t.Key, v => v.Value);

            if (personToWorkDone.Count > 3)
            {
                return(personToWorkDone.Take(2).Select(t => t.Key));
            }
            else if (personToWorkDone.Count > 1)
            {
                return(new List <string> {
                    personToWorkDone.First().Key
                });
            }
            else
            {
                return(new List <string>());
            }
        }
コード例 #8
0
ファイル: SprintProxy.cs プロジェクト: yuanzhitang/Trend
        private StoryProgressItem GetStoryProgress(Story story)
        {
            var progressItem = new StoryProgressItem();

            progressItem.StoryType = story.Type.ToString();
            progressItem.StoryDesc = story.GetDesc();
            progressItem.Owner     = NameUtil.ConvertToEngName(story.Owner);
            decimal totalWorkDone = GetTotalStoryWorkDoInHours(story);
            decimal totalWorkToDo = GetTotalStoryWorkToDoInHours(story);

            if ((totalWorkToDo + totalWorkDone) == 0)
            {
                progressItem.Progress = 0;
            }
            else
            {
                progressItem.Progress = (int)((totalWorkDone / (totalWorkToDo + totalWorkDone)) * 100);
            }

            return(progressItem);
        }
コード例 #9
0
        //private static List<CurrentSprintProxy> sprintProxyList = new List<CurrentSprintProxy>();

        // GET: Statistics
        public ActionResult Index()
        {
            var appData = App.GetReleaseScrumData();
            //foreach (var sprint in appData.Item1.Sprints)
            //{
            //	var sprintProxy = new CurrentSprintProxy() { CurrentSprint = sprint };
            //	sprintProxy.AnalyzeCompletedStory();
            //	sprintProxy.AnalyzeFailedStory();

            //	sprintProxyList.Add(sprintProxy);
            //}

            Dictionary <string, List <Story> > personToStories = new Dictionary <string, List <Story> >();

            foreach (var sprint in appData.ReleaseData.Sprints)
            {
                foreach (var story in sprint.Stories.Where(t => t.IsComplete()))
                {
                    if (NameUtil.InValidNames.Contains(story.Owner))
                    {
                        continue;
                    }

                    var engName = NameUtil.ConvertToEngName(story.Owner);
                    if (!personToStories.ContainsKey(engName))
                    {
                        personToStories[engName] = new List <Story>();
                        personToStories[engName].Add(story);
                    }
                    else
                    {
                        personToStories[engName].Add(story);
                    }
                }
            }

            personToStories = personToStories.OrderByDescending(t => t.Value.Count).ToDictionary(p => p.Key, o => o.Value);
            return(View(personToStories));
        }
コード例 #10
0
ファイル: SprintProxy.cs プロジェクト: yuanzhitang/Trend
        private void AnalyzeHighRiskForPersonByStory()
        {
            Dictionary <string, List <Story> >   personToStories  = new Dictionary <string, List <Story> >();
            Dictionary <string, List <decimal> > personToWorkToDo = new Dictionary <string, List <decimal> >();

            foreach (var story in CurrentSprint.GetUnCompletedStories())
            {
                string ownerEngName = NameUtil.ConvertToEngName(story.Owner);

                if (!personToWorkToDo.ContainsKey(ownerEngName))
                {
                    personToWorkToDo[ownerEngName] = new List <decimal>();
                    personToStories[ownerEngName]  = new List <Story>();
                }

                personToWorkToDo[ownerEngName].Add(GetTotalStoryWorkToDo(story));
                personToStories[ownerEngName].Add(story);
            }

            int availableDays = DateTimeUtil.GetWorkingDays(DateTime.Now, CurrentSprint.EndTime);

            foreach (var item in personToWorkToDo)
            {
                decimal totalWorkToDoInDays = 0;
                item.Value.ForEach(t => totalWorkToDoInDays += t);

                if (totalWorkToDoInDays > availableDays)
                {
                    string errorDesc       = $"This member has a total of {item.Value.Count} story/stories.They still need {totalWorkToDoInDays} day(s), but there are only {availableDays} day(s) left in the sprint.";
                    var    ownerStories    = personToStories[item.Key].Select(t => t.Type + " " + t.ID + " " + t.Title + "- Size:" + t.Size);
                    var    persionRiskItem = new PersonRiskItem()
                    {
                        Owner = item.Key, ExceedDay = totalWorkToDoInDays - availableDays, OwningStories = string.Join("\n", ownerStories), RiskDetail = errorDesc
                    };
                    HighRiskPersons.Add(persionRiskItem);
                }
            }
        }
コード例 #11
0
ファイル: SprintProxy.cs プロジェクト: yuanzhitang/Trend
 public void AnalyzePersonTasks()
 {
     PersonTasks.Clear();
     foreach (var story in Stories)
     {
         foreach (var task in story.Tasks)
         {
             var engName       = NameUtil.ConvertToEngName(task.Owner);
             var currentPerson = PersonTasks.FirstOrDefault(t => t.Name == engName);
             if (currentPerson == null)
             {
                 PersonTasks.Add(new TaskSizeProgressItem()
                 {
                     Name = engName, Total = task.Estimate, Left = task.WorkToDo
                 });
             }
             else
             {
                 currentPerson.Total += task.Estimate;
                 currentPerson.Left  += task.WorkToDo;
             }
         }
     }
 }
コード例 #12
0
        public static List <List <TaskWallOfTask> > GetTaskWallOfTaskSummary(string personName)
        {
            var listOfFourItem = new List <List <TaskWallOfTask> >();

            var result = new List <TaskWallOfTask>();

            var appData            = App.GetReleaseScrumData();
            var AllInCompletedTask = App.GetReleaseScrumData().CurrentSprintProxy.GetInCompleteTasks();
            var AllCompletedTasks  = App.GetReleaseScrumData().CurrentSprintProxy.GetCompletedTasks();

            var taskDetail = new List <string>();

            foreach (var currentTask in AllInCompletedTask.OrderBy(t => t.Owner))
            {
                //var colorSetting = GetColorSetting(currentTask.Owner);
                var englishName = NameUtil.ConvertToEngName(currentTask.Owner);

                if (string.IsNullOrEmpty(personName) || personName == englishName)
                {
                    var progress = $"size:{currentTask.WorkDone + currentTask.WorkToDo}";
                    int percent  = 100;
                    if ((currentTask.WorkDone + currentTask.WorkToDo) != 0)
                    {
                        percent = (int)((currentTask.WorkDone / (currentTask.WorkDone + currentTask.WorkToDo)) * 100);
                    }

                    result.Add(new TaskWallOfTask()
                    {
                        Task    = currentTask,
                        Percent = percent,
                    });
                }
            }

            foreach (var currentTask in AllCompletedTasks.OrderBy(t => t.Owner))
            {
                var englishName = NameUtil.ConvertToEngName(currentTask.Owner);

                if (string.IsNullOrEmpty(personName) || personName == englishName)
                {
                    result.Add(new TaskWallOfTask()
                    {
                        Task    = currentTask,
                        Percent = 100,
                    });
                }
            }

            var listItem = new List <TaskWallOfTask>();

            foreach (var task in result)
            {
                listItem.Add(task);
                if (listItem.Count == 4)
                {
                    listOfFourItem.Add(listItem);

                    listItem = new List <TaskWallOfTask>();
                }
            }

            if (listItem.Any())
            {
                listOfFourItem.Add(listItem);
            }

            return(listOfFourItem);
        }
コード例 #13
0
        private IEnumerable <PersonActivityItem> AnalyzeSprintDiff(Sprint current, Sprint last)
        {
            var result = new List <PersonActivityItem>();

            foreach (var story in current.Stories)
            {
                if (last.Stories.Any(t => t.ID == story.ID))
                {
                    var    oldStory = last.Stories.First(t => t.ID == story.ID);
                    string detail   = string.Empty;
                    if (AnalyzeStoryDiff(story, oldStory, ref detail))
                    {
                        result.Add(new PersonActivityItem()
                        {
                            Time     = DateTime.Now,
                            Name     = NameUtil.ConvertToEngName(story.ModifiedOwner),
                            Activity = $"Updated story:{story.GetBreifDesc()}{Breakline}{detail}",
                            Sprint   = current.Name
                        });
                    }

                    foreach (var task in story.Tasks)
                    {
                        var lastTask = oldStory.Tasks.FirstOrDefault(t => t.ID == task.ID);
                        if (lastTask == null)
                        {
                            result.Add(new PersonActivityItem()
                            {
                                Time     = task.Created,
                                Name     = string.IsNullOrEmpty(task.CreatedOwner) ? NameUtil.ConvertToEngName(task.CreatedOwner) : NameUtil.ConvertToEngName(task.ModifiedOwner),
                                Activity = $"Created new Task:{task.ID}-{task.Description}",
                                Sprint   = current.Name
                            });
                        }
                        else
                        {
                            string detailOfTaskDiff = string.Empty;
                            if (AnalyzeTaskDiff(task, lastTask, ref detailOfTaskDiff))
                            {
                                result.Add(new PersonActivityItem()
                                {
                                    Time     = DateTime.Now,
                                    Name     = NameUtil.ConvertToEngName(task.ModifiedOwner),
                                    Activity = $"Updated task:{task.ID}-{task.Description}{Breakline}{detailOfTaskDiff}",
                                    Sprint   = current.Name
                                });
                            }
                        }
                    }
                }
                else
                {
                    if (DateTime.Now.Subtract(story.Created).Days == 0)
                    {
                        result.Add(new PersonActivityItem()
                        {
                            Time     = DateTime.Now,
                            Name     = NameUtil.ConvertToEngName(story.CreatedOwner),
                            Activity = $"Created new story:{story.GetBreifDesc()}",
                            Sprint   = current.Name
                        });
                    }
                }
            }

            return(result);
        }
コード例 #14
0
ファイル: SprintProxy.cs プロジェクト: yuanzhitang/Trend
        public List <ActivityItem> GetRecentActivity()
        {
            RecentActivities.Clear();

            foreach (var story in Stories)
            {
                var engName = NameUtil.ConvertToEngName(story.ModifiedOwner);

                var existedOne = RecentActivities.FirstOrDefault(t => t.Name == engName);

                if (existedOne == null)
                {
                    RecentActivities.Add(new ActivityItem()
                    {
                        Name         = engName,
                        ModifiedTime = story.Modified,
                        EventObject  = story.Type + " " + story.ID + " " + story.Title
                    });
                }
                else
                {
                    if (story.Modified > existedOne.ModifiedTime)
                    {
                        existedOne.ModifiedTime = story.Modified;
                        existedOne.EventObject  = story.Type + " " + story.ID + " " + story.Title;
                    }
                }

                foreach (var tsk in story.Tasks)
                {
                    engName = NameUtil.ConvertToEngName(tsk.ModifiedOwner);

                    existedOne = RecentActivities.FirstOrDefault(t => t.Name == engName);

                    if (existedOne == null)
                    {
                        RecentActivities.Add(new ActivityItem()
                        {
                            Name         = engName,
                            ModifiedTime = tsk.Modified,
                            EventObject  = tsk.Type + " " + tsk.ID + " " + tsk.Description
                        });
                    }
                    else
                    {
                        if (tsk.Modified > existedOne.ModifiedTime)
                        {
                            existedOne.ModifiedTime = tsk.Modified;
                            existedOne.EventObject  = tsk.Type + " " + tsk.ID + " " + tsk.Description;
                        }
                    }
                }
            }

            RecentActivities = RecentActivities.OrderByDescending(t => t.ModifiedTime).ToList();
            RecentActivities.ForEach(activity =>
            {
                int subDays               = DateTimeUtil.GetSubstractDays(activity.ModifiedTime);
                int subWorkingDays        = DateTimeUtil.GetSubstractWorkingDays(activity.ModifiedTime);
                activity.ReadableDateTime = activity.GetReadableDateTimeText(subDays);
                if (subWorkingDays > 4)
                {
                    activity.StatusImg = "Deep Sleep";
                }
                else if (subWorkingDays > 1)
                {
                    var recentActivity = App.CurrentSprintActivity.Items.FirstOrDefault(t => t.Name == activity.Name);
                    if (recentActivity != null)
                    {
                        subWorkingDays = DateTimeUtil.GetSubstractWorkingDays(recentActivity.Time);
                        if (subWorkingDays <= 2)
                        {
                            //Updated uTrack yesterday, if we calculate this working days today, the subworkingday is 2
                            activity.StatusImg = "work";
                        }
                        else
                        {
                            activity.StatusImg = "sleep";
                        }
                    }
                    else
                    {
                        activity.StatusImg = "work";
                    }
                }
                else
                {
                    activity.StatusImg = "work";
                }

                var personTasks = PersonTasks.FirstOrDefault(t => t.Name == activity.Name);
                if (personTasks != null && personTasks.Left == 0)
                {
                    activity.StatusImg = "Free";
                }
            });

            return(RecentActivities);
        }