fix(inventory): учитывать скидки на позицию и заказ при расчёте цены продажи
Расширяем логику расчёта цены продажи для учёта как скидок на отдельные позиции, так и скидок на весь заказ. Скидка на заказ распределяется пропорционально доле каждой позиции в общей сумме заказа. Изменения внесены в SaleProcessor и сигнал создания продажи при завершении заказа.
This commit is contained in:
@@ -36,12 +36,27 @@ class SaleProcessor:
|
|||||||
# Определяем цену продажи из заказа или из товара
|
# Определяем цену продажи из заказа или из товара
|
||||||
if order and reservation.order_item:
|
if order and reservation.order_item:
|
||||||
item = reservation.order_item
|
item = reservation.order_item
|
||||||
# Цена за единицу с учётом скидки
|
# Цена за единицу с учётом всех скидок (позиция + заказ)
|
||||||
if item.discount_amount and item.quantity > 0:
|
item_subtotal = Decimal(str(item.price)) * Decimal(str(item.quantity))
|
||||||
subtotal = Decimal(str(item.price)) * Decimal(str(item.quantity))
|
|
||||||
price_with_discount = (subtotal - Decimal(str(item.discount_amount))) / Decimal(str(item.quantity))
|
# Скидка на позицию
|
||||||
|
item_discount = Decimal(str(item.discount_amount)) if item.discount_amount else Decimal('0')
|
||||||
|
|
||||||
|
# Скидка на заказ (распределяется пропорционально доле позиции в заказе)
|
||||||
|
# subtotal - сумма позиций С учётом скидок на позиции (без скидки на заказ)
|
||||||
|
order_total = order.subtotal if hasattr(order, 'subtotal') else Decimal('0')
|
||||||
|
if order_total > 0 and order.discount_amount:
|
||||||
|
order_discount = Decimal(str(order.discount_amount))
|
||||||
|
item_order_discount = order_discount * (item_subtotal / order_total)
|
||||||
|
else:
|
||||||
|
item_order_discount = Decimal('0')
|
||||||
|
|
||||||
|
total_discount = item_discount + item_order_discount
|
||||||
|
if total_discount and item.quantity > 0:
|
||||||
|
price_with_discount = (item_subtotal - total_discount) / Decimal(str(item.quantity))
|
||||||
else:
|
else:
|
||||||
price_with_discount = Decimal(str(item.price))
|
price_with_discount = Decimal(str(item.price))
|
||||||
|
|
||||||
# Пересчитываем цену в базовые единицы
|
# Пересчитываем цену в базовые единицы
|
||||||
if item.sales_unit and item.conversion_factor_snapshot:
|
if item.sales_unit and item.conversion_factor_snapshot:
|
||||||
sale_price = price_with_discount * item.conversion_factor_snapshot
|
sale_price = price_with_discount * item.conversion_factor_snapshot
|
||||||
|
|||||||
@@ -480,10 +480,25 @@ def create_sale_on_order_completion(sender, instance, created, **kwargs):
|
|||||||
f"Используем quantity_in_base_units: {sale_quantity}"
|
f"Используем quantity_in_base_units: {sale_quantity}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Цена за единицу с учётом скидки
|
# Цена за единицу с учётом всех скидок (позиция + заказ)
|
||||||
if item.discount_amount and item.quantity > 0:
|
item_subtotal = Decimal(str(item.price)) * Decimal(str(item.quantity))
|
||||||
subtotal = Decimal(str(item.price)) * Decimal(str(item.quantity))
|
|
||||||
price_with_discount = (subtotal - Decimal(str(item.discount_amount))) / Decimal(str(item.quantity))
|
# Скидка на позицию
|
||||||
|
item_discount = Decimal(str(item.discount_amount)) if item.discount_amount else Decimal('0')
|
||||||
|
|
||||||
|
# Скидка на заказ (распределяется пропорционально доле позиции в заказе)
|
||||||
|
# subtotal - сумма позиций С учётом скидок на позиции (без скидки на заказ)
|
||||||
|
order_total = instance.subtotal if hasattr(instance, 'subtotal') else Decimal('0')
|
||||||
|
if order_total > 0 and instance.discount_amount:
|
||||||
|
order_discount = Decimal(str(instance.discount_amount))
|
||||||
|
# Пропорциональная часть скидки заказа для этой позиции
|
||||||
|
item_order_discount = order_discount * (item_subtotal / order_total)
|
||||||
|
else:
|
||||||
|
item_order_discount = Decimal('0')
|
||||||
|
|
||||||
|
total_discount = item_discount + item_order_discount
|
||||||
|
if total_discount and item.quantity > 0:
|
||||||
|
price_with_discount = (item_subtotal - total_discount) / Decimal(str(item.quantity))
|
||||||
else:
|
else:
|
||||||
price_with_discount = Decimal(str(item.price))
|
price_with_discount = Decimal(str(item.price))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user