diff --git a/taiga/projects/history/mixins.py b/taiga/projects/history/mixins.py index 14a0f44d..2e058879 100644 --- a/taiga/projects/history/mixins.py +++ b/taiga/projects/history/mixins.py @@ -20,6 +20,9 @@ import warnings from .services import take_snapshot from taiga.projects.notifications import services as notifications_services +from taiga.base.api import serializers +from taiga.base.fields import MethodField + class HistoryResourceMixin(object): """ @@ -77,3 +80,11 @@ class HistoryResourceMixin(object): def pre_delete(self, obj): self.persist_history_snapshot(obj, delete=True) super().pre_delete(obj) + + +class TotalCommentsSerializerMixin(serializers.LightSerializer): + total_comments = MethodField() + + def get_total_comments(self, obj): + # The "total_comments" attribute is attached in the get_queryset of the viewset. + return getattr(obj, "total_comments", 0) or 0 diff --git a/taiga/projects/history/utils.py b/taiga/projects/history/utils.py new file mode 100644 index 00000000..a273f748 --- /dev/null +++ b/taiga/projects/history/utils.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2014-2016 Andrey Antukh +# Copyright (C) 2014-2016 Jesús Espino +# Copyright (C) 2014-2016 David Barragán +# Copyright (C) 2014-2016 Alejandro Alonso +# Copyright (C) 2014-2016 Anler Hernández +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from taiga.projects.history.services import get_typename_for_model_class + + +def attach_total_comments_to_queryset(queryset, as_field="total_comments"): + """Attach a total comments counter to each object of the queryset. + + :param queryset: A Django projects queryset object. + :param as_field: Attach the counter as an attribute with this name. + + :return: Queryset object with the additional `as_field` field. + """ + model = queryset.model + sql = """ + SELECT COUNT(history_historyentry.id) + FROM history_historyentry + WHERE history_historyentry.key = CONCAT('{key_prefix}', {tbl}.id) AND + history_historyentry.comment is not null AND + history_historyentry.comment != '' + """ + + typename = get_typename_for_model_class(model) + + sql = sql.format(tbl=model._meta.db_table, key_prefix="{}:".format(typename)) + + queryset = queryset.extra(select={as_field: sql}) + return queryset diff --git a/taiga/projects/tasks/serializers.py b/taiga/projects/tasks/serializers.py index f0621581..c1fca652 100644 --- a/taiga/projects/tasks/serializers.py +++ b/taiga/projects/tasks/serializers.py @@ -28,11 +28,13 @@ from taiga.projects.mixins.serializers import StatusExtraInfoSerializerMixin from taiga.projects.notifications.mixins import WatchedResourceSerializer from taiga.projects.tagging.serializers import TaggedInProjectResourceSerializer from taiga.projects.votes.mixins.serializers import VoteResourceSerializerMixin +from taiga.projects.history.mixins import TotalCommentsSerializerMixin class TaskListSerializer(VoteResourceSerializerMixin, WatchedResourceSerializer, OwnerExtraInfoSerializerMixin, AssignedToExtraInfoSerializerMixin, StatusExtraInfoSerializerMixin, BasicAttachmentsInfoSerializerMixin, - TaggedInProjectResourceSerializer, serializers.LightSerializer): + TaggedInProjectResourceSerializer, TotalCommentsSerializerMixin, + serializers.LightSerializer): id = Field() user_story = Field(attr="user_story_id") diff --git a/taiga/projects/tasks/utils.py b/taiga/projects/tasks/utils.py index 0d8661fc..d06f96e3 100644 --- a/taiga/projects/tasks/utils.py +++ b/taiga/projects/tasks/utils.py @@ -23,6 +23,7 @@ from taiga.projects.notifications.utils import attach_total_watchers_to_queryset from taiga.projects.notifications.utils import attach_is_watcher_to_queryset from taiga.projects.votes.utils import attach_total_voters_to_queryset from taiga.projects.votes.utils import attach_is_voter_to_queryset +from taiga.projects.history.utils import attach_total_comments_to_queryset def attach_user_story_extra_info(queryset, as_field="user_story_extra_info"): @@ -76,4 +77,5 @@ def attach_extra_info(queryset, user=None, include_attachments=False): queryset = attach_is_voter_to_queryset(queryset, user) queryset = attach_is_watcher_to_queryset(queryset, user) queryset = attach_user_story_extra_info(queryset) + queryset = attach_total_comments_to_queryset(queryset) return queryset diff --git a/taiga/projects/userstories/serializers.py b/taiga/projects/userstories/serializers.py index b7c43466..7fecf778 100644 --- a/taiga/projects/userstories/serializers.py +++ b/taiga/projects/userstories/serializers.py @@ -29,6 +29,7 @@ from taiga.projects.mixins.serializers import StatusExtraInfoSerializerMixin from taiga.projects.notifications.mixins import WatchedResourceSerializer from taiga.projects.tagging.serializers import TaggedInProjectResourceSerializer from taiga.projects.votes.mixins.serializers import VoteResourceSerializerMixin +from taiga.projects.history.mixins import TotalCommentsSerializerMixin class OriginIssueSerializer(serializers.LightSerializer): @@ -47,7 +48,7 @@ class UserStoryListSerializer(ProjectExtraInfoSerializerMixin, VoteResourceSerializerMixin, WatchedResourceSerializer, OwnerExtraInfoSerializerMixin, AssignedToExtraInfoSerializerMixin, StatusExtraInfoSerializerMixin, BasicAttachmentsInfoSerializerMixin, - TaggedInProjectResourceSerializer, + TaggedInProjectResourceSerializer, TotalCommentsSerializerMixin, serializers.LightSerializer): id = Field() diff --git a/taiga/projects/userstories/utils.py b/taiga/projects/userstories/utils.py index 57e4ecd3..5e410aba 100644 --- a/taiga/projects/userstories/utils.py +++ b/taiga/projects/userstories/utils.py @@ -21,6 +21,7 @@ from taiga.projects.attachments.utils import attach_basic_attachments from taiga.projects.notifications.utils import attach_watchers_to_queryset from taiga.projects.notifications.utils import attach_total_watchers_to_queryset from taiga.projects.notifications.utils import attach_is_watcher_to_queryset +from taiga.projects.history.utils import attach_total_comments_to_queryset from taiga.projects.votes.utils import attach_total_voters_to_queryset from taiga.projects.votes.utils import attach_is_voter_to_queryset @@ -174,4 +175,5 @@ def attach_extra_info(queryset, user=None, include_attachments=False, include_ta queryset = attach_total_watchers_to_queryset(queryset) queryset = attach_is_voter_to_queryset(queryset, user) queryset = attach_is_watcher_to_queryset(queryset, user) + queryset = attach_total_comments_to_queryset(queryset) return queryset