+
{% if show_view_toggle|default:True %}
diff --git a/myproject/products/views/api_views.py b/myproject/products/views/api_views.py
index 5d50fd9..0111215 100644
--- a/myproject/products/views/api_views.py
+++ b/myproject/products/views/api_views.py
@@ -21,10 +21,11 @@ def _get_product_photo_url(product_id):
return None
-def _apply_product_filters(queryset, category_id=None, tag_id=None, in_stock_only=False, warehouse_id=None, skip_stock_filter=False):
+def _apply_product_filters(queryset, category_id=None, tag_id=None, stock_status='all', warehouse_id=None, skip_stock_filter=False):
"""Применяет фильтры к queryset товаров.
Args:
+ stock_status: 'all' - все товары, 'in_stock' - только в наличии, 'out_of_stock' - только не в наличии
skip_stock_filter: Если True, warehouse_id не фильтрует по остаткам.
Используется для приёмки товаров.
"""
@@ -32,8 +33,10 @@ def _apply_product_filters(queryset, category_id=None, tag_id=None, in_stock_onl
queryset = queryset.filter(categories__id=category_id)
if tag_id:
queryset = queryset.filter(tags__id=tag_id)
- if in_stock_only:
+ if stock_status == 'in_stock':
queryset = queryset.filter(in_stock=True)
+ elif stock_status == 'out_of_stock':
+ queryset = queryset.filter(in_stock=False)
if warehouse_id and not skip_stock_filter:
# Фильтруем только товары, которые есть на указанном складе с доступным количеством
# НЕ применяется при skip_stock_filter=True (приёмка товаров)
@@ -58,7 +61,7 @@ def search_products_and_variants(request):
- page: номер страницы для пагинации (по умолчанию 1)
- category: ID категории для фильтрации (опционально)
- tag: ID тега для фильтрации (опционально)
- - in_stock: 'true' для фильтрации только товаров в наличии (опционально)
+ - stock_status: 'all' (все), 'in_stock' (в наличии), 'out_of_stock' (не в наличии) (опционально, по умолчанию 'all')
- warehouse: ID склада для фильтрации только товаров с доступным остатком (опционально)
Возвращает JSON в формате Select2 с группировкой:
@@ -190,14 +193,14 @@ def search_products_and_variants(request):
# Дополнительные фильтры
category_id = request.GET.get('category', '').strip()
tag_id = request.GET.get('tag', '').strip()
- in_stock_only = request.GET.get('in_stock', '').lower() == 'true'
+ stock_status = request.GET.get('stock_status', 'all').strip()
warehouse_id = request.GET.get('warehouse', '').strip()
skip_stock_filter = request.GET.get('skip_stock_filter', '').lower() == 'true'
results = []
# Проверяем, есть ли дополнительные фильтры
- has_filters = category_id or tag_id or in_stock_only or warehouse_id
+ has_filters = category_id or tag_id or stock_status != 'all' or warehouse_id
# Если поиска нет - показываем популярные товары и комплекты
if not query or len(query) < 2:
@@ -215,7 +218,7 @@ def search_products_and_variants(request):
# Показываем последние добавленные активные товары
products_qs = Product.objects.filter(status='active').prefetch_related('sales_units__unit')
# Применяем фильтры
- products_qs = _apply_product_filters(products_qs, category_id, tag_id, in_stock_only, warehouse_id, skip_stock_filter)
+ products_qs = _apply_product_filters(products_qs, category_id, tag_id, stock_status, warehouse_id, skip_stock_filter)
products = products_qs.order_by('-created_at')[:page_size]
for product in products:
@@ -359,7 +362,7 @@ def search_products_and_variants(request):
).order_by('-relevance', 'name')
# Применяем дополнительные фильтры
- products_query = _apply_product_filters(products_query, category_id, tag_id, in_stock_only, warehouse_id, skip_stock_filter)
+ products_query = _apply_product_filters(products_query, category_id, tag_id, stock_status, warehouse_id, skip_stock_filter)
# Добавляем prefetch для единиц продажи
products_query = products_query.prefetch_related('sales_units__unit')