Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TP2000-1083: Quota order number create #1081

Merged
merged 11 commits into from
Nov 14, 2023
4 changes: 3 additions & 1 deletion common/jinja2/layouts/confirm.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
<div class="govuk-grid-column-two-thirds">
{% block panel %}{% endblock%}
<h2 class="govuk-heading-m">Next steps</h2>
<p class="govuk-body">To complete your task you must publish your change. </p>
{% block next_steps %}
<p class="govuk-body">To complete your task you must publish your change. </p>
{% endblock%}
<div>{% block main_button %}{% endblock%}</div>
{{ govukButton({
"text": "Go to your workbasket summary",
Expand Down
3 changes: 2 additions & 1 deletion common/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import factory
from factory.fuzzy import FuzzyChoice
from factory.fuzzy import FuzzyText
from faker import Faker

from common.models import TrackedModel
Expand Down Expand Up @@ -745,7 +746,7 @@ class Meta:
model = "quotas.QuotaOrderNumber"

sid = numeric_sid()
order_number = string_sequence(6, characters=string.digits)
order_number = FuzzyText(length=4, chars=string.digits, prefix="05")
mechanism = 0
category = 1
valid_between = date_ranges("big_no_end")
Expand Down
25 changes: 25 additions & 0 deletions measures/migrations/0015_alter_measure_dead_order_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 3.2.20 on 2023-10-31 15:16

import django.core.validators
from django.db import migrations
from django.db import models


class Migration(migrations.Migration):
dependencies = [
("measures", "0014_action_pair_data_migration"),
]

operations = [
migrations.AlterField(
model_name="measure",
name="dead_order_number",
field=models.CharField(
blank=True,
db_index=True,
max_length=6,
null=True,
validators=[django.core.validators.RegexValidator("^05[0-9]{4}$")],
),
),
]
129 changes: 120 additions & 9 deletions quotas/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from crispy_forms_gds.layout import Size
from crispy_forms_gds.layout import Submit
from django import forms
from django.core.exceptions import ValidationError
from django.template.loader import render_to_string
from django.urls import reverse_lazy

Expand All @@ -26,6 +27,13 @@
from quotas import validators
from quotas.constants import QUOTA_ORIGIN_EXCLUSIONS_FORMSET_PREFIX

CATEGORY_HELP_TEXT = "Categories are required for the TAP database but will not appear as a TARIC3 object in your workbasket"
SAFEGUARD_HELP_TEXT = (
"Once the quota category has been set as ‘Safeguard’, this cannot be changed"
)
START_DATE_HELP_TEXT = "If possible, avoid putting a start date in the past as this may cause issues with CDS downstream"
ORDER_NUMBER_HELP_TEXT = "The order number must begin with 05 and be 6 digits long. Licensed quotas must begin 054 and safeguards must begin 058"


class QuotaFilterForm(forms.Form):
def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -115,12 +123,6 @@ class QuotaUpdateForm(
ValidityPeriodForm,
forms.ModelForm,
):
CATEGORY_HELP_TEXT = "Categories are required for the TAP database but will not appear as a TARIC3 object in your workbasket"
SAFEGUARD_HELP_TEXT = (
"Once the quota category has been set as ‘Safeguard’, this cannot be changed"
)
START_DATE_HELP_TEXT = "If possible, avoid putting a start date in the past as this may cause issues with CDS downstream"

class Meta:
model = models.QuotaOrderNumber
fields = [
Expand Down Expand Up @@ -149,12 +151,12 @@ def init_fields(self):
attrs={"disabled": True},
choices=validators.QuotaCategory.choices,
)
self.fields["category"].help_text = self.SAFEGUARD_HELP_TEXT
self.fields["category"].help_text = SAFEGUARD_HELP_TEXT
else:
self.fields["category"].choices = validators.QuotaCategoryEditing.choices
self.fields["category"].help_text = self.CATEGORY_HELP_TEXT
self.fields["category"].help_text = CATEGORY_HELP_TEXT

self.fields["start_date"].help_text = self.START_DATE_HELP_TEXT
self.fields["start_date"].help_text = START_DATE_HELP_TEXT

def init_layout(self):
self.helper = FormHelper(self)
Expand Down Expand Up @@ -199,6 +201,115 @@ def init_layout(self):
)


class QuotaOrderNumberCreateForm(
ValidityPeriodForm,
forms.ModelForm,
):
class Meta:
model = models.QuotaOrderNumber
fields = [
"order_number",
"valid_between",
"category",
"mechanism",
]

order_number = forms.CharField(
help_text=ORDER_NUMBER_HELP_TEXT,
validators=[validators.quota_order_number_validator],
error_messages={
"invalid": "Order number must be six digits long and begin with 05",
"required": "Enter the order number",
},
)
category = forms.ChoiceField(
choices=validators.QuotaCategory.choices,
help_text=CATEGORY_HELP_TEXT,
error_messages={
"invalid_choice": "Please select a valid category",
"required": "Choose the category",
},
)
mechanism = forms.ChoiceField(
choices=validators.AdministrationMechanism.choices,
error_messages={
"invalid_choice": "Please select a valid mechanism",
"required": "Choose the mechanism",
},
)

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

def init_fields(self):
self.fields["start_date"].help_text = START_DATE_HELP_TEXT

def init_layout(self):
self.helper = FormHelper(self)
self.helper.label_size = Size.SMALL
self.helper.legend_size = Size.SMALL

self.helper.layout = Layout(
Accordion(
AccordionSection(
"Order number",
"order_number",
),
AccordionSection(
"Validity",
"start_date",
"end_date",
),
AccordionSection(
"Category and mechanism",
"category",
"mechanism",
),
css_class="govuk-width-!-two-thirds",
),
Submit(
"submit",
"Save",
data_module="govuk-button",
data_prevent_double_click="true",
),
)

def clean(self):
category = self.cleaned_data.get("category")
mechanism = self.cleaned_data.get("mechanism")
order_number = self.cleaned_data.get("order_number", "")

if (
mechanism is not None
and int(mechanism) == validators.AdministrationMechanism.LICENSED
):
if int(category) == validators.QuotaCategory.SAFEGUARD:
raise ValidationError(
"Mechanism cannot be set to licensed for safeguard quotas",
)
if not order_number.startswith("054"):
raise ValidationError(
"The order number for licensed quotas must begin with 054",
)

if (
category is not None
and int(
category,
)
== validators.QuotaCategory.SAFEGUARD
and not order_number.startswith("058")
):
raise ValidationError(
"The order number for safeguard quotas must begin with 058",
)

return super().clean()


class QuotaOrderNumberOriginForm(
FormSetSubmitMixin,
ValidityPeriodForm,
Expand Down
2 changes: 1 addition & 1 deletion quotas/jinja2/quota-definitions/confirm-create.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
{% block main_button %}
{{ govukButton({
"text": "Create another",
"href": url("quota_definition-ui-create", args=[object.order_number.sid]),
"href": object.get_url('create'),
"classes": "govuk-button--primary"
}) }}
{% endblock%}
Expand Down
41 changes: 41 additions & 0 deletions quotas/jinja2/quotas/confirm-create.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{% extends "common/confirm_create.jinja" %}
{% from "components/breadcrumbs.jinja" import breadcrumbs %}
{% from "components/button/macro.njk" import govukButton %}
{% from "components/warning-text/macro.njk" import govukWarningText %}


{% block breadcrumb %}
{{ breadcrumbs(request, [
{"text": "Find and edit quotas", "href": url("quota-ui-list")},
{"text": page_title}
])
}}
{% endblock %}

{% block next_steps %}
{{ govukWarningText({
"text": "Before you can associate this quota order number with a measure you will need to create a quota origin."
}) }}
{% endblock%}

{% block main_button %}
<div>
{{ govukButton({
"text": "Create a quota origin",
"href": url('quota_order_number_origin-ui-create', args=[object.sid]),
"classes": "govuk-button--primary"
}) }}
</div>
<div>
{{ govukButton({
"text": "Create another quota order number",
"href": object.get_url('create'),
"classes": "govuk-button--secondary"
}) }}
</div>
{% endblock%}

{% block actions %}
<li><a class="govuk-link" href="{{ object.get_url() }}">View this quota order number</a></li>
<li><a href="{{ object.get_url('list') }}">Find and edit quotas</a></li>
{% endblock %}
23 changes: 23 additions & 0 deletions quotas/migrations/0008_alter_quotaordernumber_order_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.20 on 2023-10-31 15:16

import django.core.validators
from django.db import migrations
from django.db import models


class Migration(migrations.Migration):
dependencies = [
("quotas", "0007_auto_20221130_1427"),
]

operations = [
migrations.AlterField(
model_name="quotaordernumber",
name="order_number",
field=models.CharField(
db_index=True,
max_length=6,
validators=[django.core.validators.RegexValidator("^05[0-9]{4}$")],
),
),
]
Loading
Loading