Files
octopus/myproject/inventory/views/debug_views.py
Andrey Smakotin 7cab70e8b0 Расширена debug страница для отслеживания статусов ShowcaseItem
- inventory/templates/inventory/debug_page.html: добавлена секция ShowcaseItem
  * Таблица с полями: ID, Название, Статус, OrderItem, Locked By
  * Цветовые индикаторы статусов (available/in_cart/reserved/sold)
  * Ссылки на связанные OrderItem
- inventory/views/debug_views.py: добавлены данные ShowcaseItem в контекст
  * showcase_items queryset с select_related для оптимизации
  * Статистика по статусам ShowcaseItem
- Инструмент для тестирования lifecycle витринных букетов
2026-01-05 01:38:59 +03:00

171 lines
7.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Отладочные view для суперюзеров.
Для мониторинга работы системы инвентаризации.
"""
from django.contrib.auth.decorators import login_required, user_passes_test
from django.shortcuts import render
from django.db.models import Q, Sum, Count
from inventory.models import (
StockBatch, Stock, Reservation, Sale, SaleBatchAllocation, WriteOff,
WriteOffDocument, WriteOffDocumentItem, IncomingDocument, IncomingDocumentItem,
ShowcaseItem
)
from orders.models import Order
from products.models import Product
from inventory.models import Warehouse
def is_superuser(user):
"""Проверка что пользователь - суперюзер."""
return user.is_superuser
@login_required
@user_passes_test(is_superuser)
def debug_inventory_page(request):
"""
Отладочная страница для суперюзеров.
Показывает полную картину по инвентаризации: партии, остатки, резервы, продажи.
"""
# Получаем параметры фильтров
product_id = request.GET.get('product')
order_number = request.GET.get('order')
warehouse_id = request.GET.get('warehouse')
# Базовые querysets
stock_batches = StockBatch.objects.select_related('product', 'warehouse').order_by('-created_at')
stocks = Stock.objects.select_related('product', 'warehouse').order_by('product__name')
reservations = Reservation.objects.select_related(
'product', 'warehouse', 'order_item__order'
).order_by('-reserved_at')
sales = Sale.objects.select_related('product', 'warehouse', 'order').order_by('-date')
allocations = SaleBatchAllocation.objects.select_related(
'sale__product', 'batch'
).order_by('-id')
# Все списания: из продаж (WriteOff) и из документов списания (WriteOffDocumentItem)
writeoffs = WriteOff.objects.select_related('batch__product', 'batch__warehouse').order_by('-date')
writeoff_documents = WriteOffDocument.objects.select_related('warehouse').order_by('-date')
writeoff_document_items = WriteOffDocumentItem.objects.select_related(
'product', 'document__warehouse'
).order_by('-id')
# Документы поступления
incoming_documents = IncomingDocument.objects.select_related('warehouse', 'created_by', 'confirmed_by').order_by('-date', '-created_at')
incoming_document_items = IncomingDocumentItem.objects.select_related('product', 'document__warehouse').order_by('-id')
orders = Order.objects.prefetch_related('items').order_by('-created_at')
# Витринные экземпляры
showcase_items = ShowcaseItem.objects.select_related(
'product_kit', 'showcase', 'sold_order_item__order'
).order_by('-updated_at')
# Применяем фильтры
if product_id:
product = Product.objects.filter(id=product_id).first()
stock_batches = stock_batches.filter(product_id=product_id)
stocks = stocks.filter(product_id=product_id)
reservations = reservations.filter(product_id=product_id)
sales = sales.filter(product_id=product_id)
allocations = allocations.filter(sale__product_id=product_id)
writeoffs = writeoffs.filter(batch__product_id=product_id)
writeoff_document_items = writeoff_document_items.filter(product_id=product_id)
incoming_document_items = incoming_document_items.filter(product_id=product_id)
orders = orders.filter(items__product_id=product_id).distinct()
else:
product = None
if order_number:
# Парсим номер заказа: "ORD-103" -> 103 или "103" -> 103
try:
# Если формат "ORD-XXX", извлекаем число
if order_number.upper().startswith('ORD-'):
order_num = int(order_number.upper().replace('ORD-', ''))
else:
# Просто число
order_num = int(order_number)
order = Order.objects.filter(order_number=order_num).first()
except (ValueError, AttributeError):
order = None
if order:
reservations = reservations.filter(order_item__order=order)
sales = sales.filter(order=order)
# Фильтруем товары по заказу
product_ids = order.items.values_list('product_id', flat=True)
stock_batches = stock_batches.filter(product_id__in=product_ids)
stocks = stocks.filter(product_id__in=product_ids)
allocations = allocations.filter(sale__order=order)
# Фильтруем только этот заказ в таблице заказов
orders = orders.filter(id=order.id)
# Фильтруем витринные экземпляры по заказу
showcase_items = showcase_items.filter(sold_order_item__order=order)
else:
order = None
if warehouse_id:
warehouse = Warehouse.objects.filter(id=warehouse_id).first()
stock_batches = stock_batches.filter(warehouse_id=warehouse_id)
stocks = stocks.filter(warehouse_id=warehouse_id)
reservations = reservations.filter(warehouse_id=warehouse_id)
sales = sales.filter(warehouse_id=warehouse_id)
writeoffs = writeoffs.filter(batch__warehouse_id=warehouse_id)
writeoff_documents = writeoff_documents.filter(warehouse_id=warehouse_id)
writeoff_document_items = writeoff_document_items.filter(document__warehouse_id=warehouse_id)
incoming_documents = incoming_documents.filter(warehouse_id=warehouse_id)
incoming_document_items = incoming_document_items.filter(document__warehouse_id=warehouse_id)
else:
warehouse = None
# Ограничиваем количество записей для производительности
stock_batches = stock_batches[:100]
stocks = stocks[:100]
reservations = reservations[:100]
sales = sales[:100]
allocations = allocations[:100]
writeoffs = writeoffs[:100]
writeoff_documents = writeoff_documents[:50]
writeoff_document_items = writeoff_document_items[:100]
incoming_documents = incoming_documents[:50]
incoming_document_items = incoming_document_items[:100]
orders = orders[:50]
showcase_items = showcase_items[:100]
# Статистика по статусам ShowcaseItem
showcase_items_stats = ShowcaseItem.objects.aggregate(
available=Count('id', filter=Q(status='available')),
in_cart=Count('id', filter=Q(status='in_cart')),
reserved=Count('id', filter=Q(status='reserved')),
sold=Count('id', filter=Q(status='sold')),
dismantled=Count('id', filter=Q(status='dismantled')),
)
# Списки для фильтров
products = Product.objects.filter(archived_at__isnull=True).order_by('name')[:200]
warehouses = Warehouse.objects.filter(is_active=True).order_by('name')
context = {
'stock_batches': stock_batches,
'stocks': stocks,
'reservations': reservations,
'sales': sales,
'allocations': allocations,
'writeoffs': writeoffs,
'writeoff_documents': writeoff_documents,
'writeoff_document_items': writeoff_document_items,
'incoming_documents': incoming_documents,
'incoming_document_items': incoming_document_items,
'orders': orders,
'showcase_items': showcase_items,
'showcase_items_stats': showcase_items_stats,
'products': products,
'warehouses': warehouses,
'selected_product': product,
'selected_order': order,
'selected_warehouse': warehouse,
'product_id': product_id,
'order_number': order_number,
'warehouse_id': warehouse_id,
}
return render(request, 'inventory/debug_page.html', context)