diff --git a/taiga/users/api.py b/taiga/users/api.py index 860e5885..626e20b0 100644 --- a/taiga/users/api.py +++ b/taiga/users/api.py @@ -45,6 +45,7 @@ from . import models from . import serializers from . import permissions from . import filters as user_filters +from . import services from .signals import user_cancel_account as user_cancel_account_signal @@ -95,6 +96,12 @@ class UsersViewSet(ModelCrudViewSet): return response.Ok(serializer.data) + @detail_route(methods=["GET"]) + def stats(self, request, pk=None): + user = self.get_object() + self.check_permissions(request, "stats", user) + return response.Ok(services.get_stats_for_user(user)) + @list_route(methods=["POST"]) def password_recovery(self, request, pk=None): username_or_email = request.DATA.get('username', None) diff --git a/taiga/users/permissions.py b/taiga/users/permissions.py index 6a36ab4a..a8cbd8d9 100644 --- a/taiga/users/permissions.py +++ b/taiga/users/permissions.py @@ -35,6 +35,7 @@ class UserPermission(TaigaResourcePermission): update_perms = IsTheSameUser() destroy_perms = IsTheSameUser() list_perms = AllowAny() + stats_perms = AllowAny() password_recovery_perms = AllowAny() change_password_from_recovery_perms = AllowAny() change_password_perms = IsAuthenticated() diff --git a/taiga/users/services.py b/taiga/users/services.py index 99b8975d..d1f765bf 100644 --- a/taiga/users/services.py +++ b/taiga/users/services.py @@ -88,3 +88,27 @@ def get_big_photo_or_gravatar_url(user): return get_big_photo_url(user.photo) else: return get_gravatar_url(user.email, size=settings.DEFAULT_BIG_AVATAR_SIZE) + +def get_stats_for_user(user): + """Get the user stats""" + + project_ids = user.memberships.values_list("project__id", flat=True).distinct() + total_num_projects = project_ids.count() + roles = [_(r) for r in user.memberships.values_list("role__name", flat=True)] + roles = list(set(roles)) + User = apps.get_model('users', 'User') + total_num_contacts = User.objects.filter(memberships__project__id__in=project_ids)\ + .exclude(id=user.id)\ + .distinct()\ + .count() + + UserStory = apps.get_model('userstories', 'UserStory') + total_num_closed_userstories = UserStory.objects.filter(is_closed=True, assigned_to=user).count() + + project_stats = { + 'total_num_projects': total_num_projects, + 'roles': roles, + 'total_num_contacts': total_num_contacts, + 'total_num_closed_userstories': total_num_closed_userstories, + } + return project_stats