Исправлена форма заказа: две колонки и корректная работа кнопки сохранения
- Разделен экран на две колонки: заказ слева, оплата справа - Форма оплаты вынесена за пределы основной формы заказа (устранена проблема вложенных форм) - Исправлен метод calculate_total() для сохранения итоговой суммы в БД - Добавлена модель Transaction для учета платежей и возвратов - Добавлена модель PaymentMethod для методов оплаты - Удалена старая модель Payment, заменена на Transaction - Добавлен TransactionService для управления транзакциями - Обновлен интерфейс форм оплаты для правой колонки - Кнопка 'Сохранить изменения' теперь работает корректно
This commit is contained in:
@@ -74,7 +74,7 @@ class WalletService:
|
||||
def pay_with_wallet(order, amount, user):
|
||||
"""
|
||||
Оплата заказа из кошелька клиента.
|
||||
Списывает средства с кошелька и создаёт платёж в заказе.
|
||||
Создаёт транзакцию. Списание из кошелька происходит автоматически в Transaction.save().
|
||||
|
||||
Args:
|
||||
order: Заказ для оплаты
|
||||
@@ -84,15 +84,15 @@ class WalletService:
|
||||
Returns:
|
||||
Decimal: Фактически списанная сумма или None
|
||||
"""
|
||||
from customers.models import Customer, WalletTransaction
|
||||
from orders.models import Payment, PaymentMethod
|
||||
from customers.models import Customer
|
||||
from orders.services.transaction_service import TransactionService
|
||||
|
||||
# Округляем запрошенную сумму
|
||||
amount = _quantize(amount)
|
||||
if amount <= 0:
|
||||
return None
|
||||
|
||||
# Блокируем запись клиента
|
||||
# Блокируем запись клиента для проверки баланса
|
||||
customer = Customer.objects.select_for_update().get(pk=order.customer_id)
|
||||
|
||||
# Остаток к оплате по заказу
|
||||
@@ -105,46 +105,24 @@ class WalletService:
|
||||
if usable_amount <= 0:
|
||||
return None
|
||||
|
||||
# Получаем способ оплаты "С баланса счёта"
|
||||
try:
|
||||
payment_method = PaymentMethod.objects.get(code='account_balance')
|
||||
except PaymentMethod.DoesNotExist:
|
||||
raise ValueError(
|
||||
'Способ оплаты "account_balance" не найден. '
|
||||
'Запустите команду create_payment_methods.'
|
||||
)
|
||||
|
||||
# Создаём платёж в заказе
|
||||
Payment.objects.create(
|
||||
# Создаём транзакцию
|
||||
# Transaction.save() автоматически спишет из кошелька и создаст WalletTransaction
|
||||
TransactionService.create_payment(
|
||||
order=order,
|
||||
amount=usable_amount,
|
||||
payment_method=payment_method,
|
||||
created_by=user,
|
||||
payment_method='account_balance',
|
||||
user=user,
|
||||
notes='Оплата из кошелька клиента'
|
||||
)
|
||||
|
||||
# Уменьшаем баланс кошелька
|
||||
customer.wallet_balance = _quantize(customer.wallet_balance - usable_amount)
|
||||
customer.save(update_fields=['wallet_balance'])
|
||||
|
||||
# Создаём транзакцию для аудита
|
||||
WalletTransaction.objects.create(
|
||||
customer=customer,
|
||||
amount=usable_amount,
|
||||
transaction_type='spend',
|
||||
order=order,
|
||||
description=f'Оплата заказа #{order.order_number} из кошелька',
|
||||
created_by=user
|
||||
)
|
||||
|
||||
return usable_amount
|
||||
|
||||
@staticmethod
|
||||
@transaction.atomic
|
||||
def refund_wallet_payment(order, amount, user):
|
||||
"""
|
||||
Возврат средств в кошелёк при удалении платежа.
|
||||
Увеличивает баланс кошелька и создаёт транзакцию deposit.
|
||||
Возврат средств в кошелёк.
|
||||
Используется для создания транзакции возврата с кошельком.
|
||||
|
||||
Args:
|
||||
order: Заказ, по которому был платёж
|
||||
@@ -154,27 +132,20 @@ class WalletService:
|
||||
Returns:
|
||||
Decimal: Возвращённая сумма
|
||||
"""
|
||||
from customers.models import Customer, WalletTransaction
|
||||
from orders.services.transaction_service import TransactionService
|
||||
|
||||
amount = _quantize(amount)
|
||||
if amount <= 0:
|
||||
return None
|
||||
|
||||
# Блокируем запись клиента
|
||||
customer = Customer.objects.select_for_update().get(pk=order.customer_id)
|
||||
|
||||
# Увеличиваем баланс
|
||||
customer.wallet_balance = _quantize(customer.wallet_balance + amount)
|
||||
customer.save(update_fields=['wallet_balance'])
|
||||
|
||||
# Создаём транзакцию возврата
|
||||
WalletTransaction.objects.create(
|
||||
customer=customer,
|
||||
amount=amount,
|
||||
transaction_type='deposit',
|
||||
# Transaction.save() автоматически вернёт в кошелёк и создаст WalletTransaction
|
||||
TransactionService.create_refund(
|
||||
order=order,
|
||||
description=f'Возврат платежа по заказу #{order.order_number}',
|
||||
created_by=user
|
||||
amount=amount,
|
||||
payment_method='account_balance',
|
||||
user=user,
|
||||
reason='Возврат в кошелёк'
|
||||
)
|
||||
|
||||
return amount
|
||||
|
||||
Reference in New Issue
Block a user