Рефакторинг: перенос логики создания временных комплектов в сервис

Изменения:
- Удалена функция create_temporary_kit из myproject/orders/views.py
- Перенесена в новый сервис myproject/products/services/kit_service.py
- Добавлен API endpoint products:api-temporary-kit-create для создания временных комплектов
- Обновлены URL-ы соответственно

Преимущества:
- Логика временных комплектов теперь находится в соответствующем приложении (products)
- Упрощена архитектура orders приложения
- Сервис может быть переиспользован в других контекстах
- Лучшее разделение ответственности между приложениями

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-10 23:44:05 +03:00
parent 3c0ba70bc8
commit 5d5de1fe31
15 changed files with 471 additions and 150 deletions

View File

@@ -71,7 +71,7 @@ from .variant_group_views import (
)
# API представления
from .api_views import search_products_and_variants, validate_kit_cost
from .api_views import search_products_and_variants, validate_kit_cost, create_temporary_kit_api
__all__ = [
@@ -132,4 +132,5 @@ __all__ = [
# API
'search_products_and_variants',
'validate_kit_cost',
'create_temporary_kit_api',
]

View File

@@ -531,3 +531,92 @@ def validate_kit_cost(request):
return JsonResponse({
'error': str(e)
}, status=500)
def create_temporary_kit_api(request):
"""
AJAX endpoint для создания временного комплекта.
Используется при оформлении заказа для создания букета "на лету".
Принимает JSON:
{
"name": "Букет для Анны",
"description": "Красные розы и белые лилии",
"order_id": 123, // опционально, если заказ уже создан
"components": [
{"product_id": 1, "quantity": "5"},
{"product_id": 2, "quantity": "3"}
]
}
Возвращает JSON:
{
"success": true,
"kit_id": 456,
"kit_name": "Букет для Анны",
"kit_sku": "KIT-000456",
"kit_price": "1500.00",
"message": "Временный комплект создан успешно"
}
"""
if request.method != 'POST':
return JsonResponse({
'success': False,
'error': 'Метод не поддерживается'
}, status=405)
import json
from ..services.kit_service import create_temporary_kit
from orders.models import Order
try:
data = json.loads(request.body)
name = data.get('name', '').strip()
description = data.get('description', '').strip()
order_id = data.get('order_id')
components = data.get('components', [])
# Получаем заказ если указан
order = None
if order_id:
try:
order = Order.objects.get(pk=order_id)
except Order.DoesNotExist:
return JsonResponse({
'success': False,
'error': f'Заказ #{order_id} не найден'
}, status=404)
# Создаем временный комплект через сервис
kit = create_temporary_kit(
name=name,
description=description,
components=components,
order=order
)
return JsonResponse({
'success': True,
'kit_id': kit.id,
'kit_name': kit.name,
'kit_sku': kit.sku,
'kit_price': str(kit.actual_price),
'message': f'Временный комплект "{kit.name}" создан успешно'
})
except ValueError as e:
return JsonResponse({
'success': False,
'error': str(e)
}, status=400)
except json.JSONDecodeError:
return JsonResponse({
'success': False,
'error': 'Некорректный JSON'
}, status=400)
except Exception as e:
return JsonResponse({
'success': False,
'error': f'Ошибка при создании комплекта: {str(e)}'
}, status=500)

View File

@@ -93,6 +93,28 @@ class ProductKitCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateVi
template_name = 'products/productkit_create.html'
permission_required = 'products.add_productkit'
def post(self, request, *args, **kwargs):
"""
Обрабатываем POST данные и очищаем ID товаров/комплектов от префиксов.
API возвращает ID в формате "product_123" или "kit_456", но Django ожидает числа.
"""
# Создаем изменяемую копию POST данных
post_data = request.POST.copy()
# Очищаем product ID от префиксов (product_123 -> 123)
for key in post_data.keys():
if key.endswith('-product') and post_data[key]:
value = post_data[key]
if '_' in value:
# Извлекаем числовой ID из "product_123"
numeric_id = value.split('_')[1]
post_data[key] = numeric_id
# Заменяем request.POST на очищенные данные
request.POST = post_data
return super().post(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@@ -199,6 +221,28 @@ class ProductKitUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateVi
template_name = 'products/productkit_edit.html'
permission_required = 'products.change_productkit'
def post(self, request, *args, **kwargs):
"""
Обрабатываем POST данные и очищаем ID товаров/комплектов от префиксов.
API возвращает ID в формате "product_123" или "kit_456", но Django ожидает числа.
"""
# Создаем изменяемую копию POST данных
post_data = request.POST.copy()
# Очищаем product ID от префиксов (product_123 -> 123)
for key in post_data.keys():
if key.endswith('-product') and post_data[key]:
value = post_data[key]
if '_' in value:
# Извлекаем числовой ID из "product_123"
numeric_id = value.split('_')[1]
post_data[key] = numeric_id
# Заменяем request.POST на очищенные данные
request.POST = post_data
return super().post(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)