From 0ee1dadf92632050b99a43bb4a8d6d27491b903b Mon Sep 17 00:00:00 2001
From: Parbhat Puri <parbhatpuri17@gmail.com>
Date: Tue, 21 May 2019 14:42:22 +0530
Subject: [PATCH] GH-972: Allow staff users to add meta categories to
 submissions

---
 opentech/apply/funds/forms.py                 | 24 +++++++++++++++++++
 ...1_applicationsubmission_meta_categories.py | 19 +++++++++++++++
 opentech/apply/funds/models/submissions.py    |  6 +++++
 .../applicationsubmission_admin_detail.html   |  1 +
 .../templates/funds/includes/actions.html     |  2 ++
 .../includes/update_meta_categories_form.html |  4 ++++
 opentech/apply/funds/views.py                 |  9 +++++++
 7 files changed, 65 insertions(+)
 create mode 100644 opentech/apply/funds/migrations/0061_applicationsubmission_meta_categories.py
 create mode 100644 opentech/apply/funds/templates/funds/includes/update_meta_categories_form.html

diff --git a/opentech/apply/funds/forms.py b/opentech/apply/funds/forms.py
index 4057a2906..2a5c1c5b1 100644
--- a/opentech/apply/funds/forms.py
+++ b/opentech/apply/funds/forms.py
@@ -3,6 +3,7 @@ from django.utils.text import mark_safe, slugify
 from django.utils.translation import ugettext_lazy as _
 from django_select2.forms import Select2Widget
 
+from opentech.apply.categories.models import MetaCategory
 from opentech.apply.users.models import User
 
 from .models import AssignedReviewers, ApplicationSubmission, ReviewerRole
@@ -286,3 +287,26 @@ class UpdatePartnersForm(forms.ModelForm):
             self.submitted_partners
         )
         return instance
+
+
+class MetaCategoryMultipleChoiceField(forms.ModelMultipleChoiceField):
+    def label_from_instance(self, obj):
+        depth_line = '-' * (obj.get_depth() - 1)
+        return "{} {}".format(depth_line, super().label_from_instance(obj))
+
+
+class UpdateMetaCategoriesForm(forms.ModelForm):
+    meta_categories = MetaCategoryMultipleChoiceField(
+        queryset=MetaCategory.objects.all(),
+        widget=Select2MultiCheckboxesWidget(attrs={'data-placeholder': 'Meta categories'}),
+        label='Meta categories',
+        required=False,
+    )
+
+    class Meta:
+        model = ApplicationSubmission
+        fields: list = []
+
+    def __init__(self, *args, **kwargs):
+        kwargs.pop('user')
+        super().__init__(*args, **kwargs)
diff --git a/opentech/apply/funds/migrations/0061_applicationsubmission_meta_categories.py b/opentech/apply/funds/migrations/0061_applicationsubmission_meta_categories.py
new file mode 100644
index 000000000..5fdb7e8d5
--- /dev/null
+++ b/opentech/apply/funds/migrations/0061_applicationsubmission_meta_categories.py
@@ -0,0 +1,19 @@
+# Generated by Django 2.0.13 on 2019-05-21 06:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('categories', '0002_metacategory'),
+        ('funds', '0060_add_duration_type_in_duration_block'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='applicationsubmission',
+            name='meta_categories',
+            field=models.ManyToManyField(blank=True, related_name='submissions', to='categories.MetaCategory'),
+        ),
+    ]
diff --git a/opentech/apply/funds/models/submissions.py b/opentech/apply/funds/models/submissions.py
index cd1c41523..316099182 100644
--- a/opentech/apply/funds/models/submissions.py
+++ b/opentech/apply/funds/models/submissions.py
@@ -32,6 +32,7 @@ from wagtail.core.fields import StreamField
 from wagtail.contrib.forms.models import AbstractFormSubmission
 
 from opentech.apply.activity.messaging import messenger, MESSAGES
