Skip to content

Commit

Permalink
Merge pull request #2006 from uktrade/uat
Browse files Browse the repository at this point in the history
PROD Release
  • Loading branch information
depsiatwal authored Jun 6, 2024
2 parents 6892eff + 92892de commit 08d69b8
Show file tree
Hide file tree
Showing 41 changed files with 351 additions and 175 deletions.
2 changes: 1 addition & 1 deletion caseworker/advice/templates/advice/case_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ <h3>{{ forloop.counter }}. {{ good.good.name }}</h3>
{% if case.data.denial_matches %}
{% for denial in case.data.denial_matches %}
<p>
<a href="{% url 'external_data:denial-detail' pk=denial.denial.id %}?queue_id={{queue.id}}&case_id={{case.id}}">
<a href="{% url 'external_data:denial-detail' pk=denial.denial_entity.id %}?queue_id={{queue.id}}&case_id={{case.id}}">
{{ denial.denial.reference }}
</a>
<span class="govuk-tag govuk-tag--grey govuk-!-margin-0">
Expand Down
2 changes: 1 addition & 1 deletion caseworker/advice/templatetags/advice_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def get_flags_list(flags):
def get_denial_references(denial_matches):
denial_references = []
for denial_match in denial_matches:
denial_references.append(denial_match["denial"]["reference"])
denial_references.append(denial_match["denial_entity"]["reference"])
return denial_references


Expand Down
6 changes: 5 additions & 1 deletion caseworker/cases/views/denials.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
from django.utils.functional import cached_property
from django.views.generic import FormView
from django.conf import settings

from core.auth.views import LoginRequiredMixin
from caseworker.cases.forms.denial_forms import DenialSearchForm
Expand Down Expand Up @@ -94,11 +95,14 @@ def get_context_data(self, **kwargs):
search_results, _ = search_denials(request=self.request, search=search, filter=filter)
total_pages = search_results.get("total_pages", 0)

