Добавлено: - Столбец 'Статус оплаты' с цветовой индикацией: * Зеленый бейдж - Оплачен полностью * Желтый бейдж - Частично оплачен * Красный бейдж - Не оплачен - Столбец 'Оплачено' показывает: amount_paid / total_amount * Например: 500.00 / 1000.00 (оплачено 500 из 1000) Использованные поля: - payment_status (paid/partial/unpaid) - amount_paid (сумма внесенная клиентом) - total_amount (итоговая сумма заказа)
428 lines
20 KiB
HTML
428 lines
20 KiB
HTML
{% 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>
|
||
<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_amount|floatformat:2 }}</td>
|
||
<td>
|
||
{% if order.payment_status == 'paid' %}
|
||
<span class="badge bg-success">Оплачен</span>
|
||
{% elif order.payment_status == 'partial' %}
|
||
<span class="badge bg-warning text-dark">Частично</span>
|
||
{% else %}
|
||
<span class="badge bg-danger">Не оплачен</span>
|
||
{% endif %}
|
||
</td>
|
||
<td><strong>{{ order.amount_paid|floatformat:2 }}</strong> / {{ order.total_amount|floatformat:2 }}</td>
|
||
<td class="text-muted-small">{{ order.created_at|date:"d.m.Y H:i" }}</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="10" 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_price|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.reserved_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>
|
||
</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>
|
||
{% 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.date|date:"d.m.Y H:i:s" }}</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="8" 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_price|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 %}
|