- Исправлена логика удаления inline-форм для позиций заказа - Добавлена обработка удаления сохранённых и новых форм - Добавлено поле id и DELETE в OrderItemForm для корректной работы формсета - Добавлена проверка на null для created_by на странице отладки - Расширены права доступа к отладочной странице: теперь доступна owner и manager - Добавлено логирование для отладки процесса обновления заказа
759 lines
39 KiB
HTML
759 lines
39 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; }
|
||
.showcase-available { background-color: #d4edda; }
|
||
.showcase-in-cart { background-color: #fff3cd; }
|
||
.showcase-reserved { background-color: #ffeaa7; }
|
||
.showcase-sold { background-color: #d1ecf1; }
|
||
.showcase-dismantled { background-color: #f8d7da; }
|
||
.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>
|
||
<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-secondary">{{ res.quantity }}</span></td>
|
||
<td>
|
||
{% if res.quantity_base %}
|
||
<span class="badge bg-dark">{{ res.quantity_base }}</span>
|
||
{% else %}
|
||
<span class="text-danger">-</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if res.sales_unit %}
|
||
<small>{{ res.sales_unit.name }}</small>
|
||
{% else %}
|
||
<span class="text-muted">Базовая</span>
|
||
{% endif %}
|
||
</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>
|
||
{% if res.showcase %}
|
||
<span class="badge bg-warning text-dark" title="Витрина: {{ res.showcase.name }}">🌺 {{ res.showcase.name }}</span>
|
||
{% elif res.showcase_item %}
|
||
<span class="badge bg-warning text-dark" title="Витрина: {{ res.showcase_item.showcase.name }}">🌺 {{ res.showcase_item.showcase.name }}</span>
|
||
{% else %}
|
||
<span class="text-muted">-</span>
|
||
{% 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="12" class="text-center text-muted">Нет резервов</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ВИТРИННЫЕ ЭКЗЕМПЛЯРЫ (ShowcaseItem) -->
|
||
<div class="section-card">
|
||
<h3>🌺 Витринные экземпляры ShowcaseItem ({{ showcase_items.count }})</h3>
|
||
<div class="summary-box">
|
||
<strong>Available:</strong> {{ showcase_items_stats.available|default:0 }}
|
||
</div>
|
||
<div class="summary-box">
|
||
<strong>In Cart:</strong> {{ showcase_items_stats.in_cart|default:0 }}
|
||
</div>
|
||
<div class="summary-box">
|
||
<strong>Reserved:</strong> {{ showcase_items_stats.reserved|default:0 }}
|
||
</div>
|
||
<div class="summary-box">
|
||
<strong>Sold:</strong> {{ showcase_items_stats.sold|default:0 }}
|
||
</div>
|
||
<div class="summary-box">
|
||
<strong>Dismantled:</strong> {{ showcase_items_stats.dismantled|default:0 }}
|
||
</div>
|
||
<div class="table-responsive mt-2">
|
||
<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 item in showcase_items %}
|
||
<tr class="
|
||
{% if item.status == 'available' %}showcase-available
|
||
{% elif item.status == 'in_cart' %}showcase-in-cart
|
||
{% elif item.status == 'reserved' %}showcase-reserved
|
||
{% elif item.status == 'sold' %}showcase-sold
|
||
{% elif item.status == 'dismantled' %}showcase-dismantled
|
||
{% endif %}
|
||
">
|
||
<td>{{ item.id }}</td>
|
||
<td>
|
||
<strong>{{ item.product_kit.name }}</strong>
|
||
{% if item.product_kit.is_temporary %}
|
||
<span class="badge bg-warning text-dark" title="Временный комплект из POS">TEMP</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>{{ item.showcase.name }}</td>
|
||
<td>
|
||
{% if item.status == 'available' %}
|
||
<span class="badge bg-success">Доступен</span>
|
||
{% elif item.status == 'in_cart' %}
|
||
<span class="badge bg-warning text-dark">В корзине</span>
|
||
{% elif item.status == 'reserved' %}
|
||
<span class="badge bg-warning" style="background-color: #f39c12 !important;">Зарезервирован</span>
|
||
{% elif item.status == 'sold' %}
|
||
<span class="badge bg-info">Продан</span>
|
||
{% elif item.status == 'dismantled' %}
|
||
<span class="badge bg-danger">Разобран</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary">{{ item.get_status_display }}</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if item.sold_order_item %}
|
||
<strong>{{ item.sold_order_item.order.order_number }}</strong>
|
||
<small class="text-muted">(#{{ item.sold_order_item.id }})</small>
|
||
{% else %}
|
||
<span class="text-muted">-</span>
|
||
{% endif %}
|
||
</td>
|
||
<td class="text-muted-small">
|
||
{% if item.sold_at %}{{ item.sold_at|date:"d.m.Y H:i:s" }}{% else %}-{% endif %}
|
||
</td>
|
||
<td class="text-muted-small">{{ item.created_at|date:"d.m.Y H:i" }}</td>
|
||
<td class="text-muted-small">{{ item.updated_at|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>
|
||
<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>
|
||
|
||
<!-- СПИСАНИЯ WriteOff (одиночные записи) -->
|
||
<div class="section-card">
|
||
<h3>🗑️ Списания WriteOff ({{ writeoffs.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>Партия ID</th>
|
||
<th>Кол-во</th>
|
||
<th>Причина</th>
|
||
<th>Дата</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for wo in writeoffs %}
|
||
<tr>
|
||
<td>{{ wo.id }}</td>
|
||
<td><strong>{{ wo.batch.product.name }}</strong></td>
|
||
<td>{{ wo.batch.warehouse.name }}</td>
|
||
<td>{{ wo.batch.id }}</td>
|
||
<td><span class="badge bg-danger">{{ wo.quantity }}</span></td>
|
||
<td>{{ wo.reason|default:"-" }}</td>
|
||
<td class="text-muted-small">{{ wo.date|date:"d.m.Y H:i:s" }}</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="7" class="text-center text-muted">Нет списаний WriteOff</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ДОКУМЕНТЫ СПИСАНИЯ (WriteOffDocument) -->
|
||
<div class="section-card">
|
||
<h3>📄 Документы списания WriteOffDocument ({{ writeoff_documents.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>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for doc in writeoff_documents %}
|
||
<tr>
|
||
<td>{{ doc.id }}</td>
|
||
<td><strong>{{ doc.document_number|default:"-" }}</strong></td>
|
||
<td>{{ doc.warehouse.name }}</td>
|
||
<td>
|
||
{% if doc.status == 'draft' %}
|
||
<span class="badge bg-warning text-dark">Черновик</span>
|
||
{% elif doc.status == 'confirmed' %}
|
||
<span class="badge bg-success">Проведен</span>
|
||
{% elif doc.status == 'cancelled' %}
|
||
<span class="badge bg-danger">Отменен</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary">{{ doc.status }}</span>
|
||
{% endif %}
|
||
</td>
|
||
<td class="text-muted-small">{{ doc.date|date:"d.m.Y" }}</td>
|
||
<td>
|
||
{% if doc.inventory %}
|
||
<span class="badge bg-info">INV-{{ doc.inventory.id }}</span>
|
||
{% else %}
|
||
<span class="text-muted">-</span>
|
||
{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="6" class="text-center text-muted">Нет документов списания</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- СТРОКИ ДОКУМЕНТОВ СПИСАНИЯ (WriteOffDocumentItem) -->
|
||
<div class="section-card">
|
||
<h3>📋 Строки документов списания WriteOffDocumentItem ({{ writeoff_document_items.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>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for item in writeoff_document_items %}
|
||
<tr>
|
||
<td>{{ item.id }}</td>
|
||
<td><strong>{{ item.document.document_number|default:"-" }}</strong></td>
|
||
<td><strong>{{ item.product.name }}</strong></td>
|
||
<td>{{ item.document.warehouse.name }}</td>
|
||
<td><span class="badge bg-danger">{{ item.quantity }}</span></td>
|
||
<td>{{ item.reason|default:"-" }}</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="6" class="text-center text-muted">Нет строк документов списания</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ДОКУМЕНТЫ ПОСТУПЛЕНИЯ (IncomingDocument) -->
|
||
<div class="section-card">
|
||
<h3>📥 Документы поступления IncomingDocument ({{ incoming_documents.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 doc in incoming_documents %}
|
||
<tr>
|
||
<td>{{ doc.id }}</td>
|
||
<td><strong>{{ doc.document_number }}</strong></td>
|
||
<td>{{ doc.warehouse.name }}</td>
|
||
<td>
|
||
{% if doc.status == 'draft' %}
|
||
<span class="badge bg-warning text-dark">Черновик</span>
|
||
{% elif doc.status == 'confirmed' %}
|
||
<span class="badge bg-success">Проведён</span>
|
||
{% elif doc.status == 'cancelled' %}
|
||
<span class="badge bg-danger">Отменён</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary">{{ doc.status }}</span>
|
||
{% endif %}
|
||
</td>
|
||
<td><span class="badge bg-info">{{ doc.get_receipt_type_display }}</span></td>
|
||
<td class="text-muted-small">{{ doc.date|date:"d.m.Y" }}</td>
|
||
<td>{{ doc.supplier_name|default:"-" }}</td>
|
||
<td class="text-muted-small">
|
||
{% if doc.created_by %}
|
||
{{ doc.created_by.name|default:doc.created_by.email }}
|
||
{% else %}
|
||
-
|
||
{% endif %}
|
||
</td>
|
||
<td class="text-muted-small">
|
||
{% if doc.confirmed_by %}
|
||
{{ doc.confirmed_by.name|default:doc.confirmed_by.email }} ({{ doc.confirmed_at|date:"d.m H:i" }})
|
||
{% else %}
|
||
-
|
||
{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="9" class="text-center text-muted">Нет документов поступления</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- СТРОКИ ДОКУМЕНТОВ ПОСТУПЛЕНИЯ (IncomingDocumentItem) -->
|
||
<div class="section-card">
|
||
<h3>📋 Строки документов поступления IncomingDocumentItem ({{ incoming_document_items.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 item in incoming_document_items %}
|
||
<tr>
|
||
<td>{{ item.id }}</td>
|
||
<td><strong>{{ item.document.document_number }}</strong></td>
|
||
<td><strong>{{ item.product.name }}</strong> ({{ item.product.sku }})</td>
|
||
<td>{{ item.document.warehouse.name }}</td>
|
||
<td><span class="badge bg-success">{{ item.quantity }}</span></td>
|
||
<td>{{ item.cost_price }} ₽</td>
|
||
<td><strong>{{ item.total_cost }} ₽</strong></td>
|
||
<td class="text-muted-small">{{ item.notes|default:"-" }}</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="8" 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 %}
|