return super().get_context_data(
context = super().get_context_data(
search_string=search,
case=self.case,
total_pages=total_pages,
search_results=search_results,
parties=self.parties_to_search,
search_score_feature_flag=settings.FEATURE_FLAG_DENIALS_SEARCH_SCORE,
**kwargs,
)

return context
4 changes: 3 additions & 1 deletion caseworker/cases/views/external_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class MatchingDenials(LoginRequiredMixin, View):
def post(self, request, **kwargs):
data = []
for match_id in request.POST.getlist("objects", []):
data.append({"application": str(kwargs["pk"]), "denial": match_id, "category": kwargs["category"]})
data.append({"application": str(kwargs["pk"]), "denial_entity": match_id, "category": kwargs["category"]})

response = client.post(request, f"/applications/{kwargs['pk']}/denial-matches/", data)
response.raise_for_status()
return redirect(
Expand All @@ -28,6 +29,7 @@ class RemoveMatchingDenials(LoginRequiredMixin, View):
def post(self, request, **kwargs):
data = {}
data["objects"] = request.POST.getlist("objects", [])

response = client.delete(request, f"/applications/{kwargs['pk']}/denial-matches/", data)
response.raise_for_status()
return redirect(
Expand Down
8 changes: 7 additions & 1 deletion caseworker/templates/case/denial-for-case.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ <h2 class="govuk-heading-l govuk-!-margin-top-6 govuk-!-margin-bottom-3">
<th scope="col" class="govuk-table__header">Item description</th>
<th scope="col" class="govuk-table__header">End use</th>
<th scope="col" class="govuk-table__header">Party type</th>
{% if search_score_feature_flag %}
<th scope="col" class="govuk-table__header">Search score</th>
{% endif %}
{% endif %}
</tr>
</thead>
Expand All @@ -100,7 +103,7 @@ <h2 class="govuk-heading-l govuk-!-margin-top-6 govuk-!-margin-bottom-3">
</td>
<td class="govuk-table__cell">

<a style="position: relative;" href="{% url 'external_data:denial-detail' pk=denial.id %}">{{ denial.regime_reg_ref }}</a>
<a style="position: relative;" href="{% url 'external_data:denial-detail' pk=denial.id %}">{{ denial.regime_reg_ref|safe }}</a>
</td>
<td class="govuk-table__cell">{{ denial.reference|sentence_case }}</td>
<td class="govuk-table__cell">{{ denial.name|safe }}</td>
Expand All @@ -110,6 +113,9 @@ <h2 class="govuk-heading-l govuk-!-margin-top-6 govuk-!-margin-bottom-3">
<td class="govuk-table__cell">{{ denial.item_description|safe }}</td>
<td class="govuk-table__cell">{{ denial.end_use }}</td>
<td class="govuk-table__cell">{{ denial.entity_type.value }}</td>
{% if search_score_feature_flag %}
<td class="govuk-table__cell">{{ denial.search_score }}</td>
{% endif %}
</tr>
{% endfor %}

Expand Down
8 changes: 4 additions & 4 deletions caseworker/templates/case/slices/denial-matches.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,20 @@ <h2 class="govuk-heading-m">Denial matches</h2>
<input class="govuk-checkboxes__input" type="checkbox" name="objects"
value="{{ match.id }}" id="{{ match.id }}">
<label class="govuk-label govuk-checkboxes__label" for="{{ match.id }}">{{
match.denial.regime_ref }}</label>
match.denial_entity.regime_reg_ref }}</label>
</div>
</td>
{% endif %}
<td class="govuk-table__cell">
<a href="{% url 'external_data:denial-detail' pk=match.denial.id %}?queue_id={{queue.id}}&case_id={{case.id}}">{{ match.denial.regime_reg_ref }}</a><br>
<a href="{% url 'external_data:denial-detail' pk=match.denial_entity.id %}?queue_id={{queue.id}}&case_id={{case.id}}">{{ match.denial_entity.regime_reg_ref }}</a><br>
{% if match.category == "exact" %}
<strong class="govuk-tag govuk-tag--grey">FULL MATCH</strong>
{% elif match.category == "partial" %}
<strong class="govuk-tag govuk-tag--grey">POSSIBLE MATCH</strong>
{% endif %}
</td>
<td class="govuk-table__cell">{{ match.denial.name }}</td>
<td class="govuk-table__cell">{{ match.denial.address }}</td>
<td class="govuk-table__cell">{{ match.denial_entity.regime_reg_ref }}</td>
<td class="govuk-table__cell">{{ match.denial_entity.address }}</td>
</tr>
{% endfor %}
</tbody>
Expand Down
2 changes: 1 addition & 1 deletion caseworker/templates/external_data/help-build-query.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="govuk-details__text">
<p>To manual edit your query, use name’, ‘address or denial_cle or 'item_description' to search a specific category.</p>
<p>To manually edit your query, use 'name', 'address' or 'denial_cle' or 'item_description' or 'regime_reg_ref' to search a specific category.</p>
<p>Use AND between keywords to search for results matching both keywords. For example, name:(Oliver) AND name:(Smith) to search for both Oliver and Smith.</p>
<p>Use OR between keywords to find products matching either keyword.</p>
<p>Use NOT to exclude keywords from search results.</p>
Expand Down
3 changes: 2 additions & 1 deletion ci.exporter.env
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ SsF52iSXTw==
TOKEN_SESSION_KEY=exporter_token_session_key

MOCK_SSO_ACTIVATE_ENDPOINTS=True
MOCK_SSO_USER_EMAIL=[email protected]
MOCK_SSO_USER_FIRST_NAME=LITE
MOCK_SSO_USER_LAST_NAME=Testing

EXPORTER_TEST_SSO_EMAIL="[email protected]"

# Below values can be found in vault
export EXPORTER_AUTHBROKER_CLIENT_ID=
export EXPORTER_AUTHBROKER_CLIENT_SECRET=
Expand Down
5 changes: 3 additions & 2 deletions conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,11 @@
ACCEPTED_FILE_UPLOAD_MIME_TYPES = env.list(
"ACCEPTED_FILE_UPLOAD_MIME_TYPES",
default=(
# Default file-types supported by LITE are pdf, doc, docx,
# rtf, jpeg, png and tiff
# Default file types supported by LITE are
# DOCX, DOC, PDF, PNG, JPEG, ODT
"application/pdf",
"application/msword",
"application/vnd.oasis.opendocument.text",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/rtf",
"application/xml",
Expand Down
1 change: 1 addition & 0 deletions conf/caseworker.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
}

FEATURE_FLAG_PRODUCT_SEARCH = env.bool("FEATURE_FLAG_PRODUCT_SEARCH", False)
FEATURE_FLAG_DENIALS_SEARCH_SCORE = env.bool("FEATURE_FLAG_DENIALS_SEARCH_SCORE", False)

# Application Performance Monitoring
if env.str("ELASTIC_APM_SERVER_URL", ""):
Expand Down
54 changes: 24 additions & 30 deletions exporter/applications/forms/common.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from django import forms

from django.urls import reverse_lazy

from exporter.applications.forms.edit import told_by_an_official_form, reference_name_form
Expand All @@ -8,7 +10,6 @@
Form,
BackLink,
TextArea,
RadioButtons,
Option,
FormGroup,
TextInput,
Expand All @@ -17,35 +18,8 @@
Checkboxes,
)
from lite_forms.helpers import conditional


def edit_type_form(application_id):
return Form(
title=strings.Applications.Edit.TITLE,
description=strings.Applications.Edit.DESCRIPTION,
questions=[
RadioButtons(
name="edit-type",
options=[
Option(
key="minor",
value=strings.Applications.Edit.Minor.TITLE,
description=strings.Applications.Edit.Minor.DESCRIPTION,
),
Option(
key="major",
value=strings.Applications.Edit.Major.TITLE,
description=strings.Applications.Edit.Major.DESCRIPTION,
),
],
)
],
back_link=BackLink(
strings.BACK_TO_APPLICATION,
reverse_lazy("applications:application", kwargs={"pk": application_id}),
),
default_button_name=strings.CONTINUE,
)
from crispy_forms_gds.helper import FormHelper
from crispy_forms_gds.layout import Submit


def application_copy_form(application_type=None):
Expand Down Expand Up @@ -130,3 +104,23 @@ def declaration_form(application_id):
),
javascript_imports={"/javascripts/declaration.js"},
)


