From a0e4c7b9c1bbf111d2d73b9064863e2d12009c01 Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Tue, 19 Feb 2019 10:50:40 +0000
Subject: [PATCH] GH-858: Handle batch transition messaging

---
 opentech/apply/activity/messaging.py |  8 ++++++++
 opentech/apply/activity/options.py   |  1 +
 opentech/apply/funds/views.py        | 25 +++++++++++++++++++++----
 opentech/apply/funds/workflow.py     |  5 ++---
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/opentech/apply/activity/messaging.py b/opentech/apply/activity/messaging.py
index 4ee98bb81..36c6f74c6 100644
--- a/opentech/apply/activity/messaging.py
+++ b/opentech/apply/activity/messaging.py
@@ -44,6 +44,7 @@ neat_related = {
     MESSAGES.UPDATE_LEAD: 'old_lead',
     MESSAGES.NEW_REVIEW: 'review',
     MESSAGES.TRANSITION: 'old_phase',
+    MESSAGES.BATCH_TRANSITION: 'transitions',
     MESSAGES.APPLICANT_EDIT: 'revision',
     MESSAGES.EDIT: 'revision',
     MESSAGES.COMMENT: 'comment',
@@ -182,6 +183,7 @@ class ActivityAdapter(AdapterBase):
     always_send = True
     messages = {
         MESSAGES.TRANSITION: 'handle_transition',
+        MESSAGES.BATCH_TRANSITION: 'handle_batch_transition',
         MESSAGES.NEW_SUBMISSION: 'Submitted {submission.title} for {submission.page.title}',
         MESSAGES.EDIT: 'Edited',
         MESSAGES.APPLICANT_EDIT: 'Edited',
@@ -249,6 +251,12 @@ class ActivityAdapter(AdapterBase):
 
         return staff_message
 
+    def handle_batch_transition(self, transitions, submissions, **kwargs):
+        kwargs.pop('submission')
+        for submission in submissions:
+            old_phase = transitions[submission.phase]
+            return self.handle_transition(old_phase=old_phase, submission=submission, **kwargs)
+
     def send_message(self, message, user, submission, submissions, **kwargs):
         from .models import Activity, PUBLIC
         visibility = kwargs.get('visibility', PUBLIC)
diff --git a/opentech/apply/activity/options.py b/opentech/apply/activity/options.py
index 35aa1e644..f7b713576 100644
--- a/opentech/apply/activity/options.py
+++ b/opentech/apply/activity/options.py
@@ -8,6 +8,7 @@ class MESSAGES(Enum):
     NEW_SUBMISSION = 'New Submission'
     SCREENING = 'Screening'
     TRANSITION = 'Transition'
+    BATCH_TRANSITION = 'Batch Transition'
     DETERMINATION_OUTCOME = 'Determination Outcome'
     INVITED_TO_PROPOSAL = 'Invited To Proposal'
     REVIEWERS_UPDATED = 'Reviewers Updated'
diff --git a/opentech/apply/funds/views.py b/opentech/apply/funds/views.py
index 6f406b059..8754ecc5e 100644
--- a/opentech/apply/funds/views.py
+++ b/opentech/apply/funds/views.py
@@ -136,20 +136,37 @@ class BatchProgressSubmissionView(DelegatedViewMixin, FormView):
         transitions = form.cleaned_data.get('action')
 
         failed = []
+        phase_changes = {}
         for submission in submissions:
             valid_actions = {action for action, _ in submission.get_actions_for_user(self.request.user)}
-            transition = (valid_actions & set(transitions)).pop()
             try:
-                submission.perform_transition(transition, self.request.user, request=self.request)
-            except PermissionDenied:
+                transition = (valid_actions & set(transitions)).pop()
+                submission.perform_transition(
+                    transition,
+                    self.request.user,
+                    request=self.request,
+                    notify=False,
+                )
+            except (PermissionDenied, KeyError):
                 failed.append(submission)
+            else:
+                phase_changes[submission.phase] = transitions[transition]
 
         if failed:
             messages.warning(
                 self.request,
-                _('You do no have permission to do that to: ') +
+                _('Failed to update: ') +
                 ', '.join(str(submission) for submission in failed)
             )
+
+        messenger(
+            MESSAGES.BATCH_TRANSITION,
+            user=self.request.user,
+            request=self.request,
+            submissions=submissions.exclude(id__in=[submission.id for submission in failed]),
+            related=phase_changes,
+        )
+
         return super().form_valid(form)
 
 
diff --git a/opentech/apply/funds/workflow.py b/opentech/apply/funds/workflow.py
index 23deb6fd3..b71ebe9a1 100644
--- a/opentech/apply/funds/workflow.py
+++ b/opentech/apply/funds/workflow.py
@@ -735,14 +735,13 @@ def get_determination_transitions():
 
 def get_actions_mapping():
     # Maps action names to the phase they originate from
-    transitions = defaultdict(lambda: {'display': '', 'phases': []})
+    transitions = defaultdict(lambda: {'display': '', 'transitions': {}})
     for phase_name, phase in PHASES:
         for transition_name, transition in phase.transitions.items():
             transition_display = transition['display']
             transition_key = slugify(transition_display)
-            transitions[transition_key].setdefault('transitions', []).append(transition_name)
+            transitions[transition_key]['transitions'][transition_name] = phase
             transitions[transition_key]['display'] = transition_display
-            transitions[transition_key]['phases'].append(phase_name)
 
     return transitions
 
-- 
GitLab