Единый источник истины для способов оплаты
Проблема #1: Дублирование кода способов оплаты - В tenants/admin.py был полный список способов оплаты (45 строк) - В orders/management/commands/create_payment_methods.py был другой список - При создании тенанта отсутствовал способ 'account_balance' - Нарушение DRY принципа Решение: Single Source of Truth - Единственный источник истины: команда create_payment_methods - В tenants/admin.py заменено дублирование на call_command() - Удалено 45 строк дублирующего кода - Теперь все тенанты получают одинаковый полный список Проблема #2: AttributeError в админке PaymentMethod - obj.payments.count() вызывал ошибку - В модели Transaction связь называется 'transactions', а не 'payments' Решение: Исправлено в orders/admin.py - obj.payments → obj.transactions (2 места) - Админка PaymentMethod теперь работает корректно Для тенанта buba: - Создан скрипт add_payment_methods_to_buba.py - Добавлен недостающий способ оплаты 'С баланса счёта' Изменённые файлы: - myproject/tenants/admin.py - вызов команды вместо дублирования - myproject/orders/admin.py - исправлено на transactions - add_payment_methods_to_buba.py - скрипт для существующих тенантов
This commit is contained in:
40
add_payment_methods_to_buba.py
Normal file
40
add_payment_methods_to_buba.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Скрипт для добавления способов оплаты в тенант buba
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import django
|
||||||
|
|
||||||
|
# Добавляем путь к проекту
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'myproject'))
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
|
||||||
|
django.setup()
|
||||||
|
|
||||||
|
from django_tenants.utils import schema_context
|
||||||
|
from django.core.management import call_command
|
||||||
|
|
||||||
|
print("=" * 70)
|
||||||
|
print("Добавление способов оплаты в тенант 'buba'")
|
||||||
|
print("=" * 70)
|
||||||
|
|
||||||
|
# Переключаемся на схему buba и создаём способы оплаты
|
||||||
|
with schema_context('buba'):
|
||||||
|
print("\n1. Создание способов оплаты...")
|
||||||
|
call_command('create_payment_methods')
|
||||||
|
|
||||||
|
# Проверяем что создалось
|
||||||
|
from orders.models import PaymentMethod
|
||||||
|
methods = PaymentMethod.objects.all().order_by('order')
|
||||||
|
|
||||||
|
print(f"\n2. Проверка созданных способов оплаты:")
|
||||||
|
print(f" Всего: {methods.count()}")
|
||||||
|
for method in methods:
|
||||||
|
status = "✓" if method.is_active else "✗"
|
||||||
|
print(f" {status} [{method.order}] {method.name} ({method.code})")
|
||||||
|
|
||||||
|
print("\n" + "=" * 70)
|
||||||
|
print("✓ Готово!")
|
||||||
|
print("=" * 70)
|
||||||
@@ -441,7 +441,7 @@ class PaymentMethodAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
def payments_count(self, obj):
|
def payments_count(self, obj):
|
||||||
"""Количество платежей этим способом"""
|
"""Количество платежей этим способом"""
|
||||||
count = obj.payments.count()
|
count = obj.transactions.count()
|
||||||
if count == 0:
|
if count == 0:
|
||||||
return format_html('<span style="color: #999;">{}</span>', count)
|
return format_html('<span style="color: #999;">{}</span>', count)
|
||||||
return format_html('<span style="font-weight: bold;">{}</span>', count)
|
return format_html('<span style="font-weight: bold;">{}</span>', count)
|
||||||
@@ -450,7 +450,7 @@ class PaymentMethodAdmin(admin.ModelAdmin):
|
|||||||
def has_delete_permission(self, request, obj=None):
|
def has_delete_permission(self, request, obj=None):
|
||||||
"""Запрещаем удаление используемых способов оплаты"""
|
"""Запрещаем удаление используемых способов оплаты"""
|
||||||
if obj:
|
if obj:
|
||||||
# Разрешаем удаление только если нет связанных платежей
|
# Разрешаем удаление только если нет связанных транзакций
|
||||||
if obj.payments.exists():
|
if obj.transactions.exists():
|
||||||
return False
|
return False
|
||||||
return super().has_delete_permission(request, obj)
|
return super().has_delete_permission(request, obj)
|
||||||
|
|||||||
@@ -312,51 +312,13 @@ class TenantRegistrationAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
# Создаем системные способы оплаты
|
# Создаем системные способы оплаты
|
||||||
logger.info(f"Создание системных способов оплаты для тенанта: {client.id}")
|
logger.info(f"Создание системных способов оплаты для тенанта: {client.id}")
|
||||||
from orders.models import PaymentMethod
|
from django.core.management import call_command
|
||||||
|
|
||||||
try:
|
try:
|
||||||
payment_methods = [
|
# Вызываем команду создания способов оплаты
|
||||||
{
|
# Это единственный источник истины для списка способов оплаты
|
||||||
'code': 'cash',
|
call_command('create_payment_methods')
|
||||||
'name': 'Наличными',
|
logger.info("Системные способы оплаты успешно созданы")
|
||||||
'description': 'Оплата наличными деньгами',
|
|
||||||
'is_system': True,
|
|
||||||
'order': 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'code': 'card',
|
|
||||||
'name': 'Картой',
|
|
||||||
'description': 'Оплата банковской картой',
|
|
||||||
'is_system': True,
|
|
||||||
'order': 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'code': 'online',
|
|
||||||
'name': 'Онлайн',
|
|
||||||
'description': 'Онлайн оплата через платежную систему',
|
|
||||||
'is_system': True,
|
|
||||||
'order': 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'code': 'legal_entity',
|
|
||||||
'name': 'Безнал от ЮРЛИЦ',
|
|
||||||
'description': 'Безналичный расчёт от юридических лиц',
|
|
||||||
'is_system': True,
|
|
||||||
'order': 4
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
created_count = 0
|
|
||||||
for method_data in payment_methods:
|
|
||||||
method, created = PaymentMethod.objects.get_or_create(
|
|
||||||
code=method_data['code'],
|
|
||||||
defaults=method_data
|
|
||||||
)
|
|
||||||
if created:
|
|
||||||
created_count += 1
|
|
||||||
logger.info(f"Создан способ оплаты: {method.name}")
|
|
||||||
|
|
||||||
logger.info(f"Системные способы оплаты успешно созданы: {created_count} новых")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Ошибка при создании способов оплаты: {e}", exc_info=True)
|
logger.error(f"Ошибка при создании способов оплаты: {e}", exc_info=True)
|
||||||
# Не прерываем процесс, т.к. это не критично
|
# Не прерываем процесс, т.к. это не критично
|
||||||
|
|||||||
Reference in New Issue
Block a user