Newer
Older
from django.core.exceptions import PermissionDenied
from django.http import HttpResponseRedirect
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views.generic import UpdateView
from django_filters.views import FilterView
from django_tables2.views import SingleTableMixin
from opentech.apply.activity.views import (
AllActivityContextMixin,
ActivityContextMixin,
CommentFormView,
DelegatedViewMixin,
)
from opentech.apply.activity.models import Activity
from opentech.apply.users.decorators import staff_required
from opentech.apply.utils.views import DelegateableView, ViewDispatcher
from .blocks import MustIncludeFieldBlock
from .forms import ProgressSubmissionForm, UpdateSubmissionLeadForm
from .tables import AdminSubmissionsTable, SubmissionFilter, SubmissionFilterAndSearch
@method_decorator(staff_required, name='dispatch')
class SubmissionListView(AllActivityContextMixin, SingleTableMixin, FilterView):
template_name = 'funds/submissions.html'
table_class = AdminSubmissionsTable
filterset_class = SubmissionFilter
def get_queryset(self):
return self.filterset_class._meta.model.objects.current()
def get_context_data(self, **kwargs):
active_filters = self.filterset.data
return super().get_context_data(active_filters=active_filters, **kwargs)
@method_decorator(staff_required, name='dispatch')
class SubmissionSearchView(SingleTableMixin, FilterView):
template_name = 'funds/submissions_search.html'
table_class = AdminSubmissionsTable
filterset_class = SubmissionFilterAndSearch
def get_queryset(self):
return self.filterset_class._meta.model.objects.current()
def get_context_data(self, **kwargs):
search_term = self.request.GET.get('query')
# We have more data than just 'query'
active_filters = len(self.filterset.data) > 1
return super().get_context_data(
search_term=search_term,
active_filters=active_filters,
**kwargs,
)
@method_decorator(staff_required, name='dispatch')
class ProgressSubmissionView(DelegatedViewMixin, UpdateView):
model = ApplicationSubmission
form_class = ProgressSubmissionForm
context_name = 'progress_form'
def form_valid(self, form):
old_phase = form.instance.phase.name
response = super().form_valid(form)
new_phase = form.instance.phase.name
user=self.request.user,
submission=self.kwargs['submission'],
message=f'Progressed from {old_phase} to {new_phase}'
)
return response
@method_decorator(staff_required, name='dispatch')
class UpdateLeadView(DelegatedViewMixin, UpdateView):
model = ApplicationSubmission
form_class = UpdateSubmissionLeadForm
context_name = 'lead_form'
def form_valid(self, form):
# Fetch the old lead from the database
old_lead = self.get_object().lead
response = super().form_valid(form)
new_lead = form.instance.lead
Activity.actions.create(
user=self.request.user,
submission=self.kwargs['submission'],
message=f'Lead changed from {old_lead} to {new_lead}'
)
return response
class AdminSubmissionDetailView(ActivityContextMixin, DelegateableView):
template_name_suffix = '_admin_detail'
model = ApplicationSubmission
form_views = {
'progress': ProgressSubmissionView,
'comment': CommentFormView,
def get_context_data(self, **kwargs):
other_submissions = self.model.objects.filter(user=self.object.user).current().exclude(id=self.object.id)
if self.object.next:
other_submissions = other_submissions.exclude(id=self.object.next.id)
return super().get_context_data(
other_submissions=other_submissions,
class ApplicantSubmissionDetailView(ActivityContextMixin, DelegateableView):
model = ApplicationSubmission
form_views = {
'comment': CommentFormView,
}
def dispatch(self, request, *args, **kwargs):
if self.get_object().user != request.user:
raise PermissionDenied
return super().dispatch(request, *args, **kwargs)
class SubmissionDetailView(ViewDispatcher):
admin_view = AdminSubmissionDetailView
applicant_view = ApplicantSubmissionDetailView
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
class SubmissionEditView(UpdateView):
model = ApplicationSubmission
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
instance = kwargs.pop('instance')
form_data = instance.form_data
# convert certain data to the correct field id
for field in self.object.form_fields:
if isinstance(field.block, MustIncludeFieldBlock):
try:
response = form_data[field.block.name]
except KeyError:
pass
else:
form_data[field.id] = response
kwargs['initial'] = form_data
return 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()
return HttpResponseRedirect(self.get_success_url())
workflows = [SingleStage, DoubleStage]
class BasicSubmissionForm(forms.Form):
who_are_you = forms.CharField()
def demo_workflow(request, wf_id):
logs = request.session.get('logs', list())
submission = request.session.get('submission', dict())
wf = int(wf_id)
workflow = workflow_class([BasicSubmissionForm] * wf)
current_phase = request.POST.get('current')
current = workflow.current(current_phase)
if current.stage.name not in submission:
submitted_form = current.stage.form(request.POST)
if submitted_form.is_valid():
submission[current.stage.name] = submitted_form.cleaned_data
phase = current
logs.append(
f'{phase.stage}: Form was submitted'
)
form = None
else:
form = submitted_form
else:
phase = workflow.process(current_phase, request.POST['action'])
logs.append(
f'{current.stage}: {current.name} was updated to {phase.stage}: {phase.name}'
)
submission.clear()
if phase.stage.name not in submission:
form = phase.stage.form
else:
form = None
request.session['logs'] = logs
request.session['submission'] = submission
context = {
'workflow': workflow,
'phase': phase,
'data': submission,
'form': form,
return TemplateResponse(request, 'funds/demo_workflow.html', context)