Реализован выбор склада для POS: добавлена логика выбора склада по умолчанию из сессии, эндпоинт смены склада, модалка выбора и отображение текущего склада

This commit is contained in:
2025-11-17 13:17:38 +03:00
parent 580003ec8b
commit 4961660b7a
4 changed files with 201 additions and 0 deletions

View File

@@ -14,6 +14,38 @@ from inventory.models import Showcase, Reservation, Warehouse
from inventory.services import ShowcaseManager
def get_pos_warehouse(request):
"""
Получить текущий склад для POS из сессии или выбрать дефолтный.
Логика выбора:
1. Если в сессии есть pos_warehouse_id - используем его
2. Иначе берем склад с is_default=True
3. Если нет is_default - берем первый активный
4. Если нет активных складов - None
"""
warehouse_id = request.session.get('pos_warehouse_id')
if warehouse_id:
try:
return Warehouse.objects.get(id=warehouse_id, is_active=True)
except Warehouse.DoesNotExist:
# Склад был удален или деактивирован - сбрасываем сессию
request.session.pop('pos_warehouse_id', None)
# Ищем склад по умолчанию
warehouse = Warehouse.objects.filter(is_active=True, is_default=True).first()
if not warehouse:
# Берем любой первый активный
warehouse = Warehouse.objects.filter(is_active=True).first()
# Сохраняем в сессию для следующих запросов
if warehouse:
request.session['pos_warehouse_id'] = warehouse.id
return warehouse
def get_showcase_kits_for_pos():
"""
Получает витринные комплекты для отображения в POS.
@@ -124,9 +156,27 @@ def pos_terminal(request):
Tablet-friendly POS screen prototype.
Shows categories and all items (products + kits) for quick tap-to-add.
Оптимизировано: убрана стартовая загрузка витрин, только thumbnail фото.
Работает только с одним выбранным складом.
"""
from products.models import ProductPhoto, ProductKitPhoto
# Получаем текущий склад для POS
current_warehouse = get_pos_warehouse(request)
if not current_warehouse:
# Нет активных складов - показываем ошибку
from django.contrib import messages
messages.error(request, 'Нет активных складов. Обратитесь к администратору.')
context = {
'categories_json': json.dumps([]),
'items_json': json.dumps([]),
'showcase_kits_json': json.dumps([]),
'current_warehouse': None,
'warehouses': [],
'title': 'POS Terminal',
}
return render(request, 'pos/terminal.html', context)
categories_qs = ProductCategory.objects.filter(is_active=True)
# Prefetch для первого фото товаров
@@ -195,16 +245,52 @@ def pos_terminal(request):
# Объединяем все позиции
all_items = products + kits
# Список всех активных складов для модалки выбора
warehouses = Warehouse.objects.filter(is_active=True).order_by('-is_default', 'name')
warehouses_list = [{
'id': w.id,
'name': w.name,
'is_default': w.is_default
} for w in warehouses]
context = {
'categories_json': json.dumps(categories),
'items_json': json.dumps(all_items),
'showcase_kits_json': json.dumps([]), # Пустой массив - загрузка по API
'current_warehouse': {
'id': current_warehouse.id,
'name': current_warehouse.name
},
'warehouses': warehouses_list,
'title': 'POS Terminal',
}
return render(request, 'pos/terminal.html', context)
@login_required
@require_http_methods(["POST"])
def set_warehouse(request, warehouse_id):
"""
Установить текущий склад для POS.
Сохраняет выбор в сессию.
"""
try:
warehouse = Warehouse.objects.get(id=warehouse_id, is_active=True)
request.session['pos_warehouse_id'] = warehouse.id
return JsonResponse({
'success': True,
'warehouse_id': warehouse.id,
'warehouse_name': warehouse.name
})
except Warehouse.DoesNotExist:
return JsonResponse({
'success': False,
'error': 'Склад не найден или неактивен'
}, status=404)
@login_required
@require_http_methods(["GET"])
def showcase_items_api(request):