Рефакторинг: перенос логики создания временных комплектов в сервис
Изменения: - Удалена функция 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:
@@ -14,7 +14,4 @@ urlpatterns = [
|
||||
# AJAX endpoints
|
||||
path('<int:pk>/autosave/', views.autosave_draft_order, name='order-autosave'),
|
||||
path('create-draft/', views.create_draft_from_form, name='order-create-draft'),
|
||||
|
||||
# Временные комплекты
|
||||
path('temporary-kits/create/', views.create_temporary_kit, name='temporary-kit-create'),
|
||||
]
|
||||
|
||||
@@ -3,7 +3,6 @@ from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib import messages
|
||||
from django.core.paginator import Paginator
|
||||
from django.http import JsonResponse
|
||||
from django.db import transaction
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import ValidationError
|
||||
@@ -11,7 +10,6 @@ from .models import Order, OrderItem
|
||||
from .forms import OrderForm, OrderItemFormSet
|
||||
from .filters import OrderFilter
|
||||
from .services import DraftOrderService
|
||||
from products.models import ProductKit, KitItem, Product
|
||||
import json
|
||||
|
||||
|
||||
@@ -383,122 +381,5 @@ def create_draft_from_form(request):
|
||||
|
||||
|
||||
# === ВРЕМЕННЫЕ КОМПЛЕКТЫ ===
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
def create_temporary_kit(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": "Временный комплект создан успешно"
|
||||
}
|
||||
"""
|
||||
import json
|
||||
from decimal import Decimal
|
||||
|
||||
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', [])
|
||||
|
||||
# Валидация
|
||||
if not name:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': 'Необходимо указать название комплекта'
|
||||
}, status=400)
|
||||
|
||||
if not components or len(components) == 0:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': 'Комплект должен содержать хотя бы один компонент'
|
||||
}, status=400)
|
||||
|
||||
# Создаем временный комплект
|
||||
with transaction.atomic():
|
||||
# Получаем заказ если указан
|
||||
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 = ProductKit.objects.create(
|
||||
name=name,
|
||||
description=description,
|
||||
is_temporary=True,
|
||||
is_active=True,
|
||||
order=order,
|
||||
price_adjustment_type='none'
|
||||
)
|
||||
|
||||
# Добавляем компоненты
|
||||
for component in components:
|
||||
product_id = component.get('product_id')
|
||||
quantity = component.get('quantity')
|
||||
|
||||
if not product_id or not quantity:
|
||||
continue
|
||||
|
||||
try:
|
||||
product = Product.objects.get(pk=product_id)
|
||||
KitItem.objects.create(
|
||||
kit=kit,
|
||||
product=product,
|
||||
quantity=Decimal(str(quantity))
|
||||
)
|
||||
except Product.DoesNotExist:
|
||||
# Пропускаем несуществующие товары
|
||||
continue
|
||||
except (ValueError, TypeError):
|
||||
# Пропускаем некорректные количества
|
||||
continue
|
||||
|
||||
# Пересчитываем цену комплекта
|
||||
kit.recalculate_base_price()
|
||||
|
||||
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 json.JSONDecodeError:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': 'Некорректный JSON'
|
||||
}, status=400)
|
||||
except Exception as e:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': f'Ошибка при создании комплекта: {str(e)}'
|
||||
}, status=500)
|
||||
# УДАЛЕНО: Логика создания временных комплектов перенесена в products.services.kit_service
|
||||
# Используйте API endpoint: products:api-temporary-kit-create
|
||||
|
||||
Reference in New Issue
Block a user