Skip to content

Commit

Permalink
Merge pull request #2294 from uktrade/LTD-5769-bulk-approval-fe
Browse files Browse the repository at this point in the history
LTD-5769: Add option to approve multiple cases
  • Loading branch information
saruniitr authored Jan 14, 2025
2 parents e240c68 + 399fa64 commit 5a1a5a2
Show file tree
Hide file tree
Showing 10 changed files with 403 additions and 1 deletion.
42 changes: 42 additions & 0 deletions caseworker/advice/constants.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
# Teams
DESNZ_CHEMICAL = "56273dd4-4634-4ad7-a782-e480f85a85a9" # /PS-IGNORE
DESNZ_NUCLEAR = "88164d59-8724-4596-811b-40b60b5cf892" # /PS-IGNORE
FCDO_TEAM = "67b9a4a3-6f3d-4511-8a19-23ccff221a74" # /PS-IGNORE
LICENSING_UNIT_TEAM = "58e77e47-42c8-499f-a58d-94f94541f8c6" # /PS-IGNORE
MOD_CAPPROT_TEAM = "a06aec31-47d7-443b-860d-66ab0c6d7cfd" # /PS-IGNORE
NCSC_TEAM = "2b5492ad-0ef5-4a2c-bba2-b208fbe80956" # /PS-IGNORE
ENFORCEMENT_UNIT = "48b4fe54-7d4f-4c03-b143-f8d1dcef9f5b" # /PS-IGNORE
MOD_ECJU = "b7640925-2577-4c24-8081-b85bd635b62a" # /PS-IGNORE
MOD_DI_TEAM = "2e5fab3c-4599-432e-9540-74ccfafb18ee" # /PS-IGNORE
MOD_DSR_TEAM = "4c62ce4a-18f8-4ada-8d18-4b53a565250f" # /PS-IGNORE
MOD_DSTL_TEAM = "809eba0f-f197-4f0f-949b-9af309a844fb" # /PS-IGNORE

# Queues
DESNZ_NUCLEAR_CASES_TO_REVIEW = "f26cd433-b23c-4bb0-95d3-3def83f7fd19" # /PS-IGNORE
DESNZ_NUCLEAR_COUNTERSIGNING = "91213b45-f69f-492d-9d61-84e3a27cceb3" # /PS-IGNORE
DESNZ_CHEMICAL_CASES_TO_REVIEW = "58e79b78-8817-40d0-afb3-fda57978a502" # /PS-IGNORE
DESNZ_RUSSIA_SANCTIONS = "3ac48607-8102-49d9-bf49-55ef7b3cecef" # /PS-IGNORE
FCDO_CASES_TO_REVIEW_QUEUE = "f458094c-1fed-4222-ac70-ff5fa20ff649" # /PS-IGNORE
FCDO_COUNTERSIGNING_QUEUE = "5e772575-9ae4-4a16-b55b-7e1476d810c4" # /PS-IGNORE
FCDO_CPACC_CASES_TO_REVIEW_QUEUE = "a7ac8131-8eac-4dab-9eb1-aa2e9d0c0d42" # /PS-IGNORE
LU_POST_CIRC_FINALISE_QUEUE = "f0e7c2fa-100f-42ad-b740-bb072393e664" # /PS-IGNORE
LU_LICENSING_MANAGER_QUEUE = "9f5a2a93-03ed-4416-a8f8-8b728e5ea9d0" # /PS-IGNORE
LU_SR_LICENSING_MANAGER_QUEUE = "7b643901-565a-4ec8-8a7a-de34bc541a0e" # /PS-IGNORE
MOD_CAPPROT_CASES_TO_REVIEW = "93d1bc19-979d-4ba3-a57c-b0ce253c6237" # /PS-IGNORE
MOD_DI_DIRECT_CASES_TO_REVIEW = "c93f1e56-c577-4910-a01c-434e47ac6c9c" # /PS-IGNORE
MOD_DI_INDIRECT_CASES_TO_REVIEW = "0dd6c6f0-8f8b-4c03-b68f-0d8b04225369" # /PS-IGNORE
MOD_DSR_CASES_TO_REVIEW = "a84d6556-782e-4002-abe2-8bc1e5c2b162" # /PS-IGNORE
MOD_DSTL_CASES_TO_REVIEW = "1a5f47ee-ef5e-456b-914c-4fa629b4559c" # /PS-IGNORE
MOD_ECJU_REVIEW_AND_COMBINE = "432a8587-fc0e-4d34-9b50-92ad6d45bb16" # /PS-IGNORE
NCSC_CASES_TO_REVIEW = "bbfc426b-a1af-4a4c-a97b-ae1557de4210" # /PS-IGNORE


BULK_APPROVE_ALLOWED_QUEUES = (
MOD_CAPPROT_CASES_TO_REVIEW,
MOD_DI_DIRECT_CASES_TO_REVIEW,
MOD_DI_INDIRECT_CASES_TO_REVIEW,
MOD_DSR_CASES_TO_REVIEW,
MOD_DSTL_CASES_TO_REVIEW,
NCSC_CASES_TO_REVIEW,
)

DECISION_TYPE_VERB_MAPPING = {
"Approve": "approved",
"Proviso": "approved",
Expand Down
5 changes: 5 additions & 0 deletions caseworker/advice/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,11 @@ def unassessed_trigger_list_goods(case):
]


