diff --git a/opentech/apply/activity/models.py b/opentech/apply/activity/models.py index 643ca3caeebb36920655f70fe0e94d467d999e39..d17c46c116be88d9dc0f52bf9ff13d899c45debd 100644 --- a/opentech/apply/activity/models.py +++ b/opentech/apply/activity/models.py @@ -3,6 +3,8 @@ from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver +from django_fsm.signals import post_transition + from opentech.apply.funds.models import ApplicationSubmission COMMENT = 'comment' @@ -112,3 +114,18 @@ def log_submission_activity(sender, **kwargs): submission=submission, message=f'Submitted {submission.title} for {submission.page.title}' ) + + +@receiver(post_transition, sender=ApplicationSubmission) +def log_status_update(sender, **kwargs): + instance = kwargs['instance'] + old_phase = instance.workflow[kwargs['source']].display_name + new_phase = instance.workflow[kwargs['target']].display_name + + by = kwargs['method_kwargs']['by'] + + Activity.actions.create( + user=by, + submission=instance, + message=f'Progressed from {old_phase} to {new_phase}' + ) diff --git a/opentech/apply/funds/forms.py b/opentech/apply/funds/forms.py index 3f150b64f88a8d5c7fc6b149058030e22dad8aab..8f68553386afc9b81d55db41b879b5e3785f485b 100644 --- a/opentech/apply/funds/forms.py +++ b/opentech/apply/funds/forms.py @@ -15,7 +15,7 @@ class ProgressSubmissionForm(forms.ModelForm): fields: list = [] def __init__(self, *args, **kwargs): - kwargs.pop('user') + self.user = kwargs.pop('user') super().__init__(*args, **kwargs) choices = [(name, action) for name, action in self.instance.phase.transitions.items()] action_field = self.fields['action'] @@ -32,7 +32,7 @@ class ProgressSubmissionForm(forms.ModelForm): return action_name def save(self, *args, **kwargs): - self.transition() + self.transition(by=self.user) return super().save(*args, **kwargs) diff --git a/opentech/apply/funds/models.py b/opentech/apply/funds/models.py index fad44572dfb5bd8630936dd800228cdc784e6404..e5f72cdfbeda01f63105e5afe0c3b1f28ed8da98 100644 --- a/opentech/apply/funds/models.py +++ b/opentech/apply/funds/models.py @@ -501,7 +501,7 @@ class AddTransitions(models.base.ModelBase): for transition_name, action in data.all_transitions.items(): method = data.transition_methods.get(transition_name) # Get the method defined on the parent or default to a NOOP - transition_state = attrs.get(method, lambda self: None) + transition_state = attrs.get(method, lambda *args, **kwargs: None) # Provide a neat name for graph viz display transition_state.__name__ = slugify(action) # Wrap with transition decorator diff --git a/opentech/apply/funds/templates/funds/applicationsubmission_form.html b/opentech/apply/funds/templates/funds/applicationsubmission_form.html index d7911104fe80ebcd1d7c0340c29db81d8060cd48..da02a2a9faee6f437cb24f4541980708b02b97be 100644 --- a/opentech/apply/funds/templates/funds/applicationsubmission_form.html +++ b/opentech/apply/funds/templates/funds/applicationsubmission_form.html @@ -19,7 +19,9 @@ {{ field }} {% endif %} {% endfor %} - <input class="button button--primary" type="submit" value="Submit" /> + {% for button_name, button_value in buttons %} + <input class="button button--primary" type="submit" name="{{ button_name }}" value="{{ button_value }}" /> + {% endfor %} </form> </div> {% endblock %} diff --git a/opentech/apply/funds/views.py b/opentech/apply/funds/views.py index f1f16005e4295e75e45109e85312c0866e744168..78d05fa3b93c6ee18df509b9d70a060c9bc80f7c 100644 --- a/opentech/apply/funds/views.py +++ b/opentech/apply/funds/views.py @@ -70,14 +70,7 @@ class ProgressSubmissionView(DelegatedViewMixin, UpdateView): context_name = 'progress_form' def form_valid(self, form): - old_phase = form.instance.phase.display_name response = super().form_valid(form) - new_phase = form.instance.phase.display_name - Activity.actions.create( - user=self.request.user, - submission=self.kwargs['submission'], - message=f'Progressed from {old_phase} to {new_phase}' - ) return self.progress_stage(form.instance) or response def progress_stage(self, instance): @@ -197,6 +190,18 @@ class SubmissionEditView(UpdateView): raise PermissionDenied return super().dispatch(request, *args, **kwargs) + @property + def transitions(self): + transitions = self.object.get_available_user_status_transitions(self.request.user) + return { + transition.name: transition + for transition in transitions + } + + def buttons(self): + yield ('save', 'Save') + yield from ((transition, transition.title) for transition in self.transitions) + def get_form_kwargs(self): kwargs = super().get_form_kwargs() instance = kwargs.pop('instance') @@ -215,10 +220,24 @@ class SubmissionEditView(UpdateView): kwargs['initial'] = form_data return kwargs + def get_context_data(self, **kwargs): + return super().get_context_data(buttons=self.buttons(), **kwargs) + def get_form_class(self): return self.object.get_form_class() def form_valid(self, form): self.object.form_data = form.cleaned_data self.object.save() + + if 'save' in self.request.POST: + return self.form_invalid(form) + + transition = set(self.request.POST.keys()) & set(self.transitions.keys()) + + if transition: + transition_object =self.transitions[transition.pop()] + self.object.get_transition(transition_object.target)(by=self.request.user) + self.object.save() + return HttpResponseRedirect(self.get_success_url())