From 3efca271deda64f6d3fbb5211ae8d98c3487390b Mon Sep 17 00:00:00 2001
From: Pete Andrew <peter.andrew@torchbox.com>
Date: Tue, 28 Apr 2020 17:43:26 +0100
Subject: [PATCH] Ref 1907: Improve display of 'Add determination' action

- Added 'Add determination' button as primary action. Uses existing determination button but with altered text for complete draft determination
- Button is only displayed when submission is in 'ready-for-determination' phase
---
 .../includes/determination_button.html        | 12 ++-
 hypha/apply/funds/models/submissions.py       |  4 +
 .../templates/funds/includes/actions.html     |  4 +
 hypha/apply/funds/tests/test_views.py         | 99 +++++++++++++++++++
 4 files changed, 117 insertions(+), 2 deletions(-)

diff --git a/hypha/apply/determinations/templates/determinations/includes/determination_button.html b/hypha/apply/determinations/templates/determinations/includes/determination_button.html
index 2e275ed5b..a528358dc 100644
--- a/hypha/apply/determinations/templates/determinations/includes/determination_button.html
+++ b/hypha/apply/determinations/templates/determinations/includes/determination_button.html
@@ -1,6 +1,14 @@
 {% load determination_tags workflow_tags %}
 {% if request.user|show_determination_button:submission %}
-    <a target="_blank" href="{% url 'apply:submissions:determinations:form' submission_pk=submission.id %}" class="button button--primary button--full-width">
-        {% if submission.determination.is_draft %}Update draft{% else %}Add Determination{% endif %}
+    <a target="_blank" href="{% url 'apply:submissions:determinations:form' submission_pk=submission.id %}" class="button button--primary button--full-width {{ class }}">
+        {% if submission.determinations.last.is_draft %}
+            {% if draft_text %}
+                {{ draft_text }}
+            {% else %}
+                Update draft
+            {% endif %}
+        {% else %}
+            Add determination
+        {% endif %}
     </a>
 {% endif %}
