Skip to content

Commit

Permalink
ECIL-342 CPTPP country group, banner for CFS apps and submit validation
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeylockwood committed Dec 23, 2024
1 parent 740dbcb commit cf8c8b3
Showing 13 changed files with 1,562 additions and 1,344 deletions.
6 changes: 6 additions & 0 deletions pii-ner-exclude.txt
Original file line number Diff line number Diff line change
@@ -5214,3 +5214,9 @@ eml
gif
jpeg
jpg
CPTPP
Progressive Agreement for Trans-Pacific Partnership
Comprehensive and Progressive Agreement for Trans-Pacific Partnership
checkIsEUCosmeticsRegulation(legislations
Trans-Pacific Partnership
CPTTP
28 changes: 28 additions & 0 deletions web/domains/case/export/forms.py
Original file line number Diff line number Diff line change
@@ -14,6 +14,10 @@

import web.forms.widgets as icms_widgets
from web.domains.case.forms import application_contacts
from web.domains.country.utils import (
get_cptpp_countries_list,
get_selected_cptpp_countries,
)
from web.domains.file.utils import ICMSFileField
from web.forms.mixins import OptionalFormMixin
from web.forms.widgets import ICMSModelSelect2Widget
@@ -353,6 +357,30 @@ class SubmitCFSForm(EditCFSFormBase):
All fields are fully validated to ensure form is correct.
"""

def clean(self) -> dict[str, Any]:
cleaned_data: dict[str, Any] = super().clean()

# Check that cosmetics aren't being exported to countries within the CPTPP
# This may want to be moved to the schedule level rather than the application level
has_cosmetics = self.instance.schedules.filter(
legislations__is_eu_cosmetics_regulation=True
).exists()

cptpp_selected = get_selected_cptpp_countries(cleaned_data["countries"])

if has_cosmetics and cptpp_selected.exists():
cptpp_countries_list = get_cptpp_countries_list()
self.add_error(
"countries",
(
f"This application is not necessary. A Certificate of Free Sale (CFS) for cosmetic "
f"products is no longer required for {cptpp_countries_list} due to the UK’s accession to "
f"the Comprehensive and Progressive Agreement for Trans-Pacific Partnership (CPTPP)."
),
)

return cleaned_data


class CFSScheduleFormBase(forms.ModelForm):
class Meta:
15 changes: 13 additions & 2 deletions web/domains/case/export/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import NamedTuple

from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin
@@ -26,6 +27,10 @@
view_application_file,
)
from web.domains.cat.utils import template_in_user_templates
from web.domains.country.utils import (
get_cptpp_countries_list,
get_selected_cptpp_countries_list,
)
from web.domains.file.utils import create_file_model
from web.flow.models import ProcessTypes
from web.models import (
@@ -362,6 +367,7 @@ def edit_cfs(request: AuthenticatedHttpRequest, *, application_pk: int) -> HttpR
"form": form,
"schedules": schedules,
"case_type": "export",
"cptpp_countries_list": get_cptpp_countries_list(),
}

return render(request, "web/domains/case/export/cfs-edit.html", context)
@@ -426,13 +432,14 @@ def cfs_edit_schedule(
else:
form = EditCFSScheduleForm(**form_kwargs)

schedule_legislations = schedule.legislations.filter(is_active=True)

show_schedule_statements_is_responsible_person = (
get_show_schedule_statements_is_responsible_person(schedule)
)

schedule_legislations = schedule.legislations.filter(is_active=True)
has_cosmetics = schedule_legislations.filter(is_eu_cosmetics_regulation=True).exists()
legislation_config = get_csf_schedule_legislation_config()
cptpp_countries_list = get_selected_cptpp_countries_list(application.countries.all())

context = {
"page_title": "Edit Schedule",
@@ -460,6 +467,9 @@ def cfs_edit_schedule(
"export:cfs-schedule-manage-products",
kwargs={"application_pk": application.pk, "schedule_pk": schedule.pk},
),
"show_cptpp_warning": has_cosmetics and cptpp_countries_list,
"cptpp_countries_list": cptpp_countries_list,
"ilb_contact_email": settings.ILB_CONTACT_EMAIL,
}

return render(request, "web/domains/case/export/cfs-edit-schedule.html", context)
@@ -845,6 +855,7 @@ def _get_cfs_errors(application: CertificateOfFreeSaleApplication) -> Applicatio

# Check that the schedule has products if legislation has been set
schedule_legislations = schedule.legislations.filter(is_active=True)

if schedule_legislations.exists() and not schedule.products.exists():
product_page_errors = PageErrors(
page_name=f"Schedule {idx} - Product",
3 changes: 3 additions & 0 deletions web/domains/country/managers.py
Original file line number Diff line number Diff line change
@@ -169,3 +169,6 @@ def get_eu_countries(self) -> QuerySet["Country"]:

def get_non_eu_countries(self) -> QuerySet["Country"]:
return self._get_country_group_countries(CountryGroupName.NON_EU)

def get_cptpp_countries(self) -> QuerySet["Country"]:
return self._get_country_group_countries(CountryGroupName.CPTPP)
1 change: 1 addition & 0 deletions web/domains/country/types.py
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@ class CountryGroupName(TypedTextChoices):
#
EU = "EU", "All EU countries"
NON_EU = "NON_EU", "Non EU Single Countries"
CPTPP = "CPTPP", "Comprehensive and Progressive Agreement for Trans-Pacific Partnership"

#
# Inactive Import Applications
26 changes: 26 additions & 0 deletions web/domains/country/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from django.db.models import QuerySet

from .models import Country


def comma_separator(sequence: list) -> str:
if not sequence:
return ""
if len(sequence) == 1:
return sequence[0]
return "{} and {}".format(", ".join(sequence[:-1]), sequence[-1])


def get_cptpp_countries_list() -> str:
cptpp = Country.util.get_cptpp_countries().values_list("name", flat=True)
return comma_separator(list(cptpp))


def get_selected_cptpp_countries(countries: QuerySet["Country"]) -> QuerySet["Country"]:
country_pks = countries.values_list("pk", flat=True)
return Country.util.get_cptpp_countries().filter(pk__in=country_pks)


def get_selected_cptpp_countries_list(countries: QuerySet["Country"]) -> str:
selected_countries = get_selected_cptpp_countries(countries)
return comma_separator(list(selected_countries.values_list("name", flat=True)))
Loading

0 comments on commit cf8c8b3

Please sign in to comment.