Files
octopus/myproject/inventory/views/debug_views.py
Andrey Smakotin a8ba5ce780 Улучшения инвентаризации: автоматическое проведение документов, оптимизация запросов и улучшения UI
- Автоматическое проведение документов списания и оприходования после завершения инвентаризации
- Оптимизация SQL-запросов: устранение N+1, bulk-операции для Stock, агрегация для StockBatch и Reservation
- Изменение формулы расчета разницы: (quantity_fact + quantity_reserved) - quantity_available
- Переименование поля 'По факту' в 'Подсчитано (факт, свободные)'
- Добавлены столбцы 'В резервах' и 'Всего на складе' в таблицу инвентаризации
- Перемещение столбца 'В системе (свободно)' после 'В резервах' с визуальным выделением
- Центральное выравнивание значений в столбцах таблицы
- Автоматическое выделение текста при фокусе на поле ввода количества
- Исправление форматирования разницы (убраны лишние нули)
- Изменение статуса 'Не обработана' на 'Не проведено'
- Добавление номера документа для инвентаризаций (INV-XXXXXX)
- Отображение всех типов списаний в debug-странице (WriteOff, WriteOffDocument, WriteOffDocumentItem)
- Улучшение отображения документов в детальном просмотре инвентаризации с возможностью перехода к ним
2025-12-21 23:59:02 +03:00

138 lines
6.1 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
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')
orders = Order.objects.prefetch_related('items').order_by('-created_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)
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)
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)
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]
orders = orders[:50]
# Списки для фильтров
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,
'orders': orders,
'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)