diff --git a/hypha/apply/funds/models/submissions.py b/hypha/apply/funds/models/submissions.py
index 00b8fbea4..538274ec6 100644
--- a/hypha/apply/funds/models/submissions.py
+++ b/hypha/apply/funds/models/submissions.py
@@ -702,6 +702,10 @@ class ApplicationSubmission(
     def __repr__(self):
         return f'<{self.__class__.__name__}: {self.user}, {self.round}, {self.page}>'
 
+    @property
+    def ready_for_determination(self):
+        return self.status in PHASES_MAPPING['ready-for-determination']['statuses']
+
     @property
     def accepted_for_funding(self):
         accepted = self.status in PHASES_MAPPING['accepted']['statuses']
diff --git a/hypha/apply/funds/templates/funds/includes/actions.html b/hypha/apply/funds/templates/funds/includes/actions.html
index fef520d40..3aca979d6 100644
--- a/hypha/apply/funds/templates/funds/includes/actions.html
+++ b/hypha/apply/funds/templates/funds/includes/actions.html
@@ -14,6 +14,10 @@
 
 <a data-fancybox data-src="#screen-application" class="button button--bottom-space button--primary button--full-width {% if screening_form.should_show %}is-not-disabled{% else %}is-disabled{% endif %}" href="#">Screen application</a>
 
+{% if object.ready_for_determination %}
+    {% include 'determinations/includes/determination_button.html' with submission=object class="button--bottom-space" draft_text="Complete draft determination" %}
+{% endif %}
+
 <a data-fancybox data-src="#update-status" class="button button--primary button--full-width {% if progress_form.should_show %}is-not-disabled{% else %}is-disabled{% endif %}" href="#">Update status</a>
 
 
diff --git a/hypha/apply/funds/tests/test_views.py b/hypha/apply/funds/tests/test_views.py
index dd09926fd..9b3734a11 100644
--- a/hypha/apply/funds/tests/test_views.py
+++ b/hypha/apply/funds/tests/test_views.py
@@ -1,5 +1,7 @@
+import re
 from datetime import timedelta
 
+from bs4 import BeautifulSoup
 from django.contrib.auth.models import AnonymousUser
 from django.core.exceptions import PermissionDenied
 from django.http import Http404
@@ -207,6 +209,48 @@ class TestStaffSubmissionView(BaseSubmissionViewTestCase):
         self.assertTrue(hasattr(submission, 'project'))
         self.assertEquals(submission.project.id, project.id)
 
+    def test_can_see_add_determination_primary_action(self):
+        def assert_add_determination_displayed(submission, button_text):
+            response = self.get_page(submission)
+            # Ignore whitespace (including line breaks) in button text
+            pattern = re.compile(rf'\s*{button_text}\s*')
+            buttons = BeautifulSoup(response.content, 'html5lib').find(class_='js-actions-sidebar').find_all('a', class_='button--primary', text=pattern)
+            self.assertEqual(len(buttons), 1)
+
+        submission = ApplicationSubmissionFactory(status='determination')
+
+        # Phase: ready-for-determination, no determination
+        # "Add determination" should be displayed
+        assert_add_determination_displayed(submission, 'Add determination')
+
+        # Phase: ready-for-determination, draft determination
+        # "Complete draft determination" should be displayed
+        DeterminationFactory(submission=submission, author=self.user, accepted=True, submitted=False)
+        assert_add_determination_displayed(submission, 'Complete draft determination')
+
+    def test_cant_see_add_determination_primary_action(self):
+        def assert_add_determination_not_displayed(submission, button_text):
+            response = self.get_page(submission)
+            # Ignore whitespace (including line breaks) in button text
+            pattern = re.compile(rf'\s*{button_text}\s*')
+            buttons = BeautifulSoup(response.content, 'html5lib').find(class_='js-actions-sidebar').find_all('a', class_='button--primary', text=pattern)
+            self.assertEqual(len(buttons), 0)
+
+        submission = ApplicationSubmissionFactory()
+
+        # Phase: received / in_discussion
+        # "Add determination" should not be displayed
+        # "Complete draft determination" should not be displayed
+        assert_add_determination_not_displayed(submission, 'Add determination')
+        assert_add_determination_not_displayed(submission, 'Complete draft determination')
+
+        # Phase: accepted
+        # "Add determination" should not be displayed
+        # "Complete draft determination" should not be displayed
+        submission.perform_transition('accepted', self.user)
+        assert_add_determination_not_displayed(submission, 'Add determination')
+        assert_add_determination_not_displayed(submission, 'Complete draft determination')
+
 
 class TestReviewersUpdateView(BaseSubmissionViewTestCase):
     user_factory = StaffFactory
@@ -335,6 +379,38 @@ class TestReviewersUpdateView(BaseSubmissionViewTestCase):
         self.assertCountEqual(submission.reviewers.all(), [reviewer, self.reviewers[1]])
 
 
+class TestReviewerSubmissionView(BaseSubmissionViewTestCase):
+    user_factory = ReviewerFactory
+
+    @classmethod
+    def setUpTestData(cls):
+        super().setUpTestData()
+        cls.applicant = ApplicantFactory()
+
+    def test_cant_see_add_determination_primary_action(self):
+        def assert_add_determination_not_displayed(submission, button_text):
+            response = self.get_page(submission)
+            # Ignore whitespace (including line breaks) in button text
+            pattern = re.compile(rf'\s*{button_text}\s*')
+            buttons = BeautifulSoup(response.content, 'html5lib').find_all('a', class_='button--primary', text=pattern)
+            self.assertEqual(len(buttons), 0)
+
+        submission = ApplicationSubmissionFactory(status='determination', user=self.applicant, reviewers=[self.user])
+
+        # Phase: ready-for-determination, no determination
+        # "Add determination" should not be displayed
+        # "Complete draft determination" should not be displayed
+        assert_add_determination_not_displayed(submission, 'Add determination')
+        assert_add_determination_not_displayed(submission, 'Complete draft determination')
+
+        # Phase: ready-for-determination, draft determination
+        # "Add determination" should not be displayed
+        # "Complete draft determination" should not be displayed
+        DeterminationFactory(submission=submission, accepted=True, submitted=False)
+        assert_add_determination_not_displayed(submission, 'Add determination')
+        assert_add_determination_not_displayed(submission, 'Complete draft determination')
+
+
 class TestApplicantSubmissionView(BaseSubmissionViewTestCase):
     user_factory = ApplicantFactory
 
@@ -428,6 +504,29 @@ class TestApplicantSubmissionView(BaseSubmissionViewTestCase):
         response = self.get_page(self.submission)
         self.assertNotContains(response, 'Screening Status')
 
+    def test_cant_see_add_determination_primary_action(self):
+        def assert_add_determination_not_displayed(submission, button_text):
+            response = self.get_page(submission)
+            # Ignore whitespace (including line breaks) in button text
+            pattern = re.compile(rf'\s*{button_text}\s*')
+            buttons = BeautifulSoup(response.content, 'html5lib').find_all('a', class_='button--primary', text=pattern)
+            self.assertEqual(len(buttons), 0)
+
+        submission = ApplicationSubmissionFactory(status='determination', user=self.user)
+
+        # Phase: ready-for-determination, no determination
+        # "Add determination" should not be displayed
+        # "Complete draft determination" should not be displayed
+        assert_add_determination_not_displayed(submission, 'Add determination')
+        assert_add_determination_not_displayed(submission, 'Complete draft determination')
+
+        # Phase: ready-for-determination, draft determination
+        # "Add determination" should not be displayed
+        # "Complete draft determination" should not be displayed
+        DeterminationFactory(submission=submission, accepted=True, submitted=False)
+        assert_add_determination_not_displayed(submission, 'Add determination')
+        assert_add_determination_not_displayed(submission, 'Complete draft determination')
+
 
 class TestRevisionsView(BaseSubmissionViewTestCase):
     user_factory = ApplicantFactory
-- 
GitLab