Working sprint graph

remotes/origin/enhancement/email-actions
Jesús Espino 2013-11-05 10:45:50 +01:00
parent 53ae1d3b1b
commit e1454106af
2 changed files with 43 additions and 0 deletions

View File

@ -1,8 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.shortcuts import get_object_or_404
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import detail_route
from rest_framework.response import Response
from greenmine.base import filters from greenmine.base import filters
from greenmine.base import exceptions as exc from greenmine.base import exceptions as exc
@ -13,6 +16,8 @@ from . import serializers
from . import models from . import models
from . import permissions from . import permissions
import datetime
class MilestoneViewSet(NotificationSenderMixin, ModelCrudViewSet): class MilestoneViewSet(NotificationSenderMixin, ModelCrudViewSet):
model= models.Milestone model= models.Milestone
@ -37,3 +42,33 @@ class MilestoneViewSet(NotificationSenderMixin, ModelCrudViewSet):
super().pre_save(obj) super().pre_save(obj)
@detail_route(methods=['get'])
def stats(self, request, pk=None):
milestone = get_object_or_404(models.Milestone, pk=pk)
total_points = milestone.total_points
milestone_stats = {
'name': milestone.name,
'estimated_start': milestone.estimated_start,
'estimated_finish': milestone.estimated_finish,
'total_points': total_points,
'completed_points': milestone.closed_points.values(),
'total_userstories': milestone.user_stories.count(),
'completed_userstories': len([us for us in milestone.user_stories.all() if us.is_closed]),
'total_tasks': sum([us.tasks.count() for us in milestone.user_stories.all()]),
'completed_tasks': sum([us.tasks.filter(status__is_closed=True).count() for us in milestone.user_stories.all()]),
'days': []
}
current_date = milestone.estimated_start
optimal_points = sum(total_points.values())
optimal_points_per_day = sum(total_points.values()) / (milestone.estimated_finish - milestone.estimated_start).days
while current_date <= milestone.estimated_finish:
milestone_stats['days'].append({
'day': current_date,
'name': current_date.day,
'open_points': sum(total_points.values()) - sum(milestone.closed_points_by_date(current_date).values()),
'optimal_points': optimal_points,
})
current_date = current_date + datetime.timedelta(days=1)
optimal_points -= optimal_points_per_day
return Response(milestone_stats)

View File

@ -91,6 +91,10 @@ class Milestone(WatchedMixin):
dict_result[key] = value dict_result[key] = value
return dict_result return dict_result
@property
def total_points(self):
return self._get_user_stories_points([us for us in self.user_stories.all()])
@property @property
def closed_points(self): def closed_points(self):
return self._get_user_stories_points([us for us in self.user_stories.all() return self._get_user_stories_points([us for us in self.user_stories.all()
@ -147,6 +151,10 @@ class Milestone(WatchedMixin):
"project_owner": (self.project, self.project.owner), "project_owner": (self.project, self.project.owner),
} }
def closed_points_by_date(self, date):
return self._get_user_stories_points([us for us in self.user_stories.filter(finish_date__lte=date)
if us.is_closed])
# Reversion registration (usufull for base.notification and for meke a historical) # Reversion registration (usufull for base.notification and for meke a historical)
reversion.register(Milestone) reversion.register(Milestone)