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:
@@ -91,6 +91,7 @@ TENANT_APPS = [
|
|||||||
'orders', # Заказы
|
'orders', # Заказы
|
||||||
'inventory', # Складской учет
|
'inventory', # Складской учет
|
||||||
'pos', # POS Terminal
|
'pos', # POS Terminal
|
||||||
|
'discounts', # Скидки и промокоды
|
||||||
'system_settings', # Системные настройки компании (только для владельца)
|
'system_settings', # Системные настройки компании (только для владельца)
|
||||||
# TODO: 'simple_history' - вернуть позже для истории изменений
|
# TODO: 'simple_history' - вернуть позже для истории изменений
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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="Общая сумма заказа"
|
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(
|
amount_paid = models.DecimalField(
|
||||||
max_digits=10,
|
max_digits=10,
|
||||||
@@ -382,18 +406,21 @@ class Order(models.Model):
|
|||||||
def calculate_total(self):
|
def calculate_total(self):
|
||||||
"""
|
"""
|
||||||
Пересчитывает итоговую сумму заказа.
|
Пересчитывает итоговую сумму заказа.
|
||||||
total_amount = subtotal + delivery_cost
|
total_amount = subtotal + delivery_cost - discount_amount
|
||||||
"""
|
"""
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
subtotal = self.subtotal
|
subtotal = self.subtotal
|
||||||
delivery_cost = Decimal('0')
|
delivery_cost = Decimal('0')
|
||||||
|
|
||||||
# Получаем стоимость доставки из связанной модели Delivery
|
# Получаем стоимость доставки из связанной модели Delivery
|
||||||
if hasattr(self, 'delivery'):
|
if hasattr(self, 'delivery'):
|
||||||
delivery_cost = self.delivery.cost
|
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'])
|
self.save(update_fields=['total_amount'])
|
||||||
|
|
||||||
def reset_delivery_cost(self):
|
def reset_delivery_cost(self):
|
||||||
|
|||||||
@@ -82,6 +82,23 @@ class OrderItem(models.Model):
|
|||||||
help_text="True если цена была изменена вручную при создании заказа"
|
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(
|
is_from_showcase = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
@@ -214,8 +231,10 @@ class OrderItem(models.Model):
|
|||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
def get_total_price(self):
|
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
|
@property
|
||||||
def item_name(self):
|
def item_name(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user