Улучшения инвентаризации: автоматическое проведение документов, оптимизация запросов и улучшения UI
- Автоматическое проведение документов списания и оприходования после завершения инвентаризации - Оптимизация SQL-запросов: устранение N+1, bulk-операции для Stock, агрегация для StockBatch и Reservation - Изменение формулы расчета разницы: (quantity_fact + quantity_reserved) - quantity_available - Переименование поля 'По факту' в 'Подсчитано (факт, свободные)' - Добавлены столбцы 'В резервах' и 'Всего на складе' в таблицу инвентаризации - Перемещение столбца 'В системе (свободно)' после 'В резервах' с визуальным выделением - Центральное выравнивание значений в столбцах таблицы - Автоматическое выделение текста при фокусе на поле ввода количества - Исправление форматирования разницы (убраны лишние нули) - Изменение статуса 'Не обработана' на 'Не проведено' - Добавление номера документа для инвентаризаций (INV-XXXXXX) - Отображение всех типов списаний в debug-странице (WriteOff, WriteOffDocument, WriteOffDocumentItem) - Улучшение отображения документов в детальном просмотре инвентаризации с возможностью перехода к ним
This commit is contained in:
@@ -384,9 +384,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- СПИСАНИЯ (SaleBatchAllocation) -->
|
||||
<!-- СПИСАНИЯ ИЗ ПРОДАЖ (SaleBatchAllocation) -->
|
||||
<div class="section-card">
|
||||
<h3>📤 Списания SaleBatchAllocation ({{ allocations.count }})</h3>
|
||||
<h3>📤 Списания из продаж SaleBatchAllocation ({{ allocations.count }})</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered table-hover">
|
||||
<thead>
|
||||
@@ -410,7 +410,124 @@
|
||||
<td>{{ alloc.cost_price|floatformat:2 }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="6" class="text-center text-muted">Нет списаний</td></tr>
|
||||
<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:"#" }}{{ item.document.id }}</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>
|
||||
|
||||
Reference in New Issue
Block a user