From cd4fa92a35df6b5eb4f681dfd54bb56530c56a99 Mon Sep 17 00:00:00 2001 From: jacobtoppm Date: Mon, 30 Mar 2020 17:37:48 +0100 Subject: [PATCH] Fix query when retrieving next task to filter out only tasks that have task states that are both attached to the current revision and completed, rather than tasks that have task states that individually fulfil both criteria --- wagtail/core/models.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/wagtail/core/models.py b/wagtail/core/models.py index b974deb4f3..1b1317f9a9 100644 --- a/wagtail/core/models.py +++ b/wagtail/core/models.py @@ -2854,6 +2854,9 @@ class WorkflowState(models.Model): # not STATUS_IN_PROGRESS), move to the next task self.current_task_state = next_task.specific.start(self, user=user) self.save() + # if task has auto-approved, update the workflow again + if self.current_task_state.status != self.current_task_state.STATUS_IN_PROGRESS: + self.update(user=user) # otherwise, continue on the current task else: # if there is no uncompleted task, finish the workflow. @@ -2861,7 +2864,7 @@ class WorkflowState(models.Model): def get_next_task(self): """Returns the next active task associated with the latest page revision, which has not been either approved or skipped""" - return Task.objects.filter(workflow_tasks__workflow=self.workflow, active=True).exclude(Q(task_states__page_revision=self.page.get_latest_revision()), Q(task_states__status=TaskState.STATUS_APPROVED) | Q(task_states__status=TaskState.STATUS_SKIPPED)).order_by('workflow_tasks__sort_order').first() + return Task.objects.filter(workflow_tasks__workflow=self.workflow, active=True).exclude(task_states__in=TaskState.objects.filter(Q(page_revision=self.page.get_latest_revision()), Q(status=TaskState.STATUS_APPROVED) | Q(status=TaskState.STATUS_SKIPPED))).order_by('workflow_tasks__sort_order').first() def cancel(self, user=None): """Cancels the workflow state""" @@ -3007,26 +3010,28 @@ class TaskState(MultiTableCopyMixin, models.Model): return content_type.get_object_for_this_type(id=self.id) @transaction.atomic - def approve(self, user=None): + def approve(self, user=None, update=True): """Approve the task state and update the workflow state""" if self.status != self.STATUS_IN_PROGRESS: raise PermissionDenied self.status = self.STATUS_APPROVED self.finished_at = timezone.now() self.save() - self.workflow_state.update(user=user) + if update: + self.workflow_state.update(user=user) task_approved.send(sender=self.specific.__class__, instance=self.specific, user=user) return self @transaction.atomic - def reject(self, user=None): + def reject(self, user=None, update=True): """Reject the task state and update the workflow state""" if self.status != self.STATUS_IN_PROGRESS: raise PermissionDenied self.status = self.STATUS_REJECTED self.finished_at = timezone.now() self.save() - self.workflow_state.update(user=user) + if update: + self.workflow_state.update(user=user) task_rejected.send(sender=self.specific.__class__, instance=self.specific, user=user) return self