Реализована возможность редактирования состава витринного комплекта с поддержкой отрицательных резервов

- Добавлены методы reserve_product_to_showcase и release_showcase_reservation в ShowcaseManager
- Методы работают с резервами для всех активных экземпляров витринного комплекта
- НЕ блокируют создание резерва при нехватке товара, возвращают информацию о дефиците (overdraft)
- Обновлён API endpoint update_product_kit для корректировки резервов при изменении состава
- Добавлено визуальное предупреждение на фронте о нехватке товара на складе
- В модалке редактирования комплекта добавлены контролы для изменения количества товаров (+/-, поле ввода, удаление)
- Автоматический пересчёт цен при изменении состава
- Очистка корзины POS после успешного создания витринного комплекта
This commit is contained in:
2025-12-14 13:49:13 +03:00
parent 835d6020e2
commit aff25d0317
3 changed files with 292 additions and 21 deletions

View File

@@ -1188,15 +1188,16 @@ def update_product_kit(request, kit_id):
# Получаем витрину для резервов
showcase_reservation = Reservation.objects.filter(
product__in=old_items.keys(),
product_kit=kit,
showcase__isnull=False,
status='reserved'
).select_related('showcase').first()
showcase = showcase_reservation.showcase if showcase_reservation else None
showcase = showcase_reservation.showcase if showcase_reservation else kit.showcase
# Вычисляем разницу в составе
# Вычисляем разницу в составе и собираем информацию о дефиците
all_product_ids = set(old_items.keys()) | set(aggregated_items.keys())
stock_warnings = [] # Список товаров с нехваткой остатков
for product_id in all_product_ids:
old_qty = old_items.get(product_id, Decimal('0'))
@@ -1204,21 +1205,27 @@ def update_product_kit(request, kit_id):
diff = new_qty - old_qty
if diff > 0 and showcase:
# Нужно дозарезервировать
# Нужно дозарезервировать (на каждый экземпляр)
result = ShowcaseManager.reserve_product_to_showcase(
product=products[product_id],
showcase=showcase,
quantity=diff
product_kit=kit,
quantity_per_item=diff,
)
if not result['success']:
raise Exception(f"Недостаточно запасов: {result['message']}")
# Собираем информацию о дефиците
if result.get('overdraft', Decimal('0')) > 0:
stock_warnings.append({
'product_name': products[product_id].name,
'overdraft': str(result['overdraft'])
})
elif diff < 0 and showcase:
# Нужно освободить резерв
# Нужно освободить резерв (на каждый экземпляр)
ShowcaseManager.release_showcase_reservation(
product=products[product_id],
showcase=showcase,
quantity=abs(diff)
product_kit=kit,
quantity_per_item=abs(diff),
)
# Обновляем комплект
@@ -1254,7 +1261,9 @@ def update_product_kit(request, kit_id):
'message': f'Комплект "{kit.name}" обновлён',
'kit_id': kit.id,
'kit_name': kit.name,
'kit_price': str(kit.actual_price)
'kit_price': str(kit.actual_price),
'stock_warning': len(stock_warnings) > 0,
'stock_warnings': stock_warnings
})
except ProductKit.DoesNotExist: