diff --git a/la_chariotte/order/models.py b/la_chariotte/order/models.py index 7329c72..1bc8862 100644 --- a/la_chariotte/order/models.py +++ b/la_chariotte/order/models.py @@ -49,7 +49,9 @@ class GroupedOrder(models.Model): def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) - if self.delivery_date < timezone.now().date(): + if self.delivery_date < timezone.now().date() and not self.pk: + # if the grouped order is being created (not updated), it cannot be in the past + # if we are updating, it's ok raise ValidationError("La date de livraison ne doit pas être dans le passé") if self.delivery_date < self.deadline.date(): diff --git a/la_chariotte/order/templates/order/grouped_order_overview.html b/la_chariotte/order/templates/order/grouped_order_overview.html index b601140..1a78d96 100644 --- a/la_chariotte/order/templates/order/grouped_order_overview.html +++ b/la_chariotte/order/templates/order/grouped_order_overview.html @@ -31,9 +31,8 @@ Livraison le {{ grouped_order.delivery_date }}

- - Page de la commande - + + Modifier la commande
diff --git a/la_chariotte/order/templates/order/grouped_order_update.html b/la_chariotte/order/templates/order/grouped_order_update.html new file mode 100644 index 0000000..80da6d6 --- /dev/null +++ b/la_chariotte/order/templates/order/grouped_order_update.html @@ -0,0 +1,19 @@ +{% extends 'base.html' %} + +{% block title %}Modifier la commande groupée{% endblock %} + +{% block content %} +

+ {% block content_title %}Modifier la commande groupée{% endblock %} +

+
+

{{ grouped_order.name }} - modifier

+
{% csrf_token %} + {{ form.as_p }} +
+ Annuler + +
+
+
+{% endblock %} \ No newline at end of file diff --git a/la_chariotte/order/tests/test_views.py b/la_chariotte/order/tests/test_views.py index 4754898..6c9bdbb 100644 --- a/la_chariotte/order/tests/test_views.py +++ b/la_chariotte/order/tests/test_views.py @@ -960,6 +960,125 @@ class TestGroupedOrderCreateView: ) +class TestGroupedOrderUpdateView: + def test_update_grouped_order(self, client_log): + """ + The grouped order orga updates a grouped order updates an incoming grouped order. + """ + grouped_order = create_grouped_order( + days_before_delivery_date=5, + days_before_deadline=2, + name="gr order test", + orga_user=auth.get_user(client_log), + ) + assert models.GroupedOrder.objects.count() == 1 + assert models.GroupedOrder.objects.first().name == "gr order test" + assert models.GroupedOrder.objects.first().place == None + + # get the update form + update_grouped_order_url = reverse( + "order:update_grouped_order", kwargs={"pk": grouped_order.pk} + ) + response = client_log.get(update_grouped_order_url) + assert response.status_code == 200 + + # post the update form + date = timezone.now().date() + datetime.timedelta(days=42) + deadline = timezone.now() + datetime.timedelta(days=32) + response = client_log.post( + update_grouped_order_url, + { + "name": "titre test modifié", + "deadline": deadline, + "delivery_date": date, + "place": "quelque part", + }, + ) + assert response.status_code == 302 + assert response.url.endswith("gerer-produits") + assert models.GroupedOrder.objects.count() == 1 + assert models.GroupedOrder.objects.first().name == "titre test modifié" + assert models.GroupedOrder.objects.first().place == "quelque part" + + def test_update_grouped_order__delivery_date_passed(self, client_log): + """ + The grouped order orga updates a grouped order. + They can put an old delivery date. + """ + grouped_order = create_grouped_order( + days_before_delivery_date=5, + days_before_deadline=2, + name="gr order test", + orga_user=auth.get_user(client_log), + ) + assert models.GroupedOrder.objects.count() == 1 + assert models.GroupedOrder.objects.first().name == "gr order test" + assert models.GroupedOrder.objects.first().place == None + + # get the update form + update_grouped_order_url = reverse( + "order:update_grouped_order", kwargs={"pk": grouped_order.pk} + ) + response = client_log.get(update_grouped_order_url) + assert response.status_code == 200 + + # post the update form + date = timezone.now().date() + datetime.timedelta(days=-1) + deadline = timezone.now() + datetime.timedelta(days=-3) + response = client_log.post( + update_grouped_order_url, + { + "name": "titre test modifié", + "deadline": deadline, + "delivery_date": date, + "place": "quelque part", + }, + ) + assert response.status_code == 302 + assert response.url.endswith("gerer-produits") + assert models.GroupedOrder.objects.count() == 1 + assert models.GroupedOrder.objects.first().name == "titre test modifié" + assert models.GroupedOrder.objects.first().place == "quelque part" + + def test_update_grouped_order__not_orga(self, client_log, other_user): + """A user that is not organiszer of the GO accesses update page. + They get a 403 error""" + grouped_order = create_grouped_order( + days_before_delivery_date=5, + days_before_deadline=2, + name="gr order test", + orga_user=other_user, + ) + + # get the update form + update_grouped_order_url = reverse( + "order:update_grouped_order", kwargs={"pk": grouped_order.pk} + ) + response = client_log.get(update_grouped_order_url) + assert response.status_code == 403 + + def test_update_grouped_order__anonymous(self, client, other_user): + """An anonymous user accesses the update_page. + They get redirected to login page""" + grouped_order = create_grouped_order( + days_before_delivery_date=5, + days_before_deadline=2, + name="gr order test", + orga_user=other_user, + ) + + # get the update form + update_grouped_order_url = reverse( + "order:update_grouped_order", kwargs={"pk": grouped_order.pk} + ) + response = client.get(update_grouped_order_url) + assert response.status_code == 302 + assert ( + response.url + == f"{reverse('accounts:login')}?next={update_grouped_order_url}" + ) + + class TestGroupedOrderAddItemsView: def test_get_manage_items__user_not_orga(self, client_log, other_user): """ @@ -1162,7 +1281,7 @@ class TestGroupedOrderSheetView: response = client_log.get(generate_sheet_url) assert response.status_code == 403 - def test_get__not_orga(self, client, other_user): + def test_get__anonymous(self, client, other_user): """An anonymous user accesses the sheet view. They get redirected to login page""" grouped_order = create_grouped_order( diff --git a/la_chariotte/order/urls.py b/la_chariotte/order/urls.py index 2f06177..33dda0e 100644 --- a/la_chariotte/order/urls.py +++ b/la_chariotte/order/urls.py @@ -25,6 +25,11 @@ urlpatterns = [ views.GroupedOrderAddItemsView.as_view(), name="manage_items", ), + path( + "/modifier", + views.GroupedOrderUpdateView.as_view(), + name="update_grouped_order", + ), path( "/gerer-produits/nouveau", views.ItemCreateView.as_view(), diff --git a/la_chariotte/order/views.py b/la_chariotte/order/views.py index 49a4f01..099f6ee 100644 --- a/la_chariotte/order/views.py +++ b/la_chariotte/order/views.py @@ -112,6 +112,19 @@ class GroupedOrderCreateView(LoginRequiredMixin, generic.CreateView): return kwargs +class GroupedOrderUpdateView(UserPassesTestMixin, generic.UpdateView): + """View for updating a grouped order""" + + model = GroupedOrder + template_name = "order/grouped_order_update.html" + fields = ["name", "deadline", "delivery_date", "place", "description"] + context_object_name = "grouped_order" + + def test_func(self): + """Accessible only if the requesting user is the grouped order organizer""" + return self.get_object().orga == self.request.user + + class GroupedOrderAddItemsView(UserPassesTestMixin, generic.ListView): """After creating grouped order, view for adding items to it"""