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-1537 Bulk create QuotaDefinitionPeriods #1320

Merged
merged 39 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
62f11d8
formatting
CPrich905 Nov 11, 2024
811af31
Merge branch 'master' into TP2000-1537-bulk-create-definition-periods
CPrich905 Nov 11, 2024
8139a2d
notes
CPrich905 Nov 11, 2024
f269c6c
tests
CPrich905 Nov 13, 2024
a2468e8
moar tests
CPrich905 Nov 14, 2024
667f909
tests and tidying
CPrich905 Nov 18, 2024
abcbd18
wizard view test
CPrich905 Nov 19, 2024
e0304cd
working through changes from redesign
CPrich905 Nov 25, 2024
84b4dcc
adding custom widget for decimal suffix
CPrich905 Nov 28, 2024
86cd34f
working through copy updates to bulk and single create process
CPrich905 Dec 3, 2024
f47ffea
copy updates
CPrich905 Dec 3, 2024
413fb7e
resolving conflicts
CPrich905 Dec 3, 2024
d03864f
post pair
CPrich905 Dec 5, 2024
b828488
Fix test
eadpearce Dec 5, 2024
06c61c2
fixing review styling
CPrich905 Dec 5, 2024
19fb387
success page copy changes; resolving serializing unit qualifier bug; …
CPrich905 Dec 6, 2024
d3c07f8
validation and requiring refactor
CPrich905 Dec 10, 2024
61105de
reformat links and link_text
CPrich905 Dec 10, 2024
9a2cdea
tests and refactors
CPrich905 Dec 12, 2024
79818c4
testing form.is_valid
CPrich905 Dec 13, 2024
03a386f
views.py tests
CPrich905 Dec 16, 2024
0d8e749
Merge branch 'master' into TP2000-1537-bulk-create-definition-periods
CPrich905 Dec 17, 2024
988f3ee
wip - testing views get_form_kwargs
CPrich905 Dec 17, 2024
c81dacb
Merge branch 'master' into TP2000-1537-bulk-create-definition-periods
CPrich905 Dec 17, 2024
c8b8674
tests
CPrich905 Dec 18, 2024
3c08652
tidying up
CPrich905 Dec 18, 2024
9e1659f
tidying up and tests
CPrich905 Dec 19, 2024
8e1c336
Merge branch 'master' into TP2000-1537-bulk-create-definition-periods
CPrich905 Dec 20, 2024
1b0147a
Fix transaction error
eadpearce Dec 20, 2024
eb1c7c7
missing jinja files
CPrich905 Dec 30, 2024
c1b65b0
removing extra template file
CPrich905 Dec 30, 2024
5e01055
first round of CR changes
CPrich905 Dec 31, 2024
87db359
first round of CR changes
CPrich905 Dec 31, 2024
7913ba6
fix for order_number hidden widget not populating
CPrich905 Jan 2, 2025
087ff53
Merge branch 'master' into TP2000-1537-bulk-create-definition-periods
CPrich905 Jan 2, 2025
0dec77a
fixing broken tests
CPrich905 Jan 2, 2025
114cee9
CR comments R2
CPrich905 Jan 7, 2025
a9bb1a6
Merge branch 'master' into TP2000-1537-bulk-create-definition-periods
CPrich905 Jan 7, 2025
f11e4e7
fixing broken test
CPrich905 Jan 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions common/static/common/scss/_quota-definitions.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,10 @@

.definition-original {
color: $govuk-secondary-text-colour;
}

.bulk-create-review {
details.govuk-details[open] {
height: 420px !important;
}
}
16 changes: 16 additions & 0 deletions common/templates/common/widgets/decimal_suffix.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="govuk-input__wrapper">
<input
class="numberinput govuk-input govuk-input govuk-input--width-2"
type="{{ widget.type }}"
name="{{ widget.name }}"
{% if widget.value != None %}
value="{{ widget.value|stringformat:'s' }}"
{% endif %}
{% include "django/forms/widgets/attrs.html" %}>
{% if widget.suffix %}
<div class="govuk-input__suffix" aria-hidden="true">{{widget.suffix}}</div>
{% endif %}
<label{% if widget.attrs.id %} id="{{ widget.attrs.id }}-label" for="{{ widget.attrs.id }}"{% endif %} class="govuk-label">
{{ widget.label }}
</label>
</div>
20 changes: 20 additions & 0 deletions common/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,23 @@ class MultipleFileInput(FileInput):
"""Enable multiple files to be selected using FileInput widget."""

allow_multiple_selected = True


class DecimalSuffix(widgets.NumberInput):
"""Identical to the Decimal widget but allows the addition of a suffix."""

template_name = "common/widgets/decimal_suffix.html"

def __init__(self, attrs=None, suffix="", **kwargs):
self.suffix = suffix
super().__init__(attrs, **kwargs)

def render(self, name, value, attrs=None, renderer=None):
if attrs is None:
attrs = {}
context = self.get_context(name, value, attrs)
if self.suffix:
context["widget"]["suffix"] = self.suffix

template = loader.get_template(self.template_name).render(context)
return mark_safe(template)
128 changes: 90 additions & 38 deletions quotas/forms/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

from crispy_forms_gds.helper import FormHelper
from crispy_forms_gds.layout import HTML
from crispy_forms_gds.layout import Accordion
from crispy_forms_gds.layout import AccordionSection
from crispy_forms_gds.layout import Div
from crispy_forms_gds.layout import Field
from crispy_forms_gds.layout import Layout
Expand All @@ -14,6 +12,7 @@

from common.forms import ValidityPeriodForm
from common.serializers import deserialize_date
from common.widgets import DecimalSuffix
from measures.models import MeasurementUnit
from quotas import business_rules
from quotas import models
Expand Down Expand Up @@ -145,6 +144,7 @@ class QuotaDefinitionCreateForm(
class Meta:
model = models.QuotaDefinition
fields = [
"order_number",
"valid_between",
"description",
"volume",
Expand All @@ -156,9 +156,14 @@ class Meta:
"maximum_precision",
]

order_number = forms.ModelChoiceField(
queryset=models.QuotaOrderNumber.objects.current(),
widget=forms.HiddenInput(),
)
description = forms.CharField(label="", widget=forms.Textarea(), required=False)
volume = forms.DecimalField(
label="Current volume",
help_text="The current volume is the starting balance for the quota",
widget=forms.TextInput(),
error_messages={
"invalid": "Volume must be a number",
Expand All @@ -167,20 +172,22 @@ class Meta:
)
initial_volume = forms.DecimalField(
widget=forms.TextInput(),
help_text="The initial volume is the legal balance applied to the definition period",
error_messages={
"invalid": "Initial volume must be a number",
"required": "Enter the initial volume",
},
)
measurement_unit = forms.ModelChoiceField(
queryset=MeasurementUnit.objects.current(),
empty_label="Choose measurement unit",
error_messages={"required": "Select the measurement unit"},
)

quota_critical_threshold = forms.DecimalField(
label="Threshold",
widget=DecimalSuffix(suffix="%"),
help_text="The point at which this quota definition period becomes critical, as a percentage of the total volume.",
widget=forms.TextInput(),
error_messages={
"invalid": "Critical threshold must be a number",
"required": "Enter the critical threshold",
Expand All @@ -199,13 +206,21 @@ class Meta:
)

def __init__(self, *args, **kwargs):
self.buttons = kwargs.pop("buttons", None)
self.order_number = kwargs.pop("order_number", None)
super().__init__(*args, **kwargs)
self.init_layout()
self.init_fields()

def clean(self):
cleaned_data = super().clean()
"""The "order_number" field is hidden, but is not correctly populated by
.initial when creating a single QuotaDefinitionPeriod."""
if "order_number" in self.errors:
self.cleaned_data["order_number"] = self.order_number
self.errors.pop("order_number")
validators.validate_quota_volume(self.cleaned_data)
return super().clean()
return cleaned_data

def init_fields(self):
# This is always set to 3 for current definitions
Expand All @@ -230,50 +245,87 @@ def init_fields(self):
lambda obj: f"{obj.code} - {obj.description}"
)

def init_layout(self):
self.fields["end_date"].help_text = ""
self.fields["end_date"].required = True
self.fields["measurement_unit_qualifier"].help_text = (
"A measurement unit qualifier is not always required."
)
self.fields["measurement_unit_qualifier"].empty_label = (
"Choose measurement unit qualifier."
)

def init_layout(self, *args, **kwargs):
self.helper = FormHelper(self)
self.helper.label_size = Size.SMALL
self.helper.legend_size = Size.SMALL

link_text = self.buttons["link_text"]
link = self.buttons["link"]
self.helper.layout = Layout(
Accordion(
AccordionSection(
"Description",
HTML.p("Adding a description is optional."),
"description",
"order_number",
Div(
HTML(
'<h3 class="govuk-heading">Validity period</h3>',
),
AccordionSection(
"Validity period",
"start_date",
"end_date",
"start_date",
"end_date",
),
HTML(
"<br />",
),
Div(
HTML(
'<h3 class="govuk-heading">Measurements</h3>',
),
AccordionSection(
"Measurements",
HTML.p("A measurement unit qualifier is not always required."),
Field("measurement_unit", css_class="govuk-!-width-full"),
Field("measurement_unit_qualifier", css_class="govuk-!-width-full"),
Field("measurement_unit", css_class="govuk-!-width-two-thirds"),
Field(
"measurement_unit_qualifier",
css_class="govuk-!-width-two-thirds",
),
AccordionSection(
"Volume",
HTML.p(
"The initial volume is the legal balance applied to the definition period.<br><br>The current volume is the starting balance for the quota.",
),
"initial_volume",
"volume",
"maximum_precision",
),
HTML(
"<br />",
),
Div(
HTML(
'<h3 class="govuk-heading">Volume</h3>',
),
Field("initial_volume", css_class="govuk-!-width-one-third"),
Field("volume", css_class="govuk-!-width-one-third"),
"maximum_precision",
),
HTML(
"<br />",
),
Div(
HTML(
'<h3 class="govuk-heading">Criticality</h3>',
),
AccordionSection(
"Criticality",
"quota_critical_threshold",
"quota_critical",
"quota_critical_threshold",
"quota_critical",
),
HTML(
"<br />",
),
Div(
HTML(
'<h3 class="govuk-heading">Description</h3>',
),
HTML.p("Adding a description is optional."),
Field("description", css_class="govuk-!-width-two-thirds"),
),
Submit(
"submit",
"Save",
data_module="govuk-button",
data_prevent_double_click="true",
HTML(
"<br />",
),
Div(
Submit(
"submit",
self.buttons["submit"],
data_module="govuk-button",
data_prevent_double_click="true",
),
HTML(
f'<a class="govuk-link" href={link}>{link_text}</a>',
),
css_class="govuk-button-group",
),
)

Expand Down
Loading
Loading