Adding member stats to the API

remotes/origin/enhancement/email-actions
Alejandro Alonso 2014-11-19 18:14:59 +01:00 committed by Jesús Espino
parent fa1e0c6bf6
commit e7b963a674
5 changed files with 142 additions and 0 deletions

View File

@ -80,6 +80,12 @@ class ProjectViewSet(ModelCrudViewSet):
self.check_permissions(request, 'stats', project)
return Response(services.get_stats_for_project(project))
@detail_route(methods=['get'])
def member_stats(self, request, pk=None):
project = self.get_object()
self.check_permissions(request, 'member_stats', project)
return Response(services.get_member_stats_for_project(project))
@detail_route(methods=['get'])
def issues_stats(self, request, pk=None):
project = self.get_object()

View File

@ -28,6 +28,7 @@ class ProjectPermission(TaigaResourcePermission):
modules_perms = IsProjectOwner()
list_perms = AllowAny()
stats_perms = AllowAny()
member_stats_perms = HasProjectPerm('view_project')
star_perms = IsAuthenticated()
unstar_perms = IsAuthenticated()
issues_stats_perms = AllowAny()

View File

@ -30,6 +30,7 @@ from .filters import get_issues_filters_data
from .stats import get_stats_for_project_issues
from .stats import get_stats_for_project
from .stats import get_member_stats_for_project
from .members import create_members_in_bulk
from .members import get_members_from_bulk

View File

@ -18,6 +18,8 @@ from django.db.models import Q, Count
import datetime
import copy
from taiga.projects.history.models import HistoryEntry
def _get_milestones_stats_for_backlog(project):
"""
@ -212,3 +214,77 @@ def get_stats_for_project(project):
'speed': speed,
}
return project_stats
def _get_closed_bugs_per_member_stats(project):
# Closed bugs per user
closed_bugs = project.issues.filter(status__is_closed=True)\
.values('assigned_to')\
.annotate(count=Count('assigned_to'))\
.order_by()
closed_bugs = { p["assigned_to"]: p["count"] for p in closed_bugs}
return closed_bugs
def _get_iocaine_tasks_per_member_stats(project):
# Iocaine tasks assigned per user
iocaine_tasks = project.tasks.filter(is_iocaine=True)\
.values('assigned_to')\
.annotate(count=Count('assigned_to'))\
.order_by()
iocaine_tasks = { t["assigned_to"]: t["count"] for t in iocaine_tasks}
return iocaine_tasks
def _get_wiki_changes_per_member_stats(project):
# Wiki changes
wiki_changes = {}
wiki_page_keys = ["wiki.wikipage:%s"%id for id in project.wiki_pages.values_list("id", flat=True)]
history_entries = HistoryEntry.objects.filter(key__in=wiki_page_keys).values('user')
for entry in history_entries:
editions = wiki_changes.get(entry["user"]["pk"], 0)
wiki_changes[entry["user"]["pk"]] = editions + 1
return wiki_changes
def _get_created_bugs_per_member_stats(project):
# Created_bugs
created_bugs = project.issues\
.values('owner')\
.annotate(count=Count('owner'))\
.order_by()
created_bugs = { p["owner"]: p["count"] for p in created_bugs }
return created_bugs
def _get_closed_tasks_per_member_stats(project):
# Closed tasks
closed_tasks = project.tasks.filter(status__is_closed=True)\
.values('assigned_to')\
.annotate(count=Count('assigned_to'))\
.order_by()
closed_tasks = {p["assigned_to"]: p["count"] for p in closed_tasks}
return closed_tasks
def get_member_stats_for_project(project):
base_counters = {id: 0 for id in project.members.values_list("id", flat=True)}
closed_bugs = base_counters.copy()
closed_bugs.update(_get_closed_bugs_per_member_stats(project))
iocaine_tasks = base_counters.copy()
iocaine_tasks.update(_get_iocaine_tasks_per_member_stats(project))
wiki_changes = base_counters.copy()
wiki_changes.update(_get_wiki_changes_per_member_stats(project))
created_bugs = base_counters.copy()
created_bugs.update(_get_created_bugs_per_member_stats(project))
closed_tasks = base_counters.copy()
closed_tasks.update(_get_closed_tasks_per_member_stats(project))
member_stats = {
"closed_bugs": closed_bugs,
"iocaine_tasks": iocaine_tasks,
"wiki_changes": wiki_changes,
"created_bugs": created_bugs,
"closed_tasks": closed_tasks,
}
return member_stats

View File

@ -1,5 +1,7 @@
from django.core.urlresolvers import reverse
from taiga.base.utils import json
from taiga.projects.services import stats as stats_services
from taiga.projects.history.services import take_snapshot
from .. import factories as f
@ -84,6 +86,7 @@ def test_issue_status_slug_generation(client):
assert response.status_code == 200
assert response.data["slug"] == "new-status"
def test_points_name_duplicated(client):
point_1 = f.PointsFactory()
point_2 = f.PointsFactory(project=point_1.project)
@ -96,9 +99,64 @@ def test_points_name_duplicated(client):
assert response.status_code == 400
assert response.data["name"][0] == "Name duplicated for the project"
def test_update_points_when_not_null_values_for_points(client):
points = f.PointsFactory(name="?", value="6")
role = f.RoleFactory(project=points.project, computable=True)
assert points.project.points.filter(value__isnull=True).count() == 0
points.project.update_role_points()
assert points.project.points.filter(value__isnull=True).count() == 1
def test_get_closed_bugs_per_member_stats():
project = f.ProjectFactory()
membership_1 = f.MembershipFactory(project=project)
membership_2 = f.MembershipFactory(project=project)
issue_closed_status = f.IssueStatusFactory(is_closed=True, project=project)
issue_open_status = f.IssueStatusFactory(is_closed=False, project=project)
issue_closed = f.IssueFactory(project=project,
status=issue_closed_status,
owner=membership_1.user,
assigned_to=membership_1.user)
issue_open = f.IssueFactory(project=project,
status=issue_open_status,
owner=membership_2.user,
assigned_to=membership_2.user)
task_closed_status = f.TaskStatusFactory(is_closed=True, project=project)
task_open_status = f.TaskStatusFactory(is_closed=False, project=project)
task_closed = f.TaskFactory(project=project,
status=task_closed_status,
owner=membership_1.user,
assigned_to=membership_1.user)
task_open = f.TaskFactory(project=project,
status=task_open_status,
owner=membership_2.user,
assigned_to=membership_2.user)
task_iocaine = f.TaskFactory(project=project,
status=task_open_status,
owner=membership_2.user,
assigned_to=membership_2.user,
is_iocaine=True)
wiki_page = f.WikiPageFactory.create(project=project, owner=membership_1.user)
take_snapshot(wiki_page, user=membership_1.user)
wiki_page.content="Frontend, future"
wiki_page.save()
take_snapshot(wiki_page, user=membership_1.user)
stats = stats_services.get_member_stats_for_project(project)
assert stats["closed_bugs"][membership_1.user.id] == 1
assert stats["closed_bugs"][membership_2.user.id] == 0
assert stats["iocaine_tasks"][membership_1.user.id] == 0
assert stats["iocaine_tasks"][membership_2.user.id] == 1
assert stats["wiki_changes"][membership_1.user.id] == 2
assert stats["wiki_changes"][membership_2.user.id] == 0
assert stats["created_bugs"][membership_1.user.id] == 1
assert stats["created_bugs"][membership_2.user.id] == 1
assert stats["closed_tasks"][membership_1.user.id] == 1
assert stats["closed_tasks"][membership_2.user.id] == 0