From 99aea583679f432d49baf547b03b6398fbf688ce Mon Sep 17 00:00:00 2001 From: Jonathan Sundqvist Date: Thu, 10 Oct 2019 15:42:11 +0200 Subject: [PATCH] Add a way to execute unpublishing --- djangocms_moderation/admin.py | 102 +++++++++++------- .../0017_workflow_is_unpublishing.py | 20 ++++ djangocms_moderation/models.py | 5 + djangocms_moderation/signals.py | 8 +- tests/test_admin_actions.py | 2 +- 5 files changed, 99 insertions(+), 38 deletions(-) create mode 100644 djangocms_moderation/migrations/0017_workflow_is_unpublishing.py diff --git a/djangocms_moderation/admin.py b/djangocms_moderation/admin.py index 7a6725a8..da0324b9 100644 --- a/djangocms_moderation/admin.py +++ b/djangocms_moderation/admin.py @@ -7,7 +7,7 @@ from django.contrib.contenttypes.models import ContentType from django.core.exceptions import PermissionDenied from django.db import transaction -from django.http import Http404, HttpResponseRedirect +from django.http import Http404, HttpResponseRedirect, HttpResponseNotAllowed from django.shortcuts import get_object_or_404, render from django.template.loader import render_to_string from django.urls import reverse @@ -533,6 +533,7 @@ def resubmit_view(self, request): moderation_requests=resubmitted_requests, user=request.user, rework=True, + workflow=collection.workflow ) messages.success( @@ -546,12 +547,58 @@ def resubmit_view(self, request): ) return HttpResponseRedirect(redirect_url) + def _publish_flow(self, request, queryset): + """Handles the published workflow""" + published_moderation_requests = [] + for mr in queryset.all(): + if mr.version_can_be_published(): + if publish_version(mr.version, request.user): + published_moderation_requests.append(mr) + mr.update_status( + action=constants.ACTION_FINISHED, by_user=request.user + ) + + messages.success( + request, + ungettext( + "%(count)d request successfully published", + "%(count)d requests successfully published", + len(published_moderation_requests), + ) + % {"count": len(published_moderation_requests)}, + ) + return published_moderation_requests + + def _unpublish_flow(self, request, queryset): + unpublished_moderation_requests = [] + for mr in queryset.all(): + if mr.version_can_be_unpublished(): + mr.version.unpublish(request.user) + unpublished_moderation_requests.append(mr) + mr.update_status( + action=constants.ACTION_FINISHED, by_user=request.user + ) + + messages.success( + request, + ungettext( + "%(count)d request successfully unpublished", + "%(count)d requests successfully unpublished", + len(unpublished_moderation_requests), + ) + % {"count": len(unpublished_moderation_requests)}, + ) + return unpublished_moderation_requests + def published_view(self, request): collection_id = request.GET.get('collection_id') queryset = ModerationRequest.objects.filter(pk__in=request.GET.get('ids', '').split(',')) redirect_url = self._redirect_to_changeview_url(collection_id) - if request.method != 'POST': + if request.method not in ['POST', 'GET']: + return HttpResponseNotAllowed + + if request.method == 'GET': context = dict( ids=request.GET.getlist("ids"), back_url=redirect_url, @@ -562,42 +609,25 @@ def published_view(self, request): "admin/djangocms_moderation/moderationrequest/publish_confirmation.html", context, ) - else: - try: - collection = ModerationCollection.objects.get(id=int(collection_id)) - except (ValueError, ModerationCollection.DoesNotExist): - raise Http404 - - published_moderation_requests = [] - for mr in queryset.all(): - if mr.version_can_be_published(): - if publish_version(mr.version, request.user): - published_moderation_requests.append(mr) - mr.update_status( - action=constants.ACTION_FINISHED, by_user=request.user - ) - else: - # TODO provide some feedback back to the user? - pass - messages.success( - request, - ungettext( - "%(count)d request successfully published", - "%(count)d requests successfully published", - len(published_moderation_requests), - ) - % {"count": len(published_moderation_requests)}, - ) + try: + collection = ModerationCollection.objects.get(id=int(collection_id)) + except (ValueError, ModerationCollection.DoesNotExist): + raise Http404 - post_bulk_actions(collection) - signals.published.send( - sender=self.model, - collection=collection, - moderator=collection.author, - published_moderation_requests=published_moderation_requests, - workflow=collection.workflow - ) + if collection.workflow.is_unpublishing: + moderation_requests = self._unpublish_flow(request, queryset) + else: + moderation_requests = self._publish_flow(request, queryset) + + post_bulk_actions(collection) + signals.published.send( + sender=self.model, + collection=collection, + moderator=collection.author, + moderation_requests=moderation_requests, + workflow=collection.workflow + ) return HttpResponseRedirect(redirect_url) diff --git a/djangocms_moderation/migrations/0017_workflow_is_unpublishing.py b/djangocms_moderation/migrations/0017_workflow_is_unpublishing.py new file mode 100644 index 00000000..7c501f1c --- /dev/null +++ b/djangocms_moderation/migrations/0017_workflow_is_unpublishing.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-10-11 09:23 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('djangocms_moderation', '0016_moderationrequesttreenode'), + ] + + operations = [ + migrations.AddField( + model_name='workflow', + name='is_unpublishing', + field=models.BooleanField(default=False, verbose_name='unpublishing workflow'), + ), + ] diff --git a/djangocms_moderation/models.py b/djangocms_moderation/models.py index 05ee7d12..bb0d1769 100644 --- a/djangocms_moderation/models.py +++ b/djangocms_moderation/models.py @@ -117,6 +117,7 @@ def get_users_queryset(self): class Workflow(models.Model): name = models.CharField(verbose_name=_("name"), max_length=120, unique=True) is_default = models.BooleanField(verbose_name=_("is default"), default=False) + is_unpublishing = models.BooleanField(verbose_name=_("unpublishing workflow"), default=False) identifier = models.CharField( verbose_name=_("identifier"), max_length=128, @@ -304,6 +305,7 @@ def submit_for_review(self, by_user, to_user=None): moderation_requests=list(self.moderation_requests.all()), user=by_user, rework=False, + workflow=self.workflow ) def is_cancellable(self, user): @@ -471,6 +473,9 @@ def is_approved(self): def version_can_be_published(self): return self.is_approved() and self.version.can_be_published() + def version_can_be_unpublished(self): + return self.is_approved() and self.version.can_be_unpublished() + def is_rejected(self): last_action = self.get_last_action() return last_action and last_action.action == constants.ACTION_REJECTED diff --git a/djangocms_moderation/signals.py b/djangocms_moderation/signals.py index 1044e635..3bc64d4c 100644 --- a/djangocms_moderation/signals.py +++ b/djangocms_moderation/signals.py @@ -6,7 +6,13 @@ ) submitted_for_review = django.dispatch.Signal( - providing_args=["collection", "moderation_requests", "user", "rework"] + providing_args=[ + "collection", + "moderation_requests", + "user", + "rework", + "workflow" + ] ) published = django.dispatch.Signal( diff --git a/tests/test_admin_actions.py b/tests/test_admin_actions.py index ca3a2cdf..f0a0251f 100644 --- a/tests/test_admin_actions.py +++ b/tests/test_admin_actions.py @@ -115,7 +115,7 @@ def test_signal_when_published(self): with signal_tester(published) as signal: self.client.post(response.url) args, kwargs = signal.calls[0] - published_mr = kwargs['published_moderation_requests'] + published_mr = kwargs['moderation_requests'] self.assertEquals(signal.call_count, 1) self.assertEquals(kwargs['sender'], ModerationRequest) self.assertEquals(kwargs['collection'], self.collection)