Добавлен расчёт и отображение доступного количества комплектов

- Добавлен метод calculate_available_quantity() в модель ProductKit для точного расчёта максимального количества комплектов на основе свободных остатков компонентов
- Обновлён метод check_availability() для использования нового расчёта (обратная совместимость)
- Удалён устаревший сервис kit_availability.py

Исправлено отображение остатков комплектов:
- products_list.html: вместо прочерка показывается количество комплектов
- catalog.html: добавлено отображение доступного количества комплектов с цветовой индикацией
- POS terminal.js: в карточке товара показывается конкретное количество вместо общего 'В наличии'

Обновлены представления:
- ProductsListView: аннотирует комплекты атрибутом total_free
- CatalogView: рассчитывает доступное количество для каждого комплекта
- POS get_products(): убран хардкод, используется реальный расчёт по складу
This commit is contained in:
2026-01-06 01:02:28 +03:00
parent 2aba3d2404
commit d44ae0b598
12 changed files with 130 additions and 176 deletions

View File

@@ -902,10 +902,22 @@ function renderProducts() {
stock.style.color = '#28a745'; // Зелёный (достаточно)
}
} else {
// Fallback для старых данных или комплектов
stock.textContent = item.in_stock ? 'В наличии' : 'Под заказ';
if (!item.in_stock) {
stock.style.color = '#dc3545';
// Комплекты: показываем доступное количество
if (item.type === 'kit' && item.free_qty !== undefined) {
const availableKits = parseFloat(item.free_qty) || 0;
if (availableKits > 0) {
stock.textContent = `В наличии: ${Math.floor(availableKits)} компл.`;
stock.style.color = '#28a745'; // Зелёный
} else {
stock.textContent = 'Под заказ';
stock.style.color = '#dc3545'; // Красный
}
} else {
// Fallback для старых данных
stock.textContent = item.in_stock ? 'В наличии' : 'Под заказ';
if (!item.in_stock) {
stock.style.color = '#dc3545';
}
}
}

View File

@@ -854,17 +854,20 @@ def get_items_api(request):
if not image_url:
image_url = None
# Рассчитываем доступное количество комплектов на текущем складе
available_kits = k.calculate_available_quantity(warehouse=current_warehouse)
kits.append({
'id': k.id,
'name': k.name,
'price': str(k.actual_price),
'category_ids': [c.id for c in k.categories.all()],
'in_stock': False, # Комплекты всегда "Под заказ"
'in_stock': available_kits > 0, # Доступен если можно собрать хоть один комплект
'sku': k.sku or '',
'image': image_url,
'type': 'kit',
'free_qty': '0', # Строка для консистентности с товарами
'free_qty_sort': 0 # Комплекты всегда внизу при сортировке
'free_qty': str(available_kits), # Количество комплектов которые можно собрать
'free_qty_sort': float(available_kits) # Для сортировки
})
# Объединяем и сортируем по free_qty_sort DESC