Skip to content

Commit

Permalink
Merge pull request #2205 from uktrade/uat
Browse files Browse the repository at this point in the history
PROD Release
  • Loading branch information
depsiatwal authored Oct 17, 2024
2 parents c97f166 + b49976c commit 9b11580
Show file tree
Hide file tree
Showing 34 changed files with 891 additions and 700 deletions.
4 changes: 3 additions & 1 deletion caseworker/core/services.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from cacheops import cached
from collections import defaultdict
from django.conf import settings

from caseworker.advice.services import LICENSING_UNIT_TEAM
from caseworker.cases.constants import CaseType
Expand Down Expand Up @@ -133,7 +134,8 @@ def get_user_role_name(request):
return user["user"]["role"]["name"]


@cached(timeout=CONTROL_LIST_ENTRIES_CACHE_TIMEOUT)
# Vary the cache by GIT_COMMIT sha - to invalidate the cache on release
@cached(timeout=CONTROL_LIST_ENTRIES_CACHE_TIMEOUT, extra=settings.GIT_COMMIT)
def get_control_list_entries(request, include_non_selectable_for_assessment=False):
url = "/caseworker/static/control-list-entries/"
if include_non_selectable_for_assessment:
Expand Down
3 changes: 3 additions & 0 deletions conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"django_chunk_upload_handlers",
"rules.apps.AutodiscoverRulesConfig",
"extra_views",
"cacheops",
]

MIDDLEWARE = [
Expand Down Expand Up @@ -333,3 +334,5 @@ def show_toolbar(request):

# GA/GTM KEY
GTM_ID = env.str("GTM_ID", default="")

GIT_COMMIT = env.str("GIT_COMMIT", default="")
3 changes: 2 additions & 1 deletion conf/caseworker.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@
}
}

CACHEOPS_REDIS = REDIS_URL
# Ensure cache on separate redis DB
CACHEOPS_REDIS = f"{REDIS_URL}/2"

FEATURE_FLAG_PRODUCT_SEARCH = env.bool("FEATURE_FLAG_PRODUCT_SEARCH", False)
FEATURE_FLAG_DENIALS_SEARCH_SCORE = env.bool("FEATURE_FLAG_DENIALS_SEARCH_SCORE", False)
Expand Down
5 changes: 2 additions & 3 deletions conf/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@

LOGIN_REDIRECT_URL = reverse_lazy("core:home")

FEATURE_FLAG_DJANGO_FORMS_REGISTRATION_ENABLED = env.bool("FEATURE_FLAG_DJANGO_FORMS_REGISTRATION_ENABLED", True)

LOGOUT_URL = urljoin(AUTHBROKER_URL, "logout")
AUTHBROKER_SCOPE = "openid,email,offline_access"
AUTHBROKER_AUTHORIZATION_URL = urljoin(AUTHBROKER_URL, "authorize")
Expand Down Expand Up @@ -106,7 +104,8 @@
}
}

CACHEOPS_REDIS = REDIS_URL
# Ensure cache on separate redis DB
CACHEOPS_REDIS = f"{REDIS_URL}/2"

# Application Performance Monitoring
if env.str("ELASTIC_APM_SERVER_URL", ""):
Expand Down
5 changes: 4 additions & 1 deletion core/common/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self, *args, **kwargs):
self.helper.attrs = {"enctype": "multipart/form-data"}
break

title = self.Layout.TITLE
title = self.get_title()
if hasattr(self.Layout, "TITLE_AS_LABEL_FOR"):
id_for_label = self[self.Layout.TITLE_AS_LABEL_FOR].id_for_label
title = f'<label for="{id_for_label}">{title}</label>'
Expand All @@ -46,6 +46,9 @@ def __init__(self, *args, **kwargs):
),
)

def get_title(self):
return self.Layout.TITLE

def get_layout_fields(self):
raise NotImplementedError(f"Implement `get_layout_fields` on {self.__class__.__name__}")

Expand Down
2 changes: 1 addition & 1 deletion core/feedback/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class FeedbackForm(BaseForm):
class Layout:
TITLE = "Leave feedback"
TITLE = "Leave Feedback"
SUBMIT_BUTTON_TEXT = "Submit"

feedback = forms.CharField(label="", widget=forms.Textarea)
Expand Down
22 changes: 22 additions & 0 deletions core/wizard/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import logging

from django.views.generic import FormView

