From 396c7be185edfda3b2a00168c6c179aa20a2a99f Mon Sep 17 00:00:00 2001 From: hoosnick Date: Fri, 8 Sep 2023 11:45:00 +0500 Subject: [PATCH 1/2] add: calculate discount --- lib/payme/migrations/0001_initial.py | 2 +- lib/payme/models.py | 47 ++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/lib/payme/migrations/0001_initial.py b/lib/payme/migrations/0001_initial.py index fba08cd..883bad3 100644 --- a/lib/payme/migrations/0001_initial.py +++ b/lib/payme/migrations/0001_initial.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): auto_created=True, primary_key=True, serialize=False, verbose_name='ID' )), - ('discount', models.FloatField(blank=True, null=True)), + ('discount', models.BigIntegerField(blank=True, null=True)), ('title', models.CharField(max_length=255)), ('price', models.BigIntegerField(default=0)), ('count', models.IntegerField(default=1)), diff --git a/lib/payme/models.py b/lib/payme/models.py index 50be5f5..d4c4e19 100644 --- a/lib/payme/models.py +++ b/lib/payme/models.py @@ -40,7 +40,7 @@ class Item(models.Model): Item class \ That's used for managing order items """ - discount = models.FloatField(null=True, blank=True) + discount = models.BigIntegerField(null=True, blank=True) title = models.CharField(max_length=255) price = models.BigIntegerField(default=0) count = models.IntegerField(default=1) @@ -50,7 +50,7 @@ class Item(models.Model): vat_percent = models.IntegerField(default=0, null=True, blank=True) def __str__(self) -> str: - return f"[{self.id}] {self.title} ({self.count} pc.) x {self.price:,}" + return f"[{self.id}] {self.title} ({self.count} pc.) x {self.price:,} UZS" class OrderDetail(models.Model): @@ -69,17 +69,46 @@ class OrderDetail(models.Model): @property def get_items_display(self): # pylint: disable=missing-function-docstring - return ', '.join([items.title for items in self.items.all()]) + item_display = [f'[{self.pk}]'] + + for fld in self._meta.get_fields(): + if not isinstance(fld, models.ManyToOneRel): + continue + + if not issubclass(fld.related_model, BaseOrder): + continue + + related_order = fld.get_accessor_name() + orders = getattr(self, related_order).values() + + order_id = orders[0].get('id') if orders else 'None' + + item_display.append(f'FOR ORDER - {order_id}') + if self.shipping: item_display.append(f'ADDRESS: {self.shipping.title}') + item_display.append(f'AMOUNT: {self.get_total_items_price} UZS') + + return ' '.join(item_display) @property def get_total_items_price(self) -> int: # pylint: disable=missing-function-docstring - shipping_price = self.shipping.price if self.shipping else 0 - return shipping_price + self.items.all().aggregate( + items = self.items.all().aggregate( total_price=models.Sum( - models.F('price') * models.F('count') + models.Case( + models.When( + discount__isnull=True, + then=models.F('price') * models.F('count') + ), + default=( + (models.F('price') * models.F('count')) - + models.F('discount') + ), + output_field=models.BigIntegerField() + ) ) - )['total_price'] + ) + shipping_price = self.shipping.price if self.shipping else 0 + return f"{shipping_price + items['total_price']:,}" def __str__(self) -> str: return f"{self.get_items_display}" @@ -116,10 +145,10 @@ class BaseOrder(models.Model, metaclass=DisallowOverrideMetaclass): @property def amount(self): # pylint: disable=missing-function-docstring - return self.detail.get_total_items_price + return self.detail.get_total_items_price if self.detail else 0 def __str__(self): - return f"ORDER ID: {self.id} - AMOUNT: {self.amount:,}" + return f"ORDER ID: {self.id} - AMOUNT: {self.amount} UZS" class Meta: # pylint: disable=missing-class-docstring From 1030250ae4b2c5a9865cd430fb82f2efa9ca6de3 Mon Sep 17 00:00:00 2001 From: hoosnick Date: Fri, 8 Sep 2023 11:47:08 +0500 Subject: [PATCH 2/2] lint: fix multiple-statements --- lib/payme/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/payme/models.py b/lib/payme/models.py index d4c4e19..c8a19fc 100644 --- a/lib/payme/models.py +++ b/lib/payme/models.py @@ -84,7 +84,8 @@ def get_items_display(self): order_id = orders[0].get('id') if orders else 'None' item_display.append(f'FOR ORDER - {order_id}') - if self.shipping: item_display.append(f'ADDRESS: {self.shipping.title}') + if self.shipping: + item_display.append(f'ADDRESS: {self.shipping.title}') item_display.append(f'AMOUNT: {self.get_total_items_price} UZS') return ' '.join(item_display)