feat: динамическая загрузка витринных комплектов в POS
- Добавлен API endpoint GET /pos/api/showcase-kits/ для получения актуальных витринных букетов - Изменена переменная SHOWCASE_KITS на изменяемую showcaseKits - Добавлена функция refreshShowcaseKits() для обновления данных с сервера - Кнопка ВИТРИНА теперь загружает свежие данные перед отображением - После создания временного букета автоматически обновляется список и переключается вид на витрину - Исправлена проблема с отображением только что созданных витринных букетов
This commit is contained in:
@@ -5,7 +5,7 @@ from django.http import JsonResponse
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.db import transaction
|
||||
from django.utils import timezone
|
||||
from decimal import Decimal
|
||||
from decimal import Decimal, InvalidOperation
|
||||
import json
|
||||
|
||||
from products.models import Product, ProductCategory, ProductKit, KitItem
|
||||
@@ -184,7 +184,8 @@ def get_showcases_api(request):
|
||||
'id': s.id,
|
||||
'name': s.name,
|
||||
'warehouse_name': s.warehouse.name,
|
||||
'warehouse_id': s.warehouse.id
|
||||
'warehouse_id': s.warehouse.id,
|
||||
'is_default_warehouse': s.warehouse.is_default # Для автовыбора
|
||||
} for s in showcases]
|
||||
|
||||
return JsonResponse({
|
||||
@@ -193,6 +194,21 @@ def get_showcases_api(request):
|
||||
})
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def get_showcase_kits_api(request):
|
||||
"""
|
||||
API endpoint для получения актуального списка витринных комплектов.
|
||||
Используется для динамического обновления после создания нового букета.
|
||||
"""
|
||||
showcase_kits_data = get_showcase_kits_for_pos()
|
||||
|
||||
return JsonResponse({
|
||||
'success': True,
|
||||
'items': showcase_kits_data
|
||||
})
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def create_temp_kit_to_showcase(request):
|
||||
@@ -200,26 +216,39 @@ def create_temp_kit_to_showcase(request):
|
||||
API endpoint для создания временного комплекта из корзины POS
|
||||
и резервирования его на витрину.
|
||||
|
||||
Ожидаемый payload:
|
||||
{
|
||||
"kit_name": "Название комплекта",
|
||||
"showcase_id": 1,
|
||||
"items": [
|
||||
{"product_id": 1, "quantity": 2.0},
|
||||
{"product_id": 3, "quantity": 1.0}
|
||||
],
|
||||
"price_adjustment_type": "none", // optional
|
||||
"price_adjustment_value": 0 // optional
|
||||
}
|
||||
Ожидаемый payload (multipart/form-data):
|
||||
- kit_name: Название комплекта
|
||||
- showcase_id: ID витрины
|
||||
- items: JSON список [{product_id, quantity}, ...]
|
||||
- description: Описание (опционально)
|
||||
- price_adjustment_type: Тип корректировки (опционально)
|
||||
- price_adjustment_value: Значение корректировки (опционально)
|
||||
- sale_price: Ручная финальная цена (опционально)
|
||||
- photo: Файл изображения (опционально)
|
||||
"""
|
||||
try:
|
||||
data = json.loads(request.body)
|
||||
# Получаем данные из FormData
|
||||
kit_name = request.POST.get('kit_name', '').strip()
|
||||
showcase_id = request.POST.get('showcase_id')
|
||||
description = request.POST.get('description', '').strip()
|
||||
items_json = request.POST.get('items', '[]')
|
||||
price_adjustment_type = request.POST.get('price_adjustment_type', 'none')
|
||||
price_adjustment_value = Decimal(str(request.POST.get('price_adjustment_value', 0)))
|
||||
sale_price_str = request.POST.get('sale_price', '')
|
||||
photo_file = request.FILES.get('photo')
|
||||
|
||||
kit_name = data.get('kit_name', '').strip()
|
||||
showcase_id = data.get('showcase_id')
|
||||
items = data.get('items', [])
|
||||
price_adjustment_type = data.get('price_adjustment_type', 'none')
|
||||
price_adjustment_value = Decimal(str(data.get('price_adjustment_value', 0)))
|
||||
# Парсим items из JSON
|
||||
items = json.loads(items_json)
|
||||
|
||||
# Sale price (опционально)
|
||||
sale_price = None
|
||||
if sale_price_str:
|
||||
try:
|
||||
sale_price = Decimal(str(sale_price_str))
|
||||
if sale_price <= 0:
|
||||
sale_price = None
|
||||
except (ValueError, InvalidOperation):
|
||||
sale_price = None
|
||||
|
||||
# Валидация
|
||||
if not kit_name:
|
||||
@@ -275,10 +304,12 @@ def create_temp_kit_to_showcase(request):
|
||||
# 1. Создаём ProductKit (is_temporary=True)
|
||||
kit = ProductKit.objects.create(
|
||||
name=kit_name,
|
||||
description=description,
|
||||
is_temporary=True,
|
||||
status='active',
|
||||
price_adjustment_type=price_adjustment_type,
|
||||
price_adjustment_value=price_adjustment_value
|
||||
price_adjustment_value=price_adjustment_value,
|
||||
sale_price=sale_price
|
||||
)
|
||||
|
||||
# 2. Создаём KitItem для каждого товара из корзины
|
||||
@@ -292,7 +323,16 @@ def create_temp_kit_to_showcase(request):
|
||||
# 3. Пересчитываем цену комплекта
|
||||
kit.recalculate_base_price()
|
||||
|
||||
# 4. Резервируем комплект на витрину
|
||||
# 4. Загружаем фото, если есть
|
||||
if photo_file:
|
||||
from products.models import ProductKitPhoto
|
||||
ProductKitPhoto.objects.create(
|
||||
kit=kit,
|
||||
image=photo_file,
|
||||
order=0
|
||||
)
|
||||
|
||||
# 5. Резервируем комплект на витрину
|
||||
result = ShowcaseManager.reserve_kit_to_showcase(
|
||||
product_kit=kit,
|
||||
showcase=showcase,
|
||||
|
||||
Reference in New Issue
Block a user