Добавлена отладочная страница для суперюзеров (Inventory Debug)
Реализация:
- Создан view debug_inventory_page (только для суперюзеров)
- URL: /inventory/debug/
- Компактный дизайн с минимальными отступами и маленьким шрифтом (10-11px)
Функционал:
1. Показывает полную картину инвентаризации на одной странице:
- Заказы (Order) - номер, статус, покупатель, is_returned
- Остатки (Stock) - доступно, зарезервировано, свободно
- Партии (StockBatch) - количество, активность, дата поступления
- Резервы (Reservation) - статус (reserved/converted_to_sale/released), заказ, даты
- Продажи (Sale) - количество, цены, заказ
- Списания (SaleBatchAllocation) - откуда списано, сколько
2. Фильтры:
- По товару (dropdown с названием и SKU)
- По номеру заказа (текстовое поле)
- По складу (dropdown)
- Кнопка 'Применить' и 'Сбросить'
3. UI:
- Цветовая индикация статусов резервов
- Бейджи для ключевых данных
- Компактные таблицы Bootstrap
- Неактивные партии выделены красным
- Ограничение в 100 записей на таблицу для производительности
4. Навигация:
- Ссылка 🔧 Debug в navbar (видна только суперюзерам)
- Красный цвет для видимости
Юзкейс:
Суперюзер принимает товар на склад → оформляет заказ → меняет статусы →
переходит на /inventory/debug/ → видит полную картину всех изменений
Файлы:
- inventory/views/debug_views.py - новый view
- inventory/templates/inventory/debug_page.html - шаблон
- inventory/urls.py - добавлен роут
- templates/navbar.html - добавлена ссылка для суперюзеров
This commit is contained in:
417
myproject/inventory/templates/inventory/debug_page.html
Normal file
417
myproject/inventory/templates/inventory/debug_page.html
Normal file
@@ -0,0 +1,417 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}Отладка Inventory - Суперюзер{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<style>
|
||||
/* Компактный дизайн с маленькими отступами и шрифтом */
|
||||
.debug-page {
|
||||
font-size: 10px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
.debug-page h2 {
|
||||
font-size: 14px;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 8px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
border-bottom: 2px solid #007bff;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
.debug-page h3 {
|
||||
font-size: 12px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
color: #555;
|
||||
}
|
||||
.debug-page .table {
|
||||
font-size: 10px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.debug-page .table th {
|
||||
padding: 3px 5px;
|
||||
background-color: #f8f9fa;
|
||||
font-weight: 600;
|
||||
border: 1px solid #dee2e6;
|
||||
}
|
||||
.debug-page .table td {
|
||||
padding: 2px 5px;
|
||||
border: 1px solid #dee2e6;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.debug-page .badge {
|
||||
font-size: 9px;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
.debug-page .filter-form {
|
||||
background: #f8f9fa;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.debug-page .filter-form .form-control,
|
||||
.debug-page .filter-form .form-select {
|
||||
font-size: 11px;
|
||||
padding: 3px 8px;
|
||||
height: auto;
|
||||
}
|
||||
.debug-page .filter-form label {
|
||||
font-size: 11px;
|
||||
margin-bottom: 2px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.debug-page .btn-sm {
|
||||
font-size: 11px;
|
||||
padding: 3px 10px;
|
||||
}
|
||||
.status-reserved { background-color: #fff3cd; }
|
||||
.status-converted { background-color: #d1ecf1; }
|
||||
.status-released { background-color: #d4edda; }
|
||||
.inactive-row { background-color: #f8d7da; opacity: 0.7; }
|
||||
.section-card {
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 5px;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
background: white;
|
||||
}
|
||||
.summary-box {
|
||||
display: inline-block;
|
||||
padding: 3px 8px;
|
||||
margin-right: 10px;
|
||||
background: #e9ecef;
|
||||
border-radius: 3px;
|
||||
font-size: 10px;
|
||||
}
|
||||
.text-muted-small {
|
||||
color: #6c757d;
|
||||
font-size: 9px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid debug-page mt-3">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>🔧 Отладка Inventory (только для суперюзеров)</h2>
|
||||
|
||||
<!-- Фильтры -->
|
||||
<div class="filter-form">
|
||||
<form method="get" class="row g-2">
|
||||
<div class="col-md-4">
|
||||
<label for="product">Товар:</label>
|
||||
<select name="product" id="product" class="form-select form-select-sm">
|
||||
<option value="">-- Все товары --</option>
|
||||
{% for prod in products %}
|
||||
<option value="{{ prod.id }}" {% if product_id == prod.id|stringformat:"s" %}selected{% endif %}>
|
||||
{{ prod.name }} ({{ prod.sku }})
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label for="order">Номер заказа:</label>
|
||||
<input type="text" name="order" id="order" class="form-control form-control-sm"
|
||||
value="{{ order_number|default:'' }}" placeholder="ORD-100">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label for="warehouse">Склад:</label>
|
||||
<select name="warehouse" id="warehouse" class="form-select form-select-sm">
|
||||
<option value="">-- Все склады --</option>
|
||||
{% for wh in warehouses %}
|
||||
<option value="{{ wh.id }}" {% if warehouse_id == wh.id|stringformat:"s" %}selected{% endif %}>
|
||||
{{ wh.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary btn-sm me-2">Применить</button>
|
||||
<a href="{% url 'inventory:debug_page' %}" class="btn btn-secondary btn-sm">Сбросить</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if selected_product or selected_order or selected_warehouse %}
|
||||
<div class="alert alert-info py-2" style="font-size: 11px;">
|
||||
<strong>Активные фильтры:</strong>
|
||||
{% if selected_product %}Товар: <strong>{{ selected_product.name }}</strong>{% endif %}
|
||||
{% if selected_order %}Заказ: <strong>{{ selected_order.order_number }}</strong>{% endif %}
|
||||
{% if selected_warehouse %}Склад: <strong>{{ selected_warehouse.name }}</strong>{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- ЗАКАЗЫ -->
|
||||
<div class="section-card">
|
||||
<h3>📦 Заказы ({{ orders.count }})</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Номер</th>
|
||||
<th>Статус</th>
|
||||
<th>Возврат</th>
|
||||
<th>Покупатель</th>
|
||||
<th>Товары</th>
|
||||
<th>Сумма</th>
|
||||
<th>Создан</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for order in orders %}
|
||||
<tr>
|
||||
<td>{{ order.id }}</td>
|
||||
<td><strong>{{ order.order_number }}</strong></td>
|
||||
<td>
|
||||
<span class="badge bg-secondary">{{ order.status.name|default:"?" }}</span>
|
||||
</td>
|
||||
<td>
|
||||
{% if order.is_returned %}
|
||||
<span class="badge bg-warning">Возврат</span>
|
||||
{% else %}
|
||||
<span class="text-muted">-</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ order.customer.name|default:"-" }}</td>
|
||||
<td>{{ order.items.count }} шт</td>
|
||||
<td>{{ order.total_price|floatformat:2 }}</td>
|
||||
<td class="text-muted-small">{{ order.created_at|date:"d.m.Y H:i" }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="8" class="text-center text-muted">Нет заказов</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ОСТАТКИ (Stock) -->
|
||||
<div class="section-card">
|
||||
<h3>📊 Остатки Stock ({{ stocks.count }})</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Товар</th>
|
||||
<th>Склад</th>
|
||||
<th>Доступно</th>
|
||||
<th>Зарезервировано</th>
|
||||
<th>Свободно</th>
|
||||
<th>Обновлено</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for stock in stocks %}
|
||||
<tr>
|
||||
<td>{{ stock.id }}</td>
|
||||
<td><strong>{{ stock.product.name }}</strong></td>
|
||||
<td>{{ stock.warehouse.name }}</td>
|
||||
<td><span class="badge bg-primary">{{ stock.quantity_available }}</span></td>
|
||||
<td><span class="badge bg-warning text-dark">{{ stock.quantity_reserved }}</span></td>
|
||||
<td><span class="badge bg-success">{{ stock.quantity_free }}</span></td>
|
||||
<td class="text-muted-small">{{ stock.updated_at|date:"d.m.Y H:i:s" }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="7" class="text-center text-muted">Нет данных Stock</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ПАРТИИ (StockBatch) -->
|
||||
<div class="section-card">
|
||||
<h3>📦 Партии StockBatch ({{ stock_batches.count }})</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Товар</th>
|
||||
<th>Склад</th>
|
||||
<th>Кол-во</th>
|
||||
<th>Себест.</th>
|
||||
<th>Активна</th>
|
||||
<th>Создана</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for batch in stock_batches %}
|
||||
<tr {% if not batch.is_active %}class="inactive-row"{% endif %}>
|
||||
<td>{{ batch.id }}</td>
|
||||
<td><strong>{{ batch.product.name }}</strong></td>
|
||||
<td>{{ batch.warehouse.name }}</td>
|
||||
<td><span class="badge bg-info text-dark">{{ batch.quantity }}</span></td>
|
||||
<td>{{ batch.cost_per_unit|floatformat:2 }}</td>
|
||||
<td>
|
||||
{% if batch.is_active %}
|
||||
<span class="badge bg-success">Да</span>
|
||||
{% else %}
|
||||
<span class="badge bg-danger">Нет</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-muted-small">{{ batch.created_at|date:"d.m.Y H:i" }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="7" class="text-center text-muted">Нет партий</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- РЕЗЕРВЫ (Reservation) -->
|
||||
<div class="section-card">
|
||||
<h3>🔒 Резервы Reservation ({{ reservations.count }})</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Товар</th>
|
||||
<th>Склад</th>
|
||||
<th>Кол-во</th>
|
||||
<th>Статус</th>
|
||||
<th>Заказ</th>
|
||||
<th>Создан</th>
|
||||
<th>Преобразован</th>
|
||||
<th>Освобожден</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for res in reservations %}
|
||||
<tr class="
|
||||
{% if res.status == 'reserved' %}status-reserved
|
||||
{% elif res.status == 'converted_to_sale' %}status-converted
|
||||
{% elif res.status == 'released' %}status-released
|
||||
{% endif %}
|
||||
">
|
||||
<td>{{ res.id }}</td>
|
||||
<td><strong>{{ res.product.name }}</strong></td>
|
||||
<td>{{ res.warehouse.name }}</td>
|
||||
<td><span class="badge bg-dark">{{ res.quantity }}</span></td>
|
||||
<td>
|
||||
{% if res.status == 'reserved' %}
|
||||
<span class="badge bg-warning text-dark">Зарезервирован</span>
|
||||
{% elif res.status == 'converted_to_sale' %}
|
||||
<span class="badge bg-info">В продажу</span>
|
||||
{% elif res.status == 'released' %}
|
||||
<span class="badge bg-success">Освобожден</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">{{ res.status }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if res.order_item.order %}
|
||||
<strong>{{ res.order_item.order.order_number }}</strong>
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-muted-small">{{ res.created_at|date:"d.m.Y H:i:s" }}</td>
|
||||
<td class="text-muted-small">
|
||||
{% if res.converted_at %}{{ res.converted_at|date:"d.m.Y H:i:s" }}{% else %}-{% endif %}
|
||||
</td>
|
||||
<td class="text-muted-small">
|
||||
{% if res.released_at %}{{ res.released_at|date:"d.m.Y H:i:s" }}{% else %}-{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="9" class="text-center text-muted">Нет резервов</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ПРОДАЖИ (Sale) -->
|
||||
<div class="section-card">
|
||||
<h3>💰 Продажи Sale ({{ sales.count }})</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Товар</th>
|
||||
<th>Склад</th>
|
||||
<th>Кол-во</th>
|
||||
<th>Цена продажи</th>
|
||||
<th>Себестоимость</th>
|
||||
<th>Заказ</th>
|
||||
<th>Документ</th>
|
||||
<th>Создана</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for sale in sales %}
|
||||
<tr>
|
||||
<td>{{ sale.id }}</td>
|
||||
<td><strong>{{ sale.product.name }}</strong></td>
|
||||
<td>{{ sale.warehouse.name }}</td>
|
||||
<td><span class="badge bg-primary">{{ sale.quantity }}</span></td>
|
||||
<td>{{ sale.sale_price|floatformat:2 }}</td>
|
||||
<td>{{ sale.cost_price|floatformat:2 }}</td>
|
||||
<td>
|
||||
{% if sale.order %}
|
||||
<strong>{{ sale.order.order_number }}</strong>
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-muted-small">{{ sale.document_number|default:"-" }}</td>
|
||||
<td class="text-muted-small">{{ sale.created_at|date:"d.m.Y H:i:s" }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="9" class="text-center text-muted">Нет продаж</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- СПИСАНИЯ (SaleBatchAllocation) -->
|
||||
<div class="section-card">
|
||||
<h3>📤 Списания SaleBatchAllocation ({{ allocations.count }})</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Sale ID</th>
|
||||
<th>Товар</th>
|
||||
<th>Партия ID</th>
|
||||
<th>Кол-во списано</th>
|
||||
<th>Себест. за ед.</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for alloc in allocations %}
|
||||
<tr>
|
||||
<td>{{ alloc.id }}</td>
|
||||
<td>{{ alloc.sale.id }}</td>
|
||||
<td><strong>{{ alloc.sale.product.name }}</strong></td>
|
||||
<td>{{ alloc.batch.id }}</td>
|
||||
<td><span class="badge bg-danger">{{ alloc.quantity }}</span></td>
|
||||
<td>{{ alloc.cost_per_unit|floatformat:2 }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="6" class="text-center text-muted">Нет списаний</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-secondary py-2 mt-3" style="font-size: 10px;">
|
||||
<strong>Примечание:</strong> Показаны последние 100 записей для каждой таблицы.
|
||||
Используйте фильтры для уточнения результатов.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -28,6 +28,8 @@ from .views import (
|
||||
)
|
||||
# Showcase views
|
||||
from .views.showcase import ShowcaseListView, ShowcaseCreateView, ShowcaseUpdateView, ShowcaseDeleteView, SetDefaultShowcaseView
|
||||
# Debug views
|
||||
from .views.debug_views import debug_inventory_page
|
||||
from . import views
|
||||
|
||||
app_name = 'inventory'
|
||||
@@ -102,4 +104,7 @@ urlpatterns = [
|
||||
path('showcases/<int:pk>/edit/', ShowcaseUpdateView.as_view(), name='showcase-update'),
|
||||
path('showcases/<int:pk>/delete/', ShowcaseDeleteView.as_view(), name='showcase-delete'),
|
||||
path('showcases/<int:pk>/set-default/', SetDefaultShowcaseView.as_view(), name='showcase-set-default'),
|
||||
|
||||
# ==================== DEBUG (SUPERUSER ONLY) ====================
|
||||
path('debug/', debug_inventory_page, name='debug_page'),
|
||||
]
|
||||
|
||||
106
myproject/inventory/views/debug_views.py
Normal file
106
myproject/inventory/views/debug_views.py
Normal file
@@ -0,0 +1,106 @@
|
||||
"""
|
||||
Отладочные 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
|
||||
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('-created_at')
|
||||
sales = Sale.objects.select_related('product', 'warehouse', 'order').order_by('-created_at')
|
||||
allocations = SaleBatchAllocation.objects.select_related(
|
||||
'sale__product', 'batch'
|
||||
).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)
|
||||
orders = orders.filter(items__product_id=product_id).distinct()
|
||||
else:
|
||||
product = None
|
||||
|
||||
if order_number:
|
||||
order = Order.objects.filter(order_number=order_number).first()
|
||||
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)
|
||||
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)
|
||||
else:
|
||||
warehouse = None
|
||||
|
||||
# Ограничиваем количество записей для производительности
|
||||
stock_batches = stock_batches[:100]
|
||||
stocks = stocks[:100]
|
||||
reservations = reservations[:100]
|
||||
sales = sales[:100]
|
||||
allocations = allocations[:100]
|
||||
orders = orders[:50]
|
||||
|
||||
# Списки для фильтров
|
||||
products = Product.objects.filter(is_active=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,
|
||||
'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)
|
||||
Reference in New Issue
Block a user