from formtools.wizard.views import SessionWizardView

from .storage import NoSaveStorage


logger = logging.getLogger(__name__)


class BaseSessionWizardView(SessionWizardView):
file_storage = NoSaveStorage()
template_name = "core/form-wizard.html"
Expand All @@ -15,6 +20,23 @@ def get_cleaned_data_for_step(self, step):
return {}
return cleaned_data

def get_context_data(self, form, **kwargs):
context = super().get_context_data(form, **kwargs)

try:
context["title"] = form.get_title()
except AttributeError:
pass

return context

def render_to_response(self, context):
if "title" not in context:
logger.warning("No title set for `%s`", context["form"].__class__.__name__)
elif not context["title"]:
logger.warning("Title set but blank for `%s`", context["form"].__class__.__name__)
return super().render_to_response(context)


class StepEditView(FormView):
template_name = "core/form.html"
Expand Down
131 changes: 95 additions & 36 deletions exporter/applications/forms/parties.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from core.forms.widgets import Autocomplete
from exporter.core.constants import CaseTypes, FileUploadFileTypes
from exporter.core.services import get_countries
from exporter.core.validators import PartyAddressValidator, PartyNameValidator
from lite_content.lite_exporter_frontend import strings
from lite_content.lite_exporter_frontend.applications import PartyForm, PartyTypeForm
from lite_forms.common import country_question
Expand Down Expand Up @@ -133,8 +132,10 @@ def new_party_form_group(request, application, strings, back_url, clearance_opti
return FormGroup(forms)


class PartyReuseForm(forms.Form):
title = "Do you want to reuse an existing party?"
class PartyReuseForm(BaseForm):
class Layout:
TITLE = "Do you want to reuse an existing party?"
TITLE_AS_LABEL_FOR = "reuse_party"

reuse_party = forms.ChoiceField(
choices=(
Expand All @@ -148,19 +149,15 @@ class PartyReuseForm(forms.Form):
},
)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.helper = FormHelper()
self.helper.layout = Layout(
HTML.h1(self.title),
"reuse_party",
Submit("submit", "Continue"),
)
def get_layout_fields(self):
return ("reuse_party",)


class PartySubTypeSelectForm(forms.Form):
title = "Select the type of end user"
class PartySubTypeSelectForm(BaseForm):
"""
This form needs to be instantiated with a Layout.TITLE for the type of party whose data is being set
as per the BaseForm.
"""

CHOICES = (
Choice("government", PartyForm.Options.GOVERNMENT),
Expand All @@ -179,20 +176,15 @@ class PartySubTypeSelectForm(forms.Form):
)
sub_type_other = forms.CharField(required=False, label="")

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.helper = FormHelper()
self.helper.layout = Layout(
HTML.h1(self.title),
def get_layout_fields(self):
return (
ConditionalRadios(
"sub_type",
PartyForm.Options.GOVERNMENT,
PartyForm.Options.COMMERCIAL,
PartyForm.Options.INDIVIDUAL,
ConditionalRadiosQuestion(PartyForm.Options.OTHER, "sub_type_other"),
),
Submit("submit", "Continue"),
)

def clean(self):
Expand All @@ -204,10 +196,23 @@ def clean(self):
return cleaned_data


class PartyNameForm(BaseForm):
class EndUserSubTypeSelectForm(PartySubTypeSelectForm):
class Layout:
TITLE = "End user name"
TITLE_AS_LABEL_FOR = "name"
TITLE = "Select the type of end user"
TITLE_AS_LABEL_FOR = "sub_type"


class ConsigneeSubTypeSelectForm(PartySubTypeSelectForm):
class Layout:
TITLE = "Select the type of consignee"
TITLE_AS_LABEL_FOR = "sub_type"


class PartyNameForm(BaseForm):
"""
This form needs to be instantiated with a Layout.TITLE for the type of party whose data is being set
as per the BaseForm.
"""

name = forms.CharField(
label="",
Expand All @@ -217,20 +222,37 @@ class Layout:
80,
f"End user name should be 80 characters or less",
),
PartyNameValidator(),
],
)

def get_layout_fields(self):
return ("name",)


class PartyWebsiteForm(BaseForm):
class EndUserNameForm(PartyNameForm):
class Layout:
TITLE = "End user website address (optional)"
TITLE_AS_LABEL_FOR = "website"
TITLE = "End user name"
TITLE_AS_LABEL_FOR = "name"

