diff --git a/.sanitizerconfig b/.sanitizerconfig index fc48ac74b..b2de98372 100644 --- a/.sanitizerconfig +++ b/.sanitizerconfig @@ -372,7 +372,7 @@ strategy: name_fi: null name_sv: null need_manual_confirmation: null - people_capacity: null + people_capacity_lower: null public: null reservable: null reservable_days_in_advance: null diff --git a/locale/fi/LC_MESSAGES/django.po b/locale/fi/LC_MESSAGES/django.po index 4351c02db..5871022bd 100644 --- a/locale/fi/LC_MESSAGES/django.po +++ b/locale/fi/LC_MESSAGES/django.po @@ -1180,6 +1180,9 @@ msgstr "Tunnistautuminen" msgid "People capacity" msgstr "Henkilömäärä" +msgid "People capacity upper limit" +msgstr "Maksimihenkilömäärä" + msgid "Area (m2)" msgstr "Pinta-ala (m2)" diff --git a/locale/sv/LC_MESSAGES/django.po b/locale/sv/LC_MESSAGES/django.po index 19ef60a43..c3d04105f 100644 --- a/locale/sv/LC_MESSAGES/django.po +++ b/locale/sv/LC_MESSAGES/django.po @@ -1050,6 +1050,9 @@ msgstr "Autentisering" msgid "People capacity" msgstr "Kapacitet" +msgid "People capacity upper limit" +msgstr "Maximal kapacitet" + msgid "Area (m2)" msgstr "Yta (m2)" diff --git a/openapi.yaml b/openapi.yaml index 3b28da599..21d4fd633 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -526,7 +526,7 @@ paths: in: query description: Order queryset by given resource fields, accepted values are `resource_name_fi`, `resource_name_en`, `resource_name_sv`, `unit_name_fi`, - `unit_name_en`, `unit_name_sv`, `type`, `people_capacity`. Prefix parameter + `unit_name_en`, `unit_name_sv`, `type`, `people_capacity_lower`. Prefix parameter value with `-` to get reverse ordering. schema: type: string @@ -1043,7 +1043,7 @@ components: authentication: type: string description: The type of authentication required to reserve the resource - people_capacity: + people_capacity_lower: type: number description: The maximum number of people for the resource area: diff --git a/resources/api/resource.py b/resources/api/resource.py index 906011019..d990094e2 100644 --- a/resources/api/resource.py +++ b/resources/api/resource.py @@ -198,6 +198,7 @@ class ResourceSerializer( ExtraDataMixin, TranslatedModelSerializer, munigeo_api.GeoModelSerializer ): purposes = PurposeSerializer(many=True) + people_capacity = serializers.IntegerField(source='people_capacity_lower') images = NestedResourceImageSerializer(many=True) equipment = ResourceEquipmentSerializer( many=True, read_only=True, source="resource_equipment" @@ -676,9 +677,7 @@ def __init__(self, *args, **kwargs): type = django_filters.Filter( field_name="type__id", lookup_expr="in", widget=django_filters.widgets.CSVWidget ) - people = django_filters.NumberFilter( - field_name="people_capacity", lookup_expr="gte" - ) + people = django_filters.NumberFilter(method='filter_people_capacity') need_manual_confirmation = django_filters.BooleanFilter( field_name="need_manual_confirmation", widget=DRFFilterBooleanWidget ) @@ -721,11 +720,16 @@ def __init__(self, *args, **kwargs): ("type__name_fi", "type_name_fi"), ("type__name_en", "type_name_en"), ("type__name_sv", "type_name_sv"), - ("people_capacity", "people_capacity"), + ("people_capacity_lower", "people_capacity_lower"), ("accessibility_priority", "accessibility"), ), ) + def filter_people_capacity(self, queryset, name, value): + return queryset.filter( + Q(people_capacity_lower__gte=value) | Q(people_capacity_upper__gte=value) + ) + def filter_is_favorite(self, queryset, name, value): if not self.user.is_authenticated: if value: diff --git a/resources/importer/kirjasto10.py b/resources/importer/kirjasto10.py index 80101d9f1..38ea16571 100644 --- a/resources/importer/kirjasto10.py +++ b/resources/importer/kirjasto10.py @@ -94,9 +94,9 @@ def import_resources(self): except ValueError: area = None try: - people_capacity = int(res_data['Max henkilömäärä']) + people_capacity_lower = int(res_data['Max henkilömäärä']) except ValueError: - people_capacity = None + people_capacity_lower = None try: min_period = datetime.timedelta(minutes=int(60 * float(res_data['Varausaika min'].replace(',', '.')))) except ValueError: @@ -119,7 +119,7 @@ def import_resources(self): data = dict( unit_id=unit.pk, - people_capacity=people_capacity, + people_capacity_lower=people_capacity_lower, area=area, need_manual_confirmation=confirm, min_period=min_period, diff --git a/resources/migrations/0129_rename_people_capacity.py b/resources/migrations/0129_rename_people_capacity.py new file mode 100644 index 000000000..0aca609e7 --- /dev/null +++ b/resources/migrations/0129_rename_people_capacity.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.11 on 2025-01-09 10:15 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('resources', '0128_equipment_active'), + ] + + operations = [ + migrations.RenameField( + model_name='resource', + old_name='people_capacity', + new_name='people_capacity_lower', + ), + ] diff --git a/resources/migrations/0130_resource_people_capacity_upper.py b/resources/migrations/0130_resource_people_capacity_upper.py new file mode 100644 index 000000000..b0dc3b614 --- /dev/null +++ b/resources/migrations/0130_resource_people_capacity_upper.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.11 on 2025-01-09 11:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('resources', '0129_rename_people_capacity'), + ] + + operations = [ + migrations.AddField( + model_name='resource', + name='people_capacity_upper', + field=models.PositiveIntegerField(blank=True, null=True, verbose_name='People capacity upper limit'), + ), + ] diff --git a/resources/models/resource.py b/resources/models/resource.py index f81c50480..3e9f4737c 100644 --- a/resources/models/resource.py +++ b/resources/models/resource.py @@ -332,9 +332,12 @@ class Resource(ModifiableModel, AutoIdentifiedModel): max_length=20, choices=AUTHENTICATION_TYPES, ) - people_capacity = models.PositiveIntegerField( + people_capacity_lower = models.PositiveIntegerField( verbose_name=_("People capacity"), null=True, blank=True ) + people_capacity_upper = models.PositiveIntegerField( + verbose_name=_("People capacity upper limit"), null=True, blank=True + ) area = models.PositiveIntegerField( verbose_name=_("Area (m2)"), null=True, blank=True ) diff --git a/resources/tests/test_resource_api.py b/resources/tests/test_resource_api.py index f1f5d0581..877b2fcf0 100644 --- a/resources/tests/test_resource_api.py +++ b/resources/tests/test_resource_api.py @@ -1487,34 +1487,34 @@ def test_order_by_filter(list_url, api_client, resource_in_unit, resource_in_uni assert response.data["results"][0]["type"]["id"] == resource_in_unit2.type.id # test resource people capacity - resource_in_unit.people_capacity = 1 + resource_in_unit.people_capacity_lower = 1 resource_in_unit.save() - resource_in_unit2.people_capacity = 50 + resource_in_unit2.people_capacity_lower = 50 resource_in_unit2.save() - response = api_client.get("%s?order_by=people_capacity" % list_url) + response = api_client.get("%s?order_by=people_capacity_lower" % list_url) assert response.status_code == 200 assert_response_objects(response, [resource_in_unit, resource_in_unit2]) assert ( - response.data["results"][0]["people_capacity"] - == resource_in_unit.people_capacity + response.data["results"][0]["people_capacity_lower"] + == resource_in_unit.people_capacity_lower ) assert ( - response.data["results"][1]["people_capacity"] - == resource_in_unit2.people_capacity + response.data["results"][1]["people_capacity_lower"] + == resource_in_unit2.people_capacity_lower ) - response = api_client.get("%s?order_by=-people_capacity" % list_url) + response = api_client.get("%s?order_by=-people_capacity_lower" % list_url) assert response.status_code == 200 assert_response_objects(response, [resource_in_unit, resource_in_unit2]) assert ( - response.data["results"][1]["people_capacity"] - == resource_in_unit.people_capacity + response.data["results"][1]["people_capacity_lower"] + == resource_in_unit.people_capacity_lower ) assert ( - response.data["results"][0]["people_capacity"] - == resource_in_unit2.people_capacity + response.data["results"][0]["people_capacity_lower"] + == resource_in_unit2.people_capacity_lower ) @@ -1645,3 +1645,30 @@ def test_query_counts( with django_assert_max_num_queries(MAX_QUERIES): staff_api_client.get(list_url) + +@pytest.mark.django_db +def test_filter_people_capacity(api_client, resource_in_unit, resource_in_unit2, resource_in_unit3): + resource_in_unit.people_capacity_lower = 10 + resource_in_unit.people_capacity_upper = 20 + resource_in_unit.save() + + resource_in_unit2.people_capacity_lower = 15 + resource_in_unit2.people_capacity_upper = 25 + resource_in_unit2.save() + + resource_in_unit3.people_capacity_lower = 20 + resource_in_unit3.people_capacity_upper = None + resource_in_unit3.save() + + response = api_client.get(reverse("resource-list") + "?people=15") + assert response.status_code == 200 + assert len(response.data["results"]) == 3 + + response = api_client.get(reverse("resource-list") + "?people=22") + assert response.status_code == 200 + assert len(response.data["results"]) == 1 + assert response.data["results"][0]["id"] == resource_in_unit2.id + + response = api_client.get(reverse("resource-list") + "?people=50") + assert response.status_code == 200 + assert len(response.data["results"]) == 0 diff --git a/respa_admin/forms.py b/respa_admin/forms.py index 572e41185..12f44bfd8 100644 --- a/respa_admin/forms.py +++ b/respa_admin/forms.py @@ -240,7 +240,8 @@ class Meta: "equipment", "access_methods", "external_reservation_url", - "people_capacity", + "people_capacity_lower", + "people_capacity_upper", "area", "min_period", "max_period", diff --git a/respa_admin/templates/respa_admin/resources/form/_booking.html b/respa_admin/templates/respa_admin/resources/form/_booking.html index 1cc9b7934..8bf869fb7 100644 --- a/respa_admin/templates/respa_admin/resources/form/_booking.html +++ b/respa_admin/templates/respa_admin/resources/form/_booking.html @@ -6,7 +6,8 @@

{% trans "Booking information" %}

{% trans "*Mandatory fields" %}
- {% include "respa_admin/forms/_input.html" with field=form.people_capacity %} + {% include "respa_admin/forms/_input.html" with field=form.people_capacity_lower %} + {% include "respa_admin/forms/_input.html" with field=form.people_capacity_upper %} {% include "respa_admin/forms/_input.html" with field=form.area %}