def post_bulk_approval_recommendation(request, queue_id, data):
response = client.post(request, f"/caseworker/queues/{queue_id}/bulk-approval/", data)
return response.json(), response.status_code


def get_advice_tab_context(case, caseworker, queue_id):
"""Get contextual information for the advice tab such as the tab's URL and
button visibility, based off the case, the current user and current user's queue.
Expand Down
73 changes: 73 additions & 0 deletions caseworker/advice/views/bulk_approval.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import rules

from http import HTTPStatus

from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.http import Http404, HttpResponseRedirect
from django.urls import reverse
from django.views import View


from caseworker.advice.services import post_bulk_approval_recommendation
from caseworker.users.services import get_gov_user

from core.auth.views import LoginRequiredMixin
from core.decorators import expect_status


class BulkApprovalView(LoginRequiredMixin, SuccessMessageMixin, View):
"""
Submit approval recommendation for the selected cases
"""

def dispatch(self, *args, **kwargs):

if not rules.test_rule("can_user_bulk_approve_cases", self.request, self.kwargs["pk"]):
raise Http404()
return super().dispatch(*args, **kwargs)

@property
def caseworker_id(self):
return str(self.request.session["lite_api_user_id"])

@property
def caseworker(self):
data, _ = get_gov_user(self.request, self.caseworker_id)
return data["user"]

def get_success_url(self):
return reverse("queues:cases", kwargs={"queue_pk": self.kwargs["pk"]})

@expect_status(
HTTPStatus.CREATED,
"Error submitting bulk approval recommendation",
"Unexpected error submitting bulk approval recommendation",
)
def submit_bulk_approval_recommendation(self, queue_id, payload):
return post_bulk_approval_recommendation(self.request, queue_id, payload)

def post(self, request, *args, **kwargs):
queue_id = self.kwargs["pk"]
cases = self.request.POST.getlist("cases", [])
payload = {
"cases": cases,
"advice": {
"text": "No concerns: Approved using bulk approval",
"proviso": "",
"note": "",
"footnote_required": False,
"footnote": "",
"team": str(self.caseworker["team"]["id"]),
},
}

self.submit_bulk_approval_recommendation(queue_id, payload)

num_cases = len(cases)
success_message = f"Successfully approved {num_cases} cases"
if num_cases == 1:
success_message = "Successfully approved 1 case"
messages.success(self.request, success_message)

return HttpResponseRedirect(self.get_success_url())
11 changes: 11 additions & 0 deletions caseworker/queues/rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import rules

from caseworker.advice.constants import BULK_APPROVE_ALLOWED_QUEUES


@rules.predicate
def can_user_bulk_approve_cases(request, queue_id):
return str(queue_id) in BULK_APPROVE_ALLOWED_QUEUES


rules.add_rule("can_user_bulk_approve_cases", can_user_bulk_approve_cases)
2 changes: 2 additions & 0 deletions caseworker/queues/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.urls import path

from caseworker.advice.views.bulk_approval import BulkApprovalView
from caseworker.queues.views import case_assignments, cases, enforcement, queues

app_name = "queues"
Expand Down Expand Up @@ -36,4 +37,5 @@
path(
"<uuid:pk>/enforcement-xml-import/", enforcement.EnforcementXMLImport.as_view(), name="enforcement_xml_import"
),
path("<uuid:pk>/bulk-approve/", BulkApprovalView.as_view(), name="bulk_approval"),
]
17 changes: 16 additions & 1 deletion caseworker/templates/queues/cases.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% extends 'layouts/base.html' %}

{% load svg static %}
{% load crispy_forms_tags %}
{% load crispy_forms_tags rules %}

{% block back_link %}{% endblock %}

Expand All @@ -15,7 +15,21 @@
</a>
</div>
{% if not queue.is_system_queue %}
{% test_rule 'can_user_bulk_approve_cases' request queue.id as can_user_bulk_approve_cases %}
<div class="lite-app-bar__controls lite-buttons-row" >
{% if can_user_bulk_approve_cases %}
<div data-enable-on-checkboxes="#table-cases">
<button
id="bulk-approve-button"
type="submit" class="govuk-button govuk-button--secondary"
form="form-cases"
formmethod="post"
formaction="{% url 'queues:bulk_approval' queue.id %}"
>
Approve
</button>
</div>
{% endif %}
<div data-enable-on-checkboxes="#table-cases">
<button id="assign-users-button" form="form-cases" type="submit" class="govuk-button govuk-button--secondary">{% lcs 'cases.CasesListPage.ALLOCATE_CASE' %}</button>
</div>
Expand Down Expand Up @@ -66,6 +80,7 @@
</div>

<form id="form-cases" method="get" action="{% url 'queues:case_assignment_select_role' queue.id %}">
{% csrf_token %}
{% if not data.results.cases %}
{% if tab_data.my_cases.is_selected %}
{% include "includes/notice.html" with text='cases.CasesListPage.NO_CASES_ALLOCATED' %}
Expand Down
1 change: 1 addition & 0 deletions conf/caseworker.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"caseworker.teams",
"caseworker.cases",
"caseworker.activities",
"caseworker.queues",
]

MIDDLEWARE += [
Expand Down
Loading

0 comments on commit 5a1a5a2

Please sign in to comment.