diff --git a/lego/apps/lending/filters.py b/lego/apps/lending/filters.py index 848fa8e38..389f6b995 100644 --- a/lego/apps/lending/filters.py +++ b/lego/apps/lending/filters.py @@ -1,4 +1,4 @@ -from django_filters import CharFilter, FilterSet +from django_filters import BooleanFilter, CharFilter, FilterSet from lego.apps.lending.models import LendingRequest @@ -6,6 +6,7 @@ class LendingRequestFilterSet(FilterSet): status = CharFilter(method="filter_lending_status") + archived = BooleanFilter(field_name="archived") def filter_lending_status(self, queryset, name, value): if not value: @@ -20,4 +21,4 @@ def filter_lending_status(self, queryset, name, value): class Meta: model = LendingRequest - fields = ["status"] + fields = ["status", "archived"] diff --git a/lego/apps/lending/migrations/0010_lendingrequest_archived.py b/lego/apps/lending/migrations/0010_lendingrequest_archived.py new file mode 100644 index 000000000..9551197f6 --- /dev/null +++ b/lego/apps/lending/migrations/0010_lendingrequest_archived.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.16 on 2026-04-13 19:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("lending", "0009_alter_lendableobject_category"), + ] + + operations = [ + migrations.AddField( + model_name="lendingrequest", + name="archived", + field=models.BooleanField(blank=True, default=False), + ), + ] diff --git a/lego/apps/lending/models.py b/lego/apps/lending/models.py index a310d3609..9cbdbe2eb 100644 --- a/lego/apps/lending/models.py +++ b/lego/apps/lending/models.py @@ -62,6 +62,7 @@ class LendingRequest(BasisModel): ) start_date = models.DateTimeField() end_date = models.DateTimeField() + archived = models.BooleanField(default=False, blank=True, null=False) class Meta: permission_handler = LendingRequestPermissionHandler() diff --git a/lego/apps/lending/serializers.py b/lego/apps/lending/serializers.py index 1836a2fd8..743229e39 100644 --- a/lego/apps/lending/serializers.py +++ b/lego/apps/lending/serializers.py @@ -122,6 +122,7 @@ class Meta: "id", "lendable_object", "status", + "archived", "start_date", "end_date", ) @@ -142,6 +143,7 @@ class Meta: "updated_by", "lendable_object", "status", + "archived", "start_date", "end_date", "timeline_entries", @@ -164,6 +166,7 @@ class Meta: "updated_by", "lendable_object", "status", + "archived", "comment", "start_date", "end_date", diff --git a/lego/apps/lending/tests/test_lendingrequest_api.py b/lego/apps/lending/tests/test_lendingrequest_api.py index e03d620c4..60d35444a 100644 --- a/lego/apps/lending/tests/test_lendingrequest_api.py +++ b/lego/apps/lending/tests/test_lendingrequest_api.py @@ -354,6 +354,67 @@ def test_filter_by_status(self): self.assertEqual(results[0]["id"], request2.id) self.assertEqual(results[1]["id"], request3.id) + def test_filter_by_archived(self): + request_unarchived = create_lending_request( + user=self.user, + lendable_object=self.lendable_object, + archived=False, + status="approved", + ) + request_archived = create_lending_request( + user=self.user, + lendable_object=self.lendable_object, + archived=True, + status="approved", + ) + + self.client.force_authenticate(user=self.editor_user) + + archived_response = self.client.get( + reverse("api:v1:lending-request-admin"), {"archived": "true"} + ) + self.assertEqual(archived_response.status_code, status.HTTP_200_OK) + archived_ids = [req["id"] for req in archived_response.json()["results"]] + self.assertEqual(archived_ids, [request_archived.id]) + + unarchived_response = self.client.get( + reverse("api:v1:lending-request-admin"), {"archived": "false"} + ) + self.assertEqual(unarchived_response.status_code, status.HTTP_200_OK) + unarchived_ids = [req["id"] for req in unarchived_response.json()["results"]] + self.assertEqual(unarchived_ids, [request_unarchived.id]) + + def test_filter_by_archived_and_status(self): + request_approved_unarchived = create_lending_request( + user=self.user, + lendable_object=self.lendable_object, + archived=False, + status="approved", + ) + create_lending_request( + user=self.user, + lendable_object=self.lendable_object, + archived=True, + status="approved", + ) + create_lending_request( + user=self.user, + lendable_object=self.lendable_object, + archived=False, + status="cancelled", + ) + + self.client.force_authenticate(user=self.editor_user) + + response = self.client.get( + reverse("api:v1:lending-request-admin"), + {"status": "approved", "archived": "false"}, + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + results = response.json()["results"] + self.assertEqual(len(results), 1) + self.assertEqual(results[0]["id"], request_approved_unarchived.id) + def test_list_lending_requests_can_be_sorted_newest_first(self): self.client.force_authenticate(user=self.user) @@ -849,3 +910,51 @@ def test_responsible_user_cannot_request_changes_on_own_request(self): lending_request = LendingRequest.objects.get(pk=self.request_id) self.assertEqual(lending_request.status, "unapproved") + + +class LendingRequestPatchTestCase(BaseAPITestCase): + def setUp(self): + self.user = create_user() + self.group = AbakusGroup.objects.create(name="test_group") + self.group.add_user(self.user) + + self.lendable_object = create_lendable_object() + self.lendable_object.can_view_groups.add(self.group) + self.lendable_object.can_edit_groups.add(self.group) + + self.lending_request = create_lending_request(self.user, self.lendable_object) + + def test_patch_lending_request_can_toggle_archived(self): + self.client.force_authenticate(user=self.user) + + create_response = self.client.post( + get_lending_request_list_url(), + { + "lendable_object": self.lendable_object.pk, + "start_date": (now() + timedelta(days=1)).isoformat(), + "end_date": (now() + timedelta(days=2)).isoformat(), + }, + ) + self.assertEqual(create_response.status_code, status.HTTP_201_CREATED) + request_id = create_response.data["id"] + + patch_true_response = self.client.patch( + get_lending_request_detail_url(request_id), + {"archived": True}, + ) + self.assertEqual(patch_true_response.status_code, status.HTTP_200_OK) + self.assertTrue(patch_true_response.data["archived"]) + + lending_request = LendingRequest.objects.get(pk=request_id) + self.assertTrue(lending_request.archived) + + patch_false_response = self.client.patch( + get_lending_request_detail_url(request_id), + {"archived": False}, + ) + self.assertEqual(patch_false_response.status_code, status.HTTP_200_OK) + self.assertFalse(patch_false_response.data["archived"]) + + lending_request.refresh_from_db() + self.assertFalse(lending_request.archived) +