+from opentech.apply.categories.models import MetaCategory
 from opentech.apply.determinations.models import Determination
 from opentech.apply.review.models import ReviewOpinion
 from opentech.apply.review.options import MAYBE, AGREE, DISAGREE
@@ -390,6 +391,11 @@ class ApplicationSubmission(
         limit_choices_to=LIMIT_TO_PARTNERS,
         blank=True,
     )
+    meta_categories = models.ManyToManyField(
+        MetaCategory,
+        related_name='submissions',
+        blank=True,
+    )
     user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)
     search_data = models.TextField()
 
diff --git a/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html b/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html
index f11f7ecc0..9ad4efaaa 100644
--- a/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html
+++ b/opentech/apply/funds/templates/funds/applicationsubmission_admin_detail.html
@@ -17,6 +17,7 @@
         {% include "funds/includes/update_lead_form.html" %}
         {% include "funds/includes/update_reviewer_form.html" %}
         {% include "funds/includes/update_partner_form.html" %}
+        {% include "funds/includes/update_meta_categories_form.html" %}
 {% endblock %}
 
 {% block reviews %}
diff --git a/opentech/apply/funds/templates/funds/includes/actions.html b/opentech/apply/funds/templates/funds/includes/actions.html
index 1b1d19b7f..7850e0453 100644
--- a/opentech/apply/funds/templates/funds/includes/actions.html
+++ b/opentech/apply/funds/templates/funds/includes/actions.html
@@ -19,4 +19,6 @@
     </div>
 
     <a class="button button--white button--full-width button--bottom-space" href="{% url 'funds:submissions:revisions:list' submission_pk=object.id %}">Revisions</a>
+
+    <a data-fancybox data-src="#update-meta-categories" class="button button--white button--full-width button--bottom-space" href="#">Meta Categories</a>
 </div>
diff --git a/opentech/apply/funds/templates/funds/includes/update_meta_categories_form.html b/opentech/apply/funds/templates/funds/includes/update_meta_categories_form.html
new file mode 100644
index 000000000..44395f61d
--- /dev/null
+++ b/opentech/apply/funds/templates/funds/includes/update_meta_categories_form.html
@@ -0,0 +1,4 @@
+<div class="modal" id="update-meta-categories">
+    <h4 class="modal__header-bar">Update Meta Categories</h4>
+    {% include 'funds/includes/delegated_form_base.html' with form=meta_categories_form value='Update' %}
+</div>
diff --git a/opentech/apply/funds/views.py b/opentech/apply/funds/views.py
index 11abacbb2..1c1257bd1 100644
--- a/opentech/apply/funds/views.py
+++ b/opentech/apply/funds/views.py
@@ -44,6 +44,7 @@ from .forms import (
     UpdateReviewersForm,
     UpdateSubmissionLeadForm,
     UpdatePartnersForm,
+    UpdateMetaCategoriesForm,
 )
 from .models import (
     ApplicationSubmission,
@@ -471,6 +472,13 @@ class UpdatePartnersView(DelegatedViewMixin, UpdateView):
         return response
 
 
+@method_decorator(staff_required, name='dispatch')
+class UpdateMetaCategoriesView(DelegatedViewMixin, UpdateView):
+    model = ApplicationSubmission
+    form_class = UpdateMetaCategoriesForm
+    context_name = 'meta_categories_form'
+
+
 class AdminSubmissionDetailView(ReviewContextMixin, ActivityContextMixin, DelegateableView, DetailView):
     template_name_suffix = '_admin_detail'
     model = ApplicationSubmission
@@ -481,6 +489,7 @@ class AdminSubmissionDetailView(ReviewContextMixin, ActivityContextMixin, Delega
         UpdateLeadView,
         UpdateReviewersView,
         UpdatePartnersView,
+        UpdateMetaCategoriesView,
     ]
 
     def dispatch(self, request, *args, **kwargs):
-- 
GitLab