def _group_sprints_by_milestone(self, req, milestones_to_show): """ Returns a dict which holds the sprints grouped by milestone (key: milestone, value: list of tuples (sprint, progress bar data)). The dict contains only sprints for milestones in milestones_to_show. """ # save sprints in dictionary, key is the associated milestone provider = DefaultTicketGroupStatsProvider(self.env) milestone_names = [milestone.name for milestone in milestones_to_show] sprints = {} sp_controller = SprintController(self.env) list_sprints = SprintController.ListSprintsCommand(self.env, criteria={'milestone': 'in %s' % \ milestone_names}) for s in sp_controller.process_command(list_sprints): # milestone_name = sprint.milestone # if (not milestone_name) or (milestone_name not in milestone_names): # continue milestone_name = s.milestone if milestone_name not in sprints: sprints[milestone_name] = [] sprint_stats = self.build_sprint_story_statistics(req, s.name, provider=provider) sprint_data = (s, sprint_stats) sprints[milestone_name].append(sprint_data) return sprints
def _prepare_links(self, req, name, milestone): """Prepares the links for the navigation bar""" list_sprints = SprintController.ListSprintsCommand( self.env, criteria={'milestone': name}) sprints = self.controller.process_command(list_sprints) for i, s in enumerate(sprints): s = s['sprint'] if s['name'] == name: if i > 0: add_link(req, 'prev', self.href(sprints[i - 1]['sprint']['name'])) if i < len(sprints) - 1: add_link(req, 'next', self.href(sprints[i + 1]['sprint']['name'])) break # add back link to Milestone if milestone: add_link(req, 'up', req.href.milestone(milestone), 'Milestone') prevnext_nav(req, 'Sprint', 'Milestone')
def prepare_data(self, req, args, data=None): """Returns the sprint visualization data""" if not args: raise TracError("You should provide at least a sprint name: ", args) # Assuming there is a sprint name name = args.get('name') if data is None: data = {} # avoid circular import from agilo.scrum.backlog.web_ui import NewBacklogView data.update({ 'may_edit_sprint': Action.SPRINT_EDIT in req.perm, # show a deletion confirmation if user wanted to delete 'delete_confirmation': 'delete' in req.args, 'close_confirmation': 'close' in req.args, 'edit_form_action': req.href(SprintEditView.url, name, 'edit'), 'confirm_form_action': req.href(SprintConfirmView.url, name, 'confirm'), 'sprint_backlog_link': req.href(NewBacklogView.url, Key.SPRINT_BACKLOG, name) }) list_sprints = \ SprintController.ListSprintsCommand(self.env, criteria={'name': '!=%s' % name}) data['sprints'] = [s.name for s in \ self.controller.process_command(list_sprints)] # Generate the date converter function for this timezone convert_date = view.generate_converter(req.tz) get_sprint = SprintController.GetSprintCommand(self.env, sprint=name) sprint = self.controller.process_command(get_sprint) # update the sprint dates sprint.start = convert_date(sprint.start) sprint.end = convert_date(sprint.end) # update the data with the Sprint info data.update({'sprint': sprint}) # now get the sprint ticket statistics cmd_stats = SprintController.GetTicketsStatisticsCommand(self.env, sprint=name, totals=True) nr_new, nr_planned, nr_closed = self.controller.process_command( cmd_stats) data['planned_tickets'] = nr_new data['in_progres_tickets'] = nr_planned data['open_tickets'] = nr_new + nr_planned data['closed_tickets'] = nr_closed rm = AgiloRoadmapModule(self.env) data['sprint_stats'] = rm.build_sprint_story_statistics(req, name) sprint_dates = { 'start': sprint.start, 'end': sprint.end, 'duration': sprint.duration } if sprint.is_closed: data['date_info'] = "Ended the %(end)s. Duration %(duration)s days (started the %(start)s)" % \ sprint_dates elif sprint.is_currently_running: data['date_info'] = "Started the %(start)s, ends on the %(end)s." % \ sprint_dates else: data['date_info'] = "Starts the %(start)s. Duration %(duration)s days, ends on the %(end)s" % \ sprint_dates return data