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

Создан 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,54 @@
# -*- coding: utf-8 -*-
"""
Сервис для работы со складами.
"""
from inventory.models import Warehouse
class WarehouseService:
"""Сервис управления складами"""
# Константы для склада по умолчанию
DEFAULT_NAME = 'Основной склад'
DEFAULT_DESCRIPTION = 'Склад по умолчанию, созданный автоматически при регистрации'
@classmethod
def get_default(cls) -> Warehouse | None:
"""
Получить склад по умолчанию.
Returns:
Warehouse или None если не найден
"""
return Warehouse.objects.filter(is_default=True, is_active=True).first()
@classmethod
def get_or_create_default(cls) -> tuple[Warehouse, bool]:
"""
Получить или создать склад по умолчанию.
Returns:
tuple (Warehouse, created: bool)
"""
return Warehouse.objects.get_or_create(
is_default=True,
defaults={
'name': cls.DEFAULT_NAME,
'description': cls.DEFAULT_DESCRIPTION,
'is_active': True,
'is_pickup_point': True,
}
)
@classmethod
def reset_default(cls) -> Warehouse:
"""
Удалить и пересоздать склад по умолчанию.
Используется при --reset в init_tenant_data.
Returns:
Новый Warehouse
"""
Warehouse.objects.filter(is_default=True).delete()
warehouse, _ = cls.get_or_create_default()
return warehouse