website = forms.CharField(required=False, label="", help_text="Use the format https://www.example.com")

class ConsigneeNameForm(PartyNameForm):
class Layout:
TITLE = "Consignee name"
TITLE_AS_LABEL_FOR = "name"


class PartyWebsiteForm(BaseForm):
"""
This form needs to be instantiated with a Layout.TITLE for the type of party whose data is being set
as per the BaseForm.
"""

website = forms.CharField(
required=False,
label="",
help_text="Use the format https://www.example.com",
validators=[MaxLengthValidator(200, f"Website address should be 200 characters or less")],
)

def clean_website(self):
website = self.cleaned_data.get("website")
Expand All @@ -257,14 +279,27 @@ def get_layout_fields(self):
return ("website",)


class PartyAddressForm(BaseForm):
class EndUserWebsiteForm(PartyWebsiteForm):
class Layout:
TITLE = "End user address"
TITLE = "End user website address (optional)"
TITLE_AS_LABEL_FOR = "website"


class ConsigneeWebsiteForm(PartyWebsiteForm):
class Layout:
TITLE = "Consignee website address (optional)"
TITLE_AS_LABEL_FOR = "website"


class PartyAddressForm(BaseForm):
"""
This form needs to be instantiated with a Layout.TITLE for the type of party whose data is being set
as per the BaseForm.
"""

address = forms.CharField(
widget=forms.Textarea(attrs={"rows": "10"}),
error_messages={"required": "Enter an address"},
validators=[PartyAddressValidator()],
)
country = forms.ChoiceField(
choices=[("", "Select a country")], error_messages={"required": "Select the country"}
Expand All @@ -287,6 +322,18 @@ def get_layout_fields(self):
)


class EndUserAddressForm(PartyAddressForm):
class Layout:
TITLE = "End user address"
TITLE_AS_LABEL_FOR = "address"


class ConsigneeAddressForm(PartyAddressForm):
class Layout:
TITLE = "Consignee address"
TITLE_AS_LABEL_FOR = "address"


class PartySignatoryNameForm(BaseForm):
class Layout:
TITLE = "Signatory name"
Expand All @@ -306,10 +353,10 @@ class PartyDocumentsForm(forms.Form):
title = "Do you have an end-user document?"
text_p1 = """
You will be asked to upload either an
<a class="govuk-link" target="_blank" href="https://www.gov.uk/government/publications/end-user-undertaking-euu-form">
end-user undertaking (opens in new tab)</a> or
<a class="govuk-link" target="_blank" href="https://www.gov.uk/government/publications/stockist-undertaking-su-form">
stockist undertaking (opens in new tab)</a> completed by the end-user or stockist.
<a class="govuk-link" target="_blank" href="https://www.gov.uk/government/publications/end-user-undertaking-euu-form">
end-user undertaking (opens in new tab)</a> or
<a class="govuk-link" target="_blank" href="https://www.gov.uk/government/publications/stockist-undertaking-su-form">
stockist undertaking (opens in new tab)</a> completed by the end-user or stockist.
"""
text_p2 = "You must include at least one page on company letterhead. This can either be within the end-user document or on a separate document."
text_p3 = (
Expand Down Expand Up @@ -365,6 +412,9 @@ def clean(self):

return cleaned_data

def get_title(self):
return self.title


class PartyDocumentUploadForm(forms.Form):
title = "Upload an end-user document"
Expand Down Expand Up @@ -421,6 +471,9 @@ def __init__(self, edit, *args, **kwargs):
Submit("submit", "Continue"),
)

def get_title(self):
return self.title


class PartyEnglishTranslationDocumentUploadForm(forms.Form):
title = "Upload an English translation"
Expand All @@ -446,6 +499,9 @@ def __init__(self, edit, *args, **kwargs):
Submit("submit", "Continue"),
)

def get_title(self):
return self.title


class PartyCompanyLetterheadDocumentUploadForm(forms.Form):
title = "Upload a document on company letterhead"
Expand All @@ -471,6 +527,9 @@ def __init__(self, edit, *args, **kwargs):
Submit("submit", "Continue"),
)

def get_title(self):
return self.title


class PartyEC3DocumentUploadForm(forms.Form):
title = "Upload an EC3 form (optional)"
Expand Down
Loading

0 comments on commit 9b11580

Please sign in to comment.