diff --git a/opentech/apply/funds/forms.py b/opentech/apply/funds/forms.py
index f1c21b703159c35667ac8d966f8cb70af4fe349d..e84c154bb47482cc277b561bc6f92a111d8ef207 100644
--- a/opentech/apply/funds/forms.py
+++ b/opentech/apply/funds/forms.py
@@ -6,6 +6,7 @@ from opentech.apply.users.models import User
 
 from .models import ApplicationSubmission, AssignedReviewers, ReviewerRole
 from .widgets import Select2MultiCheckboxesWidget, Select2IconWidget
+from .workflow import ACTION_MAPPING
 
 
 class ProgressSubmissionForm(forms.ModelForm):
@@ -27,6 +28,12 @@ class ProgressSubmissionForm(forms.ModelForm):
 class BatchProgressSubmissionForm(forms.Form):
     action = forms.ChoiceField(label='Take action')
 
+    def __init__(self, *args, **kwargs):
+        self.user = kwargs.pop('user')
+        super().__init__(*args, **kwargs)
+        choices = [(action, detail['display']) for action, detail in ACTION_MAPPING.items()]
+        self.fields['action'].choices = choices
+
 
 class ScreeningSubmissionForm(forms.ModelForm):
 
@@ -203,6 +210,10 @@ class BatchUpdateReviewersForm(forms.Form):
     )
     submission_ids = forms.CharField(widget=forms.HiddenInput())
 
+    def __init__(self, *args, **kwargs):
+        kwargs.pop('user')
+        super().__init__(*args, **kwargs)
+
     def clean_submission_ids(self):
         value = self.cleaned_data['submission_ids']
         return [int(submission) for submission in value.split(',')]
diff --git a/opentech/apply/funds/workflow.py b/opentech/apply/funds/workflow.py
index cb5744d5a2480962f84ab8a82375c63375a8cfc3..e66eb557ad87b63c5ac07c0fb6ad105ef27d7392 100644
--- a/opentech/apply/funds/workflow.py
+++ b/opentech/apply/funds/workflow.py
@@ -2,6 +2,7 @@ from collections import defaultdict
 from enum import Enum
 import itertools
 
+from django.utils.text import slugify
 
 """
 This file defines classes which allow you to compose workflows based on the following structure:
@@ -732,6 +733,22 @@ def get_determination_transitions():
     return transitions
 
 
+def get_actions_mapping():
+    # Maps action names to the phase they originate from
+    transitions = defaultdict(lambda: {'display': '', 'phases': []})
+    for phase_name, phase in PHASES:
+        for transition_name, transition in phase.transitions.items():
+            transition_name = transition['display']
+            transition_key = slugify(transition_name)
+            transitions[transition_key]['display'] = transition_name
+            transitions[transition_key]['phases'].append(phase_name)
+
+    return transitions
+
+
+ACTION_MAPPING = get_actions_mapping()
+
+
 DETERMINATION_OUTCOMES = get_determination_transitions()
 
 
diff --git a/opentech/apply/utils/views.py b/opentech/apply/utils/views.py
index 3e83f17d44a38942df0dc9f1133d0c3141c7cff2..a9e561cf261a232421fb6365d4ee1b63c61bb2ac 100644
--- a/opentech/apply/utils/views.py
+++ b/opentech/apply/utils/views.py
@@ -83,6 +83,9 @@ class DelegateableView(DelegatableBase):
 
 
 class DelegateableListView(DelegatableBase):
+    def get_form_args(self):
+        return None, self.request.user
+
     def post(self, request, *args, **kwargs):
         self.object_list = self.get_queryset()
         return super().post(request, *args, **kwargs)
@@ -96,8 +99,7 @@ class DelegatedViewMixin(View):
 
     def get_form_kwargs(self):
         kwargs = super().get_form_kwargs()
-        if self.is_model_form():
-            kwargs['user'] = self.request.user
+        kwargs['user'] = self.request.user
         return kwargs
 
     def get_form(self, *args, **kwargs):
@@ -121,7 +123,7 @@ class DelegatedViewMixin(View):
         if cls.is_model_form():
             form = cls.form_class(instance=submission, user=user)
         else:
-            form = cls.form_class()  # This is for the batch update, we don't pass in the user or a single submission
+            form = cls.form_class(user=user)
         form.name = cls.context_name
         return cls.context_name, form