From 523c8f5cfafe416b64f4e8f5dda101ecdaefeb52 Mon Sep 17 00:00:00 2001 From: xmeunier Date: Fri, 18 Oct 2024 13:22:53 +0200 Subject: [PATCH] Refactor compuation of counters and prices in order objects --- la_chariotte/order/models.py | 56 +++++++++-------------- la_chariotte/order/views/grouped_order.py | 10 +--- la_chariotte/order/views/order.py | 8 +--- la_chariotte/tests/utils.py | 19 +++----- 4 files changed, 30 insertions(+), 63 deletions(-) diff --git a/la_chariotte/order/models.py b/la_chariotte/order/models.py index 55dd867..557be4d 100644 --- a/la_chariotte/order/models.py +++ b/la_chariotte/order/models.py @@ -52,17 +52,6 @@ class GroupedOrder(models.Model): ) self.code = f"{base_36_pk}{random_string}"[:code_length] - def compute_total_price(self): - price = 0 - for order in self.order_set.all(): - price += order.price - self.total_price = price - self.save() - - def compute_items_ordered_nb(self): - for item in self.item_set.all(): - item.compute_ordered_nb() - def get_total_ordered_items(self): total_nb = 0 for item in self.item_set.all(): @@ -128,28 +117,33 @@ class Order(models.Model): created_date = models.DateTimeField("Date et heure de commande", auto_now_add=True) note = models.TextField(max_length=200, null=True, blank=True) - def compute_order_articles_nb(self): - """Computes the number of articles in this order""" - articles_nb = 0 - for ord_item in self.ordered_items.all(): - articles_nb += ord_item.nb - self.articles_nb = articles_nb - self.save() - - def compute_order_price(self): - """Computes the total price of the order""" - price = 0 - for ord_item in self.ordered_items.all(): - price += ord_item.get_price() - self.price = price - self.save() - def __str__(self): # pragma: no cover return ( f"Commande de {self.author} pour la commande groupée" f" {self.grouped_order.code}" ) + def create_ordered_item(self, nb, item): + """Create an OrderItem instance and update counters/price accordingly""" + self.ordered_items.add(OrderedItem.objects.create(nb=nb, order=self, item=item)) + item.ordered_nb += nb + item.save() + self.articles_nb += nb + self.price += nb * item.price + self.grouped_order.total_price += nb * item.price + self.grouped_order.save() + self.save() + + # overwrite delete() to update counters/prices + def delete(self, *args, **kwargs): + for ord_item in self.ordered_items.all(): + ord_item.item.ordered_nb -= ord_item.nb + ord_item.item.save() + self.grouped_order.total_price -= self.price + self.grouped_order.save() + self.author.delete() + super().delete(*args, **kwargs) + class Item(models.Model): name = models.CharField(max_length=100) @@ -159,14 +153,6 @@ class Item(models.Model): ordered_nb = models.IntegerField(default=0) - def compute_ordered_nb(self): - """Computes the number of times this item has been ordered""" - ordered_nb = 0 - for order in self.orders.all(): - ordered_nb += order.nb - self.ordered_nb = ordered_nb - self.save() - def get_total_price(self): """Returns the total price of all orders on this item""" return self.price * self.ordered_nb diff --git a/la_chariotte/order/views/grouped_order.py b/la_chariotte/order/views/grouped_order.py index f2c454b..8eebede 100644 --- a/la_chariotte/order/views/grouped_order.py +++ b/la_chariotte/order/views/grouped_order.py @@ -151,12 +151,6 @@ class GroupedOrderOverview(UserIsOrgaMixin, generic.DetailView): # Staff can see but not edit grouped orders return super().test_func() or self.request.user.is_staff - def get(self, request, *args, **kwargs): - # Compute grouped order total price before display - self.get_object().compute_total_price() - self.get_object().compute_items_ordered_nb() - return super().get(self, request, *args, **kwargs) - def get_context_data(self, **kwargs): context = super(GroupedOrderOverview, self).get_context_data(**kwargs) # Add share link to context @@ -255,10 +249,10 @@ class GroupedOrderDeleteView(UserIsOrgaMixin, generic.DeleteView): return reverse_lazy("order:index") def form_valid(self, form): - # Delete related OrderAuthors + # Delete related Orders grouped_order = self.get_object() for order in grouped_order.order_set.all(): - order.author.delete() + order.delete() return super().form_valid(form) diff --git a/la_chariotte/order/views/order.py b/la_chariotte/order/views/order.py index 4a02b90..3c1ce52 100644 --- a/la_chariotte/order/views/order.py +++ b/la_chariotte/order/views/order.py @@ -66,13 +66,11 @@ def place_order(request, code): if error_message: break # stop creating items if there is an error if quantity > 0: - OrderedItem.objects.create(nb=quantity, order=order, item=item) + order.create_ordered_item(nb=quantity, item=item) # Redisplay the form with error messages if there is an error if error_message: order.delete() - author.delete() - grouped_order.compute_items_ordered_nb() return render( request, "order/grouped_order_detail.html", @@ -90,7 +88,6 @@ def place_order(request, code): # Redisplay the form with error messages if there is an error if error_message: order.delete() - author.delete() return render( request, "order/grouped_order_detail.html", @@ -103,8 +100,6 @@ def place_order(request, code): ) # Send confirmation mail and redirect to confirmation page - order.compute_order_price() - grouped_order.compute_items_ordered_nb() send_order_confirmation_mail(order) # Redirect to prevent data from being posted twice when the user hits the Back @@ -123,7 +118,6 @@ def validate_item_ordered_nb(item, ordered_nb): def validate_articles_ordered_nb(order): """Return an error if no items are ordered""" - order.compute_order_articles_nb() if order.articles_nb == 0: return "Veuillez commander au moins un produit" return None diff --git a/la_chariotte/tests/utils.py b/la_chariotte/tests/utils.py index b7cc913..9134032 100644 --- a/la_chariotte/tests/utils.py +++ b/la_chariotte/tests/utils.py @@ -23,8 +23,8 @@ def create_grouped_order( def order_items_in_grouped_order(grouped_order): """Creates 2 OrderedItems and orders in the given grouped order. Returns the order""" - item_1 = grouped_order.item_set.create(name="test item", price="2") - item_2 = grouped_order.item_set.create(name="test item 2", price="9") + item_1 = grouped_order.item_set.create(name="test item", price=2) + item_2 = grouped_order.item_set.create(name="test item 2", price=9) author_1 = models.OrderAuthor.objects.create( first_name="bob", last_name="lescargot", phone="000", email="bob@escargot.fr" ) @@ -40,15 +40,8 @@ def order_items_in_grouped_order(grouped_order): order = grouped_order.order_set.create(author=author_1) order_2 = grouped_order.order_set.create(author=author_2) order_3 = grouped_order.order_set.create(author=author_3) - models.OrderedItem.objects.create(order=order, item=item_1, nb=3) - models.OrderedItem.objects.create(order=order, item=item_2, nb=2) - models.OrderedItem.objects.create(order=order_2, item=item_1, nb=1) - models.OrderedItem.objects.create(order=order_3, item=item_2, nb=1) - item_1.compute_ordered_nb() - item_2.compute_ordered_nb() - order.compute_order_price() - order_2.compute_order_price() - order_3.compute_order_price() - grouped_order.compute_total_price() - grouped_order.save() + order.create_ordered_item(item=item_1, nb=3) + order.create_ordered_item(item=item_2, nb=2) + order_2.create_ordered_item(item=item_1, nb=1) + order_3.create_ordered_item(item=item_2, nb=1) return order