diff --git a/commodities/filters.py b/commodities/filters.py index 31aa18234..16a9f294f 100644 --- a/commodities/filters.py +++ b/commodities/filters.py @@ -9,6 +9,7 @@ from commodities.models.orm import GoodsNomenclature from common.filters import ActiveStateMixin from common.filters import CurrentWorkBasketMixin +from common.filters import EndDateMixin from common.filters import TamatoFilter from common.filters import TamatoFilterBackend from common.validators import AlphanumericValidator @@ -33,9 +34,14 @@ def search_queryset(self, queryset, search_term): return super().search_queryset(queryset, search_term) -class CommodityFilter(ActiveStateMixin, TamatoFilter, CurrentWorkBasketMixin): +class CommodityFilter( + ActiveStateMixin, + TamatoFilter, + CurrentWorkBasketMixin, + EndDateMixin, +): item_id = CharFilter( - label="Code", + label="Commodity code", widget=forms.TextInput(), lookup_expr="startswith", validators=[NumericValidator], diff --git a/commodities/forms.py b/commodities/forms.py index 9d5895a70..2992b5038 100644 --- a/commodities/forms.py +++ b/commodities/forms.py @@ -24,15 +24,28 @@ def __init__(self, *args, **kwargs): self.helper.layout = Layout( Field.text("item_id", label_size=Size.SMALL), Field.text("descriptions__description", label_size=Size.SMALL), - Field.text("active_state", label_size=Size.SMALL), + Field.checkboxes( + "active_state", + legend_size=Size.SMALL, + ), Fieldset( Field.text("with_footnotes", label_size=Size.SMALL), legend="Footnotes", + legend_size=Size.SMALL, + ), + Fieldset( + Field.text("with_end_date", label_size=Size.SMALL), + legend="End date", + legend_size=Size.SMALL, + ), + Fieldset( + Field.text("current_work_basket", label_size=Size.SMALL), + legend="Workbasket", + legend_size=Size.SMALL, ), - Field.text("current_work_basket", label_size=Size.SMALL), Button( "submit", - "Search and Filter", + "Search and filter", ), HTML( f' Clear ', diff --git a/commodities/jinja2/includes/commodities/table.jinja b/commodities/jinja2/includes/commodities/table.jinja index c8c047835..2375e01ca 100644 --- a/commodities/jinja2/includes/commodities/table.jinja +++ b/commodities/jinja2/includes/commodities/table.jinja @@ -15,6 +15,8 @@ {"text": commodity.suffix}, {"text": commodity.get_indent_as_at(today).indent}, {"text": commodity.get_description().description}, + {"text": "{:%d %b %Y}".format(commodity.valid_between.lower)}, + {"text": "{:%d %b %Y}".format(commodity.valid_between.upper) if commodity.valid_between.upper else "-"}, {"text": commodity_footnotes}, ]) or "" }} {% endfor %} @@ -24,6 +26,8 @@ {"text": "Suffix"}, {"text": "Indent"}, {"text": "Commodity description"}, + {"text": "Start date"}, + {"text": "End date"}, {"text": "Footnotes"}, ], diff --git a/commodities/tests/test_views.py b/commodities/tests/test_views.py index 02bf7ae01..3e026ed63 100644 --- a/commodities/tests/test_views.py +++ b/commodities/tests/test_views.py @@ -27,6 +27,7 @@ def test_commodity_list_displays_commodity_suffix_indent_and_description( valid_user_client, + date_ranges, ): """Test that a list of commodity codes with links and their suffixes, indents and descriptions are displayed on the list view template.""" @@ -37,6 +38,9 @@ def test_commodity_list_displays_commodity_suffix_indent_and_description( description="A second commodity code description", ).described_goods_nomenclature + commodity2.valid_between = date_ranges.normal + commodity2.save(force_write=True) + url = reverse("commodity-ui-list") response = valid_user_client.get(url) page = BeautifulSoup( @@ -51,6 +55,10 @@ def test_commodity_list_displays_commodity_suffix_indent_and_description( text=commodity1.get_indent_as_at(datetime.date.today()).indent, ) assert page.find("tbody").find("td", text="A commodity code description") + assert page.find("tbody").find( + "td", + text=f"{commodity1.valid_between.lower:%d %b %Y}", + ) assert page.find("tbody").find("td", text=commodity2.item_id) assert page.find("tbody").find(href=f"/commodities/{commodity2.sid}/") @@ -60,6 +68,14 @@ def test_commodity_list_displays_commodity_suffix_indent_and_description( text=commodity2.get_indent_as_at(datetime.date.today()).indent, ) assert page.find("tbody").find("td", text="A second commodity code description") + assert page.find("tbody").find( + "td", + text=f"{commodity2.valid_between.lower:%d %b %Y}", + ) + assert page.find("tbody").find( + "td", + text=f"{commodity2.valid_between.upper:%d %b %Y}", + ) def test_commodity_list_queryset(): diff --git a/common/filters.py b/common/filters.py index c453109a5..e5a0c1663 100644 --- a/common/filters.py +++ b/common/filters.py @@ -248,7 +248,7 @@ class ActiveStateMixin(FilterSet): widget=forms.CheckboxSelectMultiple, method="filter_active_state", label="Active state", - help_text="Select all that apply", + help_text="Select one to filter by active or terminated items", required=False, ) @@ -348,3 +348,19 @@ def filter_work_basket(self, queryset, name, value): id__in=wanted_objects_id, ) return queryset + + +class EndDateMixin(FilterSet): + """A filter to only show objects which have an end date.""" + + with_end_date = BooleanFilter( + label="Show items with an end date", + widget=forms.CheckboxInput(), + method="filter_end_date", + required=False, + ) + + def filter_end_date(self, queryset, name, value): + if value: + queryset = queryset.filter(valid_between__upper_inf=False) + return queryset diff --git a/common/static/common/scss/_components.scss b/common/static/common/scss/_components.scss index c6c0606dd..a0b8ed9d9 100644 --- a/common/static/common/scss/_components.scss +++ b/common/static/common/scss/_components.scss @@ -161,3 +161,7 @@ .homepage-workbasket-action { width: 100%; } + +.govuk-checkboxes__label:before { + background-color: white +} diff --git a/quotas/tests/test_forms.py b/quotas/tests/test_forms.py index 2a51525e5..8550aa46c 100644 --- a/quotas/tests/test_forms.py +++ b/quotas/tests/test_forms.py @@ -794,21 +794,22 @@ def test_sub_quota_update_form_valid(session_request_with_workbasket, sub_quota) sub_quota_relation_type="EQ", coefficient=1.5, ) - - form = forms.SubQuotaDefinitionAssociationUpdateForm( - instance=sub_quota, - request=session_request_with_workbasket, - sid=sub_quota.sid, - ) - assert float(form.fields["coefficient"].initial) == association.coefficient - assert ( - form.fields["relationship_type"].initial == association.sub_quota_relation_type - ) - assert form.fields["measurement_unit"].initial == sub_quota.measurement_unit - assert form.fields["initial_volume"].initial == sub_quota.initial_volume - assert form.fields["volume"].initial == sub_quota.volume - assert form.fields["start_date"].initial == sub_quota.valid_between.lower - assert form.fields["end_date"].initial == sub_quota.valid_between.upper + with override_current_transaction(Transaction.objects.last()): + form = forms.SubQuotaDefinitionAssociationUpdateForm( + instance=sub_quota, + request=session_request_with_workbasket, + sid=sub_quota.sid, + ) + assert float(form.fields["coefficient"].initial) == association.coefficient + assert ( + form.fields["relationship_type"].initial + == association.sub_quota_relation_type + ) + assert form.fields["measurement_unit"].initial == sub_quota.measurement_unit + assert form.fields["initial_volume"].initial == sub_quota.initial_volume + assert form.fields["volume"].initial == sub_quota.volume + assert form.fields["start_date"].initial == sub_quota.valid_between.lower + assert form.fields["end_date"].initial == sub_quota.valid_between.upper data = { "start_date_0": sub_quota.valid_between.lower.day,