Упрощена логика обработки переплаты - убрана автоматика из calculate_total

Проблема:
- calculate_total() пытался автоматически обрабатывать переплату
- Это приводило к дублированию логики и сложной отладке
- Нарушался принцип единственной ответственности

Решение:
- Удалена автоматическая обработка переплаты из Order.calculate_total()
- Теперь calculate_total() ТОЛЬКО считает сумму - всё
- Переплата обрабатывается ТОЛЬКО в TransactionService при создании платежей/возвратов
- Добавлено предупреждение в UI о переплате с инструкцией

Как работает теперь:
1. При оплате - TransactionService автоматически вызывает add_overpayment()
2. При изменении товаров - calculate_total() только пересчитывает сумму
3. Если появилась переплата - оператор видит предупреждение
4. Оператор вручную создаёт возврат в кошелёк через форму

Преимущества:
- Одно место ответственности за переплаты
- Прозрачность для оператора
- Нет скрытых автоматизмов
- Легко обслуживать и отлаживать
- Стандартный подход для e-commerce
This commit is contained in:
2025-11-29 20:34:20 +03:00
parent 575c5d0c2f
commit 42eddc0fd1
2 changed files with 16 additions and 9 deletions

View File

@@ -323,20 +323,11 @@ class Order(models.Model):
# Пересчитываем стоимость доставки если она автоматическая
self.recalculate_delivery_cost()
# Сохраняем старую сумму для проверки изменений
old_total = self.total_amount
self.total_amount = items_total + self.delivery_cost
# Сохраняем изменения в БД
self.save(update_fields=['total_amount', 'delivery_cost', 'is_custom_delivery_cost'])
# Проверяем переплату ТОЛЬКО если сумма заказа уменьшилась
# (чтобы избежать двойной обработки при первоначальной оплате)
if old_total > 0 and self.total_amount < old_total and self.amount_paid > self.total_amount:
from customers.services.wallet_service import WalletService
# Переносим переплату в кошелёк (пользователь - modified_by или None)
WalletService.add_overpayment(self, self.modified_by)
return self.total_amount
def recalculate_amount_paid(self):

View File

@@ -609,6 +609,22 @@
<!-- Блок статистики -->
{% if order.pk %}
<!-- Предупреждение о переплате -->
{% if order.amount_paid > order.total_amount %}
{% with overpayment=order.amount_paid|add:"-"|add:order.total_amount %}
<div class="alert alert-warning mb-3">
<i class="bi bi-exclamation-triangle-fill"></i> <strong>Обнаружена переплата!</strong><br>
<small>
Оплачено <strong>{{ order.amount_paid|floatformat:2 }} руб.</strong>,
сумма заказа <strong>{{ order.total_amount|floatformat:2 }} руб.</strong><br>
Переплата: <strong class="text-danger">{{ overpayment|floatformat:2 }} руб.</strong><br>
Создайте возврат в кошелёк клиента во вкладке «Создать возврат» ниже.
</small>
</div>
{% endwith %}
{% endif %}
<div class="row mb-3">
<div class="col-md-6">
<div class="card border-primary">