class EditApplicationForm(forms.Form):
CHOICES = [
("minor", "Delete a product, third party or country"),
("major", "Add a product or edit something else"),
]
edit_type = forms.ChoiceField(
choices=CHOICES,
widget=forms.RadioSelect,
label="",
error_messages={
"required": "Please select an option to proceed.",
},
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.add_input(Submit("submit", "Continue"))
8 changes: 4 additions & 4 deletions exporter/applications/forms/parties.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from core.common.forms import BaseForm
from core.forms.layouts import ConditionalRadios, ConditionalRadiosQuestion
from core.forms.widgets import Autocomplete
from exporter.core.constants import CaseTypes
from exporter.core.constants import CaseTypes, FileUploadFileTypes
from exporter.core.services import get_countries
from lite_content.lite_exporter_frontend import strings
from lite_content.lite_exporter_frontend.applications import PartyForm, PartyTypeForm
Expand Down Expand Up @@ -351,7 +351,7 @@ def clean(self):
class PartyDocumentUploadForm(forms.Form):
title = "Upload an end-user document"
party_document = forms.FileField(
label="Upload a DOCX, DOC, PDF or PNG file.",
label=FileUploadFileTypes.UPLOAD_GUIDANCE_TEXT,
error_messages={
"required": "Select an end-user document",
},
Expand Down Expand Up @@ -407,7 +407,7 @@ def __init__(self, edit, *args, **kwargs):
class PartyEnglishTranslationDocumentUploadForm(forms.Form):
title = "Upload an English translation"
party_eng_translation_document = forms.FileField(
label="Upload a DOCX, DOC, PDF or PNG file.",
label=FileUploadFileTypes.UPLOAD_GUIDANCE_TEXT,
error_messages={
"required": "Select an English translation",
},
Expand All @@ -432,7 +432,7 @@ def __init__(self, edit, *args, **kwargs):
class PartyCompanyLetterheadDocumentUploadForm(forms.Form):
title = "Upload a document on company letterhead"
party_letterhead_document = forms.FileField(
label="Upload a DOCX, DOC, PDF or PNG file.",
label=FileUploadFileTypes.UPLOAD_GUIDANCE_TEXT,
error_messages={
"required": "Select a document on company letterhead",
},
Expand Down
27 changes: 27 additions & 0 deletions exporter/applications/templates/edit_application_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% extends 'layouts/base.html' %}
{% load crispy_forms_tags crispy_forms_gds %}

{% block title%}How do you want to edit the application?{% endblock %}

{% block back_link %}
<a href="{% url 'applications:application' application_id %}" id="back-link" class="govuk-back-link">Back</a>
{% endblock %}

{% block body %}

{% error_summary form %}

<h1 class="govuk-heading-l">How do you want to edit the application?</h1>
<p class="govuk-hint">
If you make changes, it will take longer to process your application.<br>
You cannot edit a product, only add a new one or remove an existing one.
</p>
<div class="govuk-body govuk-!-margin-bottom-4">
<a class="govuk-link" href="{% url 'exporter-help-support' %}">Contact us if you need help editing your application</a>.
</div>
<form method="post">
{% csrf_token %}
{% crispy form %}
</form>

{% endblock %}
44 changes: 20 additions & 24 deletions exporter/applications/views/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
surrender_application_confirmation,
)
from exporter.applications.forms.common import (
edit_type_form,
EditApplicationForm,
application_copy_form,
exhibition_details_form,
declaration_form,
Expand Down Expand Up @@ -57,7 +57,6 @@
from exporter.core.services import get_organisation
from lite_content.lite_exporter_frontend import strings
from lite_forms.generators import confirm_form
from lite_forms.generators import form_page
from lite_forms.views import SingleFormView, MultiFormView
from exporter.applications.forms.hcsat import HCSATminiform
from core.auth.views import LoginRequiredMixin
Expand Down Expand Up @@ -108,34 +107,31 @@ def get_success_url(self):
return self.request.GET.get("return_to")


class ApplicationEditType(LoginRequiredMixin, TemplateView):
def get(self, request, **kwargs):
application_id = str(kwargs["pk"])
data = get_application(request, application_id)

if data.get("status") and data.get("status").get("key") == APPLICANT_EDITING:
return redirect(reverse_lazy("applications:task_list", kwargs={"pk": application_id}))
class ApplicationEditType(LoginRequiredMixin, FormView):
form_class = EditApplicationForm
template_name = "edit_application_form.html"

return form_page(request, edit_type_form(application_id))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)

def post(self, request, **kwargs):
application_id = str(kwargs["pk"])
edit_type = request.POST.get("edit-type")
self.application_id = str(self.kwargs["pk"])
self.data = get_application(self.request, self.application_id)

if edit_type == "major":
data, status_code = set_application_status(request, str(kwargs["pk"]), APPLICANT_EDITING)
context.update(
{
"application_id": self.application_id,
"data": self.data,
}
)
return context

if status_code != HTTPStatus.OK:
return form_page(request, edit_type_form(str(kwargs["pk"])), errors=data)
def form_valid(self, form):

elif edit_type is None:
return form_page(
request,
edit_type_form(application_id),
errors={"edit-type": ["Select the type of edit you need to make"]},
)
self.application_id = str(self.kwargs["pk"])
if form.cleaned_data.get("edit_type") == "major":
set_application_status(self.request, self.application_id, APPLICANT_EDITING)

return redirect(reverse_lazy("applications:task_list", kwargs={"pk": str(kwargs["pk"])}))
return HttpResponseRedirect(reverse_lazy("applications:task_list", kwargs={"pk": self.application_id}))


class ApplicationTaskList(LoginRequiredMixin, TemplateView):
Expand Down
4 changes: 4 additions & 0 deletions exporter/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,7 @@ class OrganisationStatus:
DRAFT = "draft"
REVIEW = "in_review"
ACTIVE = "active"


class FileUploadFileTypes:
UPLOAD_GUIDANCE_TEXT = "Upload a DOCX, DOC, PDF, PNG, JPEG or ODT file."
5 changes: 4 additions & 1 deletion exporter/core/organisation/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ def validate_website(value):
validator = URLValidator()
validator(value)
except ValidationError:
raise ValidationError("Enter a valid URL")
try:
validator("https://" + value)
except ValidationError:
raise ValidationError("Enter a valid URL")
return value


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
<p class="govuk-body">
Control lists determine whether a product is controlled and requires a licence to export.
</p>

<a class="govuk-link" href="https://www.gov.uk/guidance/uk-strategic-export-control-lists-the-consolidated-list-of-strategic-military-and-dual-use-items" target="_blank">
Guidance - control lists (opens in new tab)
</a>
<p class="govuk-body"><a class="govuk-link" href="https://www.gov.uk/government/publications/uk-strategic-export-control-lists-the-consolidated-list-of-strategic-military-and-dual-use-items-that-require-export-authorisation" target="_blank">Control lists</a> (opens in new tab) determine whether a product is controlled and requires a licence to export.</p>
<p class="govuk-body">If the product is not subject to any controls, you'll be issued with a 'no licence required' document.</p>
Loading

0 comments on commit 08d69b8

Please sign in to comment.