diff --git a/myproject/myproject/settings.py b/myproject/myproject/settings.py index 5e67f9a..e61e4f7 100644 --- a/myproject/myproject/settings.py +++ b/myproject/myproject/settings.py @@ -91,6 +91,7 @@ TENANT_APPS = [ 'orders', # Заказы 'inventory', # Складской учет 'pos', # POS Terminal + 'discounts', # Скидки и промокоды 'system_settings', # Системные настройки компании (только для владельца) # TODO: 'simple_history' - вернуть позже для истории изменений ] diff --git a/myproject/orders/migrations/0003_order_applied_discount_order_applied_promo_code_and_more.py b/myproject/orders/migrations/0003_order_applied_discount_order_applied_promo_code_and_more.py new file mode 100644 index 0000000..3bdc4ab --- /dev/null +++ b/myproject/orders/migrations/0003_order_applied_discount_order_applied_promo_code_and_more.py @@ -0,0 +1,40 @@ +# Generated by Django 5.0.10 on 2026-01-10 21:12 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('discounts', '0001_initial'), + ('orders', '0002_initial'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='applied_discount', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='orders', to='discounts.discount', verbose_name='Примененная скидка'), + ), + migrations.AddField( + model_name='order', + name='applied_promo_code', + field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Использованный промокод'), + ), + migrations.AddField( + model_name='order', + name='discount_amount', + field=models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Сумма скидки'), + ), + migrations.AddField( + model_name='orderitem', + name='applied_discount', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='order_items', to='discounts.discount', verbose_name='Скидка на позицию'), + ), + migrations.AddField( + model_name='orderitem', + name='discount_amount', + field=models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Сумма скидки'), + ), + ] diff --git a/myproject/orders/models/order.py b/myproject/orders/models/order.py index 7a4191f..7459ebe 100644 --- a/myproject/orders/models/order.py +++ b/myproject/orders/models/order.py @@ -69,6 +69,30 @@ class Order(models.Model): help_text="Общая сумма заказа" ) + # Скидки + applied_discount = models.ForeignKey( + 'discounts.Discount', + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name='orders', + verbose_name="Примененная скидка" + ) + + discount_amount = models.DecimalField( + max_digits=10, + decimal_places=2, + default=0, + verbose_name="Сумма скидки" + ) + + applied_promo_code = models.CharField( + max_length=50, + blank=True, + null=True, + verbose_name="Использованный промокод" + ) + # Частичная оплата amount_paid = models.DecimalField( max_digits=10, @@ -382,18 +406,21 @@ class Order(models.Model): def calculate_total(self): """ Пересчитывает итоговую сумму заказа. - total_amount = subtotal + delivery_cost + total_amount = subtotal + delivery_cost - discount_amount """ from decimal import Decimal - + subtotal = self.subtotal delivery_cost = Decimal('0') - + # Получаем стоимость доставки из связанной модели Delivery if hasattr(self, 'delivery'): delivery_cost = self.delivery.cost - - self.total_amount = subtotal + delivery_cost + + # Вычитаем скидку на весь заказ (если есть) + order_discount = Decimal(str(self.discount_amount)) if self.discount_amount else Decimal('0') + + self.total_amount = subtotal + delivery_cost - order_discount self.save(update_fields=['total_amount']) def reset_delivery_cost(self): diff --git a/myproject/orders/models/order_item.py b/myproject/orders/models/order_item.py index 980be3c..bca0aaf 100644 --- a/myproject/orders/models/order_item.py +++ b/myproject/orders/models/order_item.py @@ -82,6 +82,23 @@ class OrderItem(models.Model): help_text="True если цена была изменена вручную при создании заказа" ) + # Скидки + applied_discount = models.ForeignKey( + 'discounts.Discount', + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name='order_items', + verbose_name="Скидка на позицию" + ) + + discount_amount = models.DecimalField( + max_digits=10, + decimal_places=2, + default=0, + verbose_name="Сумма скидки" + ) + # Витринные продажи is_from_showcase = models.BooleanField( default=False, @@ -214,8 +231,10 @@ class OrderItem(models.Model): super().save(*args, **kwargs) def get_total_price(self): - """Возвращает общую стоимость позиции""" - return self.price * self.quantity + """Возвращает общую стоимость позиции с учетом скидки""" + subtotal = self.price * self.quantity + discount = Decimal(str(self.discount_amount)) if self.discount_amount else Decimal('0') + return subtotal - discount @property def item_name(self):