feat(orders): добавлены поля скидок в Order и OrderItem
Интеграция системы скидок с моделями заказов: Order: - applied_discount: ForeignKey на Discount - discount_amount: сумма скидки на заказ - applied_promo_code: использованный промокод - calculate_total(): обновлён с учётом скидки OrderItem: - applied_discount: ForeignKey на Discount - discount_amount: сумма скидки на позицию - get_total_price(): обновлён с учётом скидки Миграция: - 0003_order_applied_discount... добавляет новые поля Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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='Сумма скидки'),
|
||||
),
|
||||
]
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user