From d4514e79596035208c61763becc38983da1cb3bf Mon Sep 17 00:00:00 2001 From: Laetitia Getti Date: Tue, 9 May 2023 15:17:02 +0200 Subject: [PATCH] we cannot create two similar grouped orders --- la_chariotte/order/forms.py | 19 ++++++++++++ ...oupedorder_name_alter_groupedorder_orga.py | 31 +++++++++++++++++++ ...0013_alter_groupedorder_unique_together.py | 18 +++++++++++ la_chariotte/order/models.py | 6 ++++ la_chariotte/order/tests/test_models.py | 30 ++++++++++++++++-- 5 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 la_chariotte/order/migrations/0012_alter_groupedorder_name_alter_groupedorder_orga.py create mode 100644 la_chariotte/order/migrations/0013_alter_groupedorder_unique_together.py diff --git a/la_chariotte/order/forms.py b/la_chariotte/order/forms.py index 7ab18f0..17865e7 100644 --- a/la_chariotte/order/forms.py +++ b/la_chariotte/order/forms.py @@ -1,4 +1,6 @@ from django.contrib.auth.models import User +from django.core.exceptions import NON_FIELD_ERRORS, ValidationError +from django.db import IntegrityError from django.forms import CharField, ModelForm from la_chariotte.order.models import GroupedOrder, Item @@ -17,6 +19,23 @@ class GroupedOrderForm(ModelForm): self.instance.orga = User.objects.get(id=self.user.pk) return super().save(commit=commit) + def clean(self): + cleaned_data = self.cleaned_data + + try: + GroupedOrder.objects.get( + name=cleaned_data["name"], + delivery_date=cleaned_data["delivery_date"], + orga=User.objects.get(id=self.user.pk), + ) + except GroupedOrder.DoesNotExist: + pass + else: + raise ValidationError( + "Une commande groupée avec le même titre et la même date existe déjà" + ) + return cleaned_data + class ItemCreateForm(ModelForm): class Meta: diff --git a/la_chariotte/order/migrations/0012_alter_groupedorder_name_alter_groupedorder_orga.py b/la_chariotte/order/migrations/0012_alter_groupedorder_name_alter_groupedorder_orga.py new file mode 100644 index 0000000..ecf4b7d --- /dev/null +++ b/la_chariotte/order/migrations/0012_alter_groupedorder_name_alter_groupedorder_orga.py @@ -0,0 +1,31 @@ +# Generated by Django 4.2 on 2023-05-05 14:32 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("order", "0011_alter_groupedorder_orga"), + ] + + operations = [ + migrations.AlterField( + model_name="groupedorder", + name="name", + field=models.CharField( + max_length=100, null=True, verbose_name="Titre de la commande" + ), + ), + migrations.AlterField( + model_name="groupedorder", + name="orga", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + verbose_name="Organisateur·ice", + ), + ), + ] diff --git a/la_chariotte/order/migrations/0013_alter_groupedorder_unique_together.py b/la_chariotte/order/migrations/0013_alter_groupedorder_unique_together.py new file mode 100644 index 0000000..1f2ccbf --- /dev/null +++ b/la_chariotte/order/migrations/0013_alter_groupedorder_unique_together.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2 on 2023-05-05 14:34 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("order", "0012_alter_groupedorder_name_alter_groupedorder_orga"), + ] + + operations = [ + migrations.AlterUniqueTogether( + name="groupedorder", + unique_together={("delivery_date", "name", "orga")}, + ), + ] diff --git a/la_chariotte/order/models.py b/la_chariotte/order/models.py index b6f446d..51cbe13 100644 --- a/la_chariotte/order/models.py +++ b/la_chariotte/order/models.py @@ -15,6 +15,9 @@ class GroupedOrder(models.Model): delivery_date = models.DateField("Date de livraison") deadline = models.DateTimeField("Date limite de commande") + class Meta: + unique_together = ["delivery_date", "name", "orga"] + def is_ongoing(self): """Returns True if the grouped order is open for new Orders - False if it's too late""" return self.deadline >= timezone.now() @@ -36,6 +39,9 @@ class GroupedOrder(models.Model): "La date limite de commande doit être avant la date de livraison" ) + def validate_unique(self, exclude=None): + super(GroupedOrder, self).validate_unique(exclude=exclude) + def __str__(self): # pragma: no cover return ( self.name diff --git a/la_chariotte/order/tests/test_models.py b/la_chariotte/order/tests/test_models.py index 47ef195..09a1c63 100644 --- a/la_chariotte/order/tests/test_models.py +++ b/la_chariotte/order/tests/test_models.py @@ -1,5 +1,6 @@ import datetime +from django.contrib import auth from django.urls import reverse from django.utils import timezone @@ -108,5 +109,30 @@ class TestGroupedOrderModel: "La date de livraison ne doit pas être dans le passé" in response.content.decode() assert GroupedOrder.objects.count() == 0 - def test_delivery_date_and_name_unique_together(self): - pass \ No newline at end of file + def test_validation_error_unique_together(self, client_log): + """If a grouped order with the same orga, delivery date and name of the order already exist, a validation error is raised""" + deadline_1 = timezone.now().date() + datetime.timedelta(days=12) + date = timezone.now().date() + datetime.timedelta(days=19) + GroupedOrder.objects.create( + name="commande", + orga=auth.get_user(client_log), + delivery_date=date, + deadline=deadline_1, + ) + assert GroupedOrder.objects.count() == 1 + create_gorder_url = reverse("order:create_grouped_order") + response = client_log.get(create_gorder_url) + assert response.status_code == 200 + deadline_2 = timezone.now() + datetime.timedelta(days=15) + response = client_log.post( + create_gorder_url, + {"name": "commande", "deadline": deadline_2, "delivery_date": date}, + ) + assert response.status_code == 200 + assert not response.context.get("form").is_valid() + assert ( + response.context.get("form").errors["__all__"][0] + == "Une commande groupée avec le même titre et la même date existe déjà" + ) + "Une commande groupée avec le même titre et la même date existe déjà" in response.content.decode() + assert GroupedOrder.objects.count() == 1