Skip to content

Commit

Permalink
TP2000-1475-Edit-sub-quotas (#1287)
Browse files Browse the repository at this point in the history
* duplicating definitions form wizard

* temp conflict resolution - check

* initial journey working; todo: debug sub-quotas view page; todo: big refactor/tidy; todo: confirm styling matches design

* adding validity checks to Quota Association edit form; some tidying up

* conforming main/sub-quota language; removing comments; adding measurement_unit_code to dict; refactoring de/serializers to serializers.py

* alinging styles

* adding form reset button

* pause

* tests: get_cleaned_data_for_step, get_form_kwargs, edit view renders

* refactored business rule validations to business_rules.py; tests; notes

* correcting parent_definition to main_definition; squashing migrations

* correcting parent_definition to main_definition; squashing migrations

* adding check for definition data status; tidying up

* formatting

* adding tests for business rules; TODO: re-check QA5 requirements

* fixing test

* - fixes linting

* updates to QA5 checks - in progress

* fixing and testing QA5

* test for QA6

* tests

* removing comments

* date formatter

* adding initial volume; adding breadcrumbs

* responding to PR comments

* adding button group; cleaning up set_duplicate_definitions

* PR comments pt 2

* responding to PR comments 3

* corrected title

* Replace radio buttons for tabs

* Add test and match figma design

* response to Pauls CR pt 1

* factoring out of business rules checks to avoid duplication

* removing model, using session

* wizard file

* tests for forms using session

* black formatting

* adding tests for session use; correcting sid to pk

* removing model & migration

* fixing test params

* Basic functioning sub quota edit form

* Add helper for latest version of object

* adding validation to require at least one definition to be selected

* copy changes from chat with Ash; removed storage_name from update form

* Swapped main_quota for get_main_definition for consistency

* Content updates

* Make sub-quotas heading consistent

* black

* Undo some for compatibility with create journey

* Tidy up to match master

* Ensure correct association selection

* Use latest version up to transaction

* Tidy up

* Form tests not working

* Form tests done

* View tests

* Test sub-quota edit url

* Add test for get_association_edit_url

* Edie PR comments

* Hyphen sub-quotas

* Change to current, fix association bug

---------

Co-authored-by: Charles Prichard <[email protected]>
Co-authored-by: Charlie Prichard <[email protected]>
Co-authored-by: tommacca <[email protected]>
  • Loading branch information
4 people authored Sep 26, 2024
1 parent 387dfd5 commit dc84c03
Show file tree
Hide file tree
Showing 12 changed files with 714 additions and 36 deletions.
2 changes: 1 addition & 1 deletion quotas/business_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ def validate(self, quota_definition):
class QuotaAssociationMustReferToANonDeletedSubQuota(
PreventDeletingLinkedQuotaDefinitions,
):
"""A Quota Association must refer to a non-deleted sub quota."""
"""A Quota Association must refer to a non-deleted sub-quota."""

sid_prefix = "sub_quota__"

Expand Down
60 changes: 59 additions & 1 deletion quotas/forms.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from datetime import date

from crispy_forms_gds.helper import FormHelper
from crispy_forms_gds.layout import HTML
from crispy_forms_gds.layout import Accordion
Expand Down Expand Up @@ -1110,6 +1112,9 @@ def clean(self):
class SubQuotaDefinitionsUpdatesForm(
ValidityPeriodForm,
):
"""Form used to edit duplicated sub-quota definitions and associations as
part of the sub-quota create journey."""

class Meta:
model = models.QuotaDefinition
fields = [
Expand Down Expand Up @@ -1162,6 +1167,7 @@ class Meta:
)

measurement_unit = forms.ModelChoiceField(
label="Measurement unit",
queryset=MeasurementUnit.objects.current().order_by("code"),
error_messages={"required": "Select the measurement unit"},
)
Expand Down Expand Up @@ -1223,7 +1229,7 @@ def clean(self):
main_definition_valid_between=original_definition.valid_between,
):
raise ValidationError(
"QA2: Validity period for sub quota must be within the "
"QA2: Validity period for sub-quota must be within the "
"validity period of the main quota",
)

Expand Down Expand Up @@ -1337,3 +1343,55 @@ def init_layout(self, request):
),
),
)


class SubQuotaDefinitionAssociationUpdateForm(SubQuotaDefinitionsUpdatesForm):
"""Form used to update sub-quota definitions and associations as part of the
edit sub-quotas journey."""

def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request", None)
self.workbasket = self.request.user.current_workbasket
sub_quota_definition_sid = kwargs.pop("sid")
ValidityPeriodForm.__init__(self, *args, **kwargs)
self.sub_quota = models.QuotaDefinition.objects.current().get(
sid=sub_quota_definition_sid,
)
self.init_fields()
self.set_initial_data()
self.init_layout(self.request)

def set_initial_data(self):
association = models.QuotaAssociation.objects.current().get(
sub_quota__sid=self.sub_quota.sid,
)
self.original_definition = association.main_quota
fields = self.fields
fields["relationship_type"].initial = association.sub_quota_relation_type
fields["coefficient"].initial = association.coefficient
fields["measurement_unit"].initial = self.sub_quota.measurement_unit
fields["initial_volume"].initial = self.sub_quota.initial_volume
fields["volume"].initial = self.sub_quota.volume
fields["start_date"].initial = self.sub_quota.valid_between.lower
fields["end_date"].initial = self.sub_quota.valid_between.upper

def init_fields(self):
super().init_fields()
if self.sub_quota.valid_between.lower <= date.today():
self.fields["coefficient"].disabled = True
self.fields["relationship_type"].disabled = True
self.fields["start_date"].disabled = True
self.fields["initial_volume"].disabled = True
self.fields["volume"].disabled = True
self.fields["measurement_unit"].disabled = True


class QuotaAssociationEdit(forms.ModelForm):
class Meta:
model = models.QuotaAssociation
fields = [
"sub_quota_relation_type",
"coefficient",
"main_quota",
"sub_quota",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{% extends "common/confirm_update.jinja" %}
{% from "components/breadcrumbs.jinja" import breadcrumbs %}


{% set page_title = "Sub-quota definition and association updated" %}

{% block breadcrumb %}
{{ breadcrumbs(request, [
{"text": "Find and edit quotas", "href": url("quota-ui-list")},
{"text": "Quota " ~ association.main_quota.order_number, "href": association.main_quota.order_number.get_url()},
{"text": "Quota " ~ association.main_quota.order_number ~ " - Data", "href": url("quota_definition-ui-list", kwargs={"sid":association.main_quota.order_number.sid})},
{"text": page_title},
])
}}
{% endblock %}


{% block panel %}
{{ govukPanel({
"titleText": "Sub-" ~ object._meta.verbose_name ~ ": " ~ object|string,
"text": "Sub-" ~ object._meta.verbose_name ~ ": " ~ object|string ~ " and association have been updated in workbasket " ~ request.user.current_workbasket.pk,
"classes": "govuk-!-margin-bottom-7"
}) }}
{% endblock %}

{% block button_group %}
{{ govukButton({
"text": "View workbasket summary",
"href": url("workbaskets:current-workbasket"),
"classes": "govuk-button"
}) }}
{{ govukButton({
"text": "Return to main quota",
"href": association.main_quota.order_number.get_url(),
"classes": "govuk-button--secondary"
}) }}
{% endblock %}

{% block actions %}
<li><a class="govuk-link" href="{{ object.order_number.get_url() }}">View this sub-quota definition's quota order number</a></li>
<li><a href="{{ object.order_number.get_url('list') }}">Find and edit quotas</a></li>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{% extends "layouts/form.jinja" %}
{% from "components/breadcrumbs.jinja" import breadcrumbs %}

{% from "components/table/macro.njk" import govukTable %}

{% set page_title = "Update sub-quota definition and association" %}

{% block content %}
<h2 class="govuk-heading">Main quota definition details</h2>
{% set main_definition = view.get_main_definition() %}
Expand Down
13 changes: 9 additions & 4 deletions quotas/jinja2/quotas/tables/sub_quotas.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,32 @@
{% set sub_quota_link -%}
<a class="govuk-link" href="{{ url('quota-ui-detail', args=[object.sub_quota.order_number.sid]) }}">{{ object.sub_quota.order_number.order_number }}</a>
{% endset %}
{% set edit_link -%}
<a class="govuk-link" href="{{ object.sub_quota.version_at(request.user.current_workbasket.transactions.last()).get_association_edit_url() }}">Edit</a>
{% endset %}
{{ table_rows.append([
{"text": definition_link },
{"text": sub_quota_link },
{"text": "{:%d %b %Y}".format(object.sub_quota.valid_between.lower) },
{"text": "{:%d %b %Y}".format(object.sub_quota.valid_between.upper) if object.sub_quota.valid_between.upper else "-"},
{"text": "{:%d %b %Y}".format(object.sub_quota.version_at(request.user.current_workbasket.transactions.last()).valid_between.lower) },
{"text": "{:%d %b %Y}".format(object.sub_quota.version_at(request.user.current_workbasket.transactions.last()).valid_between.upper) if object.sub_quota.valid_between.upper else "-"},
{"text": object.get_sub_quota_relation_type_display() },
{"text": object.coefficient },
{"text": edit_link },
]) or "" }}
{% endfor %}

{{ govukTable({
"head": [
{"text": "Quota definition sid"},
{"text": "Sub quota order number"},
{"text": "Sub-quota order number"},
{"text": "Start date"},
{"text": "End date"},
{"text": "Relation type"},
{"text": "Coefficient"},
{"text": "Actions"},
],
"rows": table_rows
}) }}
{% else %}
<p class="govuk-body">There are no sub quotas for this quota order number.</p>
<p class="govuk-body">There are no sub-quotas for this quota order number.</p>
{% endif %}
20 changes: 20 additions & 0 deletions quotas/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,26 @@ def get_url(self, action: str = "detail") -> Optional[str]:
def slugify_model_name(cls):
return cls._meta.verbose_name.replace(" ", "_")

def get_association_edit_url(self):
"""Get the edit url for the sub-quota definition and association edit
journey by checking if it has been updated in an 'EDITING' status
workbasket."""
url = "sub_quota_definition-edit"
try:
if self.transaction.workbasket.status == WorkflowStatus.EDITING:
# There is no edit-create journey for quota definitions so edits of a
# newly created object will add a new update object to the workbasket
if self.update_type == UpdateType.UPDATE:
url += "-update"

url = reverse(
url,
kwargs={"sid": self.sid},
)
return url
except NoReverseMatch:
return None


class QuotaAssociation(TrackedModel):
"""The quota association defines the relation between quota and sub-
Expand Down
Loading

0 comments on commit dc84c03

Please sign in to comment.