diff --git a/meinberlin/apps/budgeting/api.py b/meinberlin/apps/budgeting/api.py index 2a2de4cfd5..30c40a090a 100644 --- a/meinberlin/apps/budgeting/api.py +++ b/meinberlin/apps/budgeting/api.py @@ -12,12 +12,15 @@ from adhocracy4.categories import has_icons from adhocracy4.categories.models import Category from adhocracy4.labels.models import Label +from adhocracy4.modules.predicates import is_allowed_moderate_project from adhocracy4.modules.predicates import module_is_between_phases from adhocracy4.phases.predicates import has_feature_active from meinberlin.apps.contrib.filters import IdeaCategoryFilterBackend from meinberlin.apps.contrib.filters import OrderingFilterWithDailyRandom from meinberlin.apps.contrib.templatetags.contrib_tags import \ get_proper_elided_page_range +from meinberlin.apps.moderationtasks.filters import ModerationTaskFilterBackend +from meinberlin.apps.moderationtasks.models import ModerationTask from meinberlin.apps.moderatorfeedback.models import DEFAULT_CHOICES from meinberlin.apps.votes.api import VotingTokenInfoMixin @@ -96,6 +99,15 @@ def list(self, request, *args, **kwargs): 'choices': moderator_feedback_choices } + # moderation task filter, only show to moderators + if is_allowed_moderate_project(request.user, self.module): + moderation_task_choices = self.get_moderation_task_choices() + if moderation_task_choices: + filters['open_task'] = { + 'label': _('Open tasks'), + 'choices': moderation_task_choices, + } + # ordering filter ordering_choices = self.get_ordering_choices(request) default_ordering = self.get_default_ordering() @@ -138,6 +150,18 @@ def get_label_choices(self): return label_choices + def get_moderation_task_choices(self): + moderation_task_choices = None + moderation_tasks = ModerationTask.objects.filter( + module=self.module + ) + if moderation_tasks: + moderation_task_choices = [('', _('All')), ] + for task in moderation_tasks: + moderation_task_choices += (str(task.pk), task.name), + + return moderation_task_choices + def get_ordering_choices(self, request): ordering_choices = [('-created', _('Most recent')), ] # only show sort by rating when rating is allowed at anytime in module @@ -210,11 +234,13 @@ class ProposalViewSet(ModuleMixin, filter_backends = (DjangoFilterBackend, OrderingFilterWithDailyRandom, IdeaCategoryFilterBackend, - SearchFilter,) + SearchFilter, + ModerationTaskFilterBackend) filterset_fields = ('is_archived', 'category', 'labels', - 'moderator_feedback') + 'moderator_feedback', + 'completed_tasks') ordering_fields = ('created', 'comment_count', 'positive_rating_count', diff --git a/meinberlin/apps/moderationtasks/filters.py b/meinberlin/apps/moderationtasks/filters.py new file mode 100644 index 0000000000..e57a76c80f --- /dev/null +++ b/meinberlin/apps/moderationtasks/filters.py @@ -0,0 +1,23 @@ +from rest_framework.filters import BaseFilterBackend + +from meinberlin.apps.moderationtasks.models import ModerationTask + + +class ModerationTaskFilterBackend(BaseFilterBackend): + """Filter out proposals that have the moderation tasks completed.""" + + def filter_queryset(self, request, queryset, view): + + if 'open_task' in request.GET: + task_id = request.GET['open_task'] + try: + moderation_task = ModerationTask.objects.get(id=task_id) + proposals_completed = getattr( + moderation_task, + '{app_label}_{model}_completed'.format( + app_label=queryset.model._meta.app_label, + model=queryset.model.__name__.lower())).all() + return queryset.exclude(id__in=proposals_completed) + except ModerationTask.DoesNotExist: + pass + return queryset