feat(discounts, orders): рефакторинг системы скидок - единый источник правды
- Добавлен combine_mode в форму создания/редактирования скидок - Добавлена колонка "Объединение" в список скидок с иконками - Добавлен фильтр по режиму объединения скидок - Добавлена валидация: только одна exclusive скидка на заказ - Удалены дублирующие поля из Order и OrderItem: - applied_discount, applied_promo_code, discount_amount - Скидки теперь хранятся только в DiscountApplication - Добавлены свойства для обратной совместимости Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -82,22 +82,10 @@ 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="Сумма скидки"
|
||||
)
|
||||
# === СКИДКИ ===
|
||||
# Скидки хранятся в модели DiscountApplication (через related_name='discount_applications')
|
||||
# Старые поля applied_discount, discount_amount УДАЛЕНЫ
|
||||
# Используйте свойства ниже для доступа к скидкам
|
||||
|
||||
# Витринные продажи
|
||||
is_from_showcase = models.BooleanField(
|
||||
@@ -254,3 +242,23 @@ class OrderItem(models.Model):
|
||||
if self.is_custom_price and self.original_price:
|
||||
return self.price - self.original_price
|
||||
return None
|
||||
|
||||
# === Свойства для доступа к скидкам (через DiscountApplication) ===
|
||||
|
||||
@property
|
||||
def item_discounts(self):
|
||||
"""Скидки на эту позицию (QuerySet DiscountApplication)"""
|
||||
return self.discount_applications.filter(target='order_item').select_related('discount')
|
||||
|
||||
@property
|
||||
def discount_amount(self):
|
||||
"""Общая сумма скидки на позицию"""
|
||||
from django.db.models import Sum
|
||||
total = self.item_discounts.aggregate(total=Sum('discount_amount'))['total']
|
||||
return total if total else Decimal('0')
|
||||
|
||||
@property
|
||||
def applied_discount(self):
|
||||
"""Первая применённая скидка (для обратной совместимости)"""
|
||||
first = self.item_discounts.first()
|
||||
return first.discount if first else None
|
||||
|
||||
Reference in New Issue
Block a user