Добавлено отображение остатков и резервов в карточках товаров POS

- Аннотация товаров остатками (available_qty) и резервами (reserved_qty) через Subquery
- Компактный формат отображения: X(−Y) где X - доступно, Y - зарезервировано
- Визуальная стилизация: крупное число для остатков, мелкое для резервов
- Цветовая индикация: зелёный (≥5), жёлтый (<5), красный (≤0)
- Без дополнительных SQL-запросов, оптимизировано через подзапросы
This commit is contained in:
2025-11-17 14:03:31 +03:00
parent 4961660b7a
commit e23bdef679
2 changed files with 66 additions and 4 deletions

View File

@@ -4,13 +4,14 @@ from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.db import transaction
from django.db.models import Prefetch, OuterRef, Subquery
from django.db.models import Prefetch, OuterRef, Subquery, DecimalField
from django.db.models.functions import Coalesce
from django.utils import timezone
from decimal import Decimal, InvalidOperation
import json
from products.models import Product, ProductCategory, ProductKit, KitItem
from inventory.models import Showcase, Reservation, Warehouse
from inventory.models import Showcase, Reservation, Warehouse, Stock
from inventory.services import ShowcaseManager
@@ -186,8 +187,31 @@ def pos_terminal(request):
to_attr='first_photo_list'
)
# Подзапросы для аннотации остатков по текущему складу
stock_available_subquery = Stock.objects.filter(
product=OuterRef('pk'),
warehouse=current_warehouse
).values('quantity_available')[:1]
stock_reserved_subquery = Stock.objects.filter(
product=OuterRef('pk'),
warehouse=current_warehouse
).values('quantity_reserved')[:1]
# Показываем все товары, не только in_stock
products_qs = Product.objects.all().prefetch_related(
# Аннотируем остатками и резервами с текущего склада
products_qs = Product.objects.all().annotate(
available_qty=Coalesce(
Subquery(stock_available_subquery, output_field=DecimalField()),
Decimal('0'),
output_field=DecimalField()
),
reserved_qty=Coalesce(
Subquery(stock_reserved_subquery, output_field=DecimalField()),
Decimal('0'),
output_field=DecimalField()
)
).prefetch_related(
'categories',
first_product_photo
)
@@ -222,7 +246,9 @@ def pos_terminal(request):
'in_stock': p.in_stock,
'sku': p.sku or '',
'image': image_url,
'type': 'product'
'type': 'product',
'available_qty': str(p.available_qty),
'reserved_qty': str(p.reserved_qty)
})
# Сериализация комплектов с оптимизацией фото