Рефакторинг: вынос логики онбординга тенанта в сервисный слой

Создан TenantOnboardingService как единый источник истины для:
- Активации заявки на регистрацию тенанта
- Создания Client, Domain, Subscription
- Инициализации системных данных (Customer, статусы, способы оплаты, склад, витрина)

Новые сервисы:
- TenantOnboardingService (tenants/services/onboarding.py)
- WarehouseService (inventory/services/warehouse_service.py)
- ShowcaseService (inventory/services/showcase_service.py)
- PaymentMethodService (orders/services/payment_method_service.py)

Рефакторинг:
- admin.py: 220 строк → 5 строк (делегирование сервису)
- init_tenant_data.py: 259 строк → 68 строк
- activate_registration.py: использует сервис
- Тесты обновлены для вызова сервиса напрямую

При создании тенанта автоматически создаются склад и витрина по умолчанию.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-30 14:52:55 +03:00
parent 658cd59511
commit b59ad725cb
13 changed files with 679 additions and 477 deletions

View File

@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
"""
Сервис для работы с витринами.
"""
from inventory.models import Showcase, Warehouse
from inventory.services.warehouse_service import WarehouseService
class ShowcaseService:
"""Сервис управления витринами"""
# Константы для витрины по умолчанию
DEFAULT_NAME = 'Основная витрина'
DEFAULT_DESCRIPTION = 'Витрина по умолчанию, созданная автоматически при регистрации'
@classmethod
def get_default(cls) -> Showcase | None:
"""
Получить витрину по умолчанию.
Returns:
Showcase или None если не найдена
"""
return Showcase.objects.filter(is_default=True, is_active=True).first()
@classmethod
def get_or_create_default(cls, warehouse: Warehouse = None) -> tuple[Showcase, bool]:
"""
Получить или создать витрину по умолчанию.
Args:
warehouse: Склад для витрины. Если не указан, используется склад по умолчанию.
Returns:
tuple (Showcase, created: bool)
Raises:
ValueError: если склад не найден и не может быть создан
"""
if warehouse is None:
warehouse, _ = WarehouseService.get_or_create_default()
return Showcase.objects.get_or_create(
warehouse=warehouse,
is_default=True,
defaults={
'name': cls.DEFAULT_NAME,
'description': cls.DEFAULT_DESCRIPTION,
'is_active': True,
}
)
@classmethod
def reset_default(cls, warehouse: Warehouse = None) -> Showcase:
"""
Удалить и пересоздать витрину по умолчанию.
Используется при --reset в init_tenant_data.
Args:
warehouse: Склад для витрины
Returns:
Новый Showcase
"""
if warehouse is None:
warehouse, _ = WarehouseService.get_or_create_default()
Showcase.objects.filter(warehouse=warehouse, is_default=True).delete()
showcase, _ = cls.get_or_create_default(warehouse)
return showcase