conventional-commit
feat(inventory): introduce stock deficit notifications and base quantity tracking - Added `quantity_base` field to reservation model for precise inventory calculations - Implemented non-blocking stock deficit warnings during kit creation process - Enhanced API responses with warning details for frontend display - Updated terminal interface to show formatted stock shortage alerts BREAKING CHANGE: API response structure now includes `warnings` array instead of previous stock warning format
This commit is contained in:
@@ -47,6 +47,7 @@ class ShowcaseManager:
|
||||
'success': False,
|
||||
'showcase_items': [],
|
||||
'reservations': [],
|
||||
'warnings': None,
|
||||
'message': f'Витрина "{showcase.name}" не активна'
|
||||
}
|
||||
|
||||
@@ -63,9 +64,23 @@ class ShowcaseManager:
|
||||
'success': False,
|
||||
'showcase_items': [],
|
||||
'reservations': [],
|
||||
'warnings': None,
|
||||
'message': f'Комплект "{product_kit.name}" не содержит компонентов'
|
||||
}
|
||||
|
||||
# Проверяем дефицит компонентов (предупреждение, не блокировка)
|
||||
warnings = []
|
||||
for kit_item in kit_items:
|
||||
product = kit_item.product
|
||||
if not product:
|
||||
continue
|
||||
qty_needed = (kit_item.quantity or Decimal('1')) * quantity
|
||||
stock = Stock.objects.filter(product=product, warehouse=warehouse).first()
|
||||
free_qty = stock.quantity_free if stock else Decimal('0')
|
||||
if free_qty < qty_needed:
|
||||
deficit = qty_needed - free_qty
|
||||
warnings.append(f"{product.name}: не хватает {deficit} шт.")
|
||||
|
||||
# Создаём N экземпляров
|
||||
for _ in range(quantity):
|
||||
# 1. Создаём ShowcaseItem
|
||||
@@ -96,6 +111,7 @@ class ShowcaseManager:
|
||||
product_kit=product_kit,
|
||||
showcase_item=showcase_item, # Связь с экземпляром!
|
||||
quantity=kit_item.quantity,
|
||||
quantity_base=kit_item.quantity, # Для корректного учёта в Stock
|
||||
status='reserved'
|
||||
)
|
||||
all_reservations.append(reservation)
|
||||
@@ -113,6 +129,7 @@ class ShowcaseManager:
|
||||
'success': True,
|
||||
'showcase_items': showcase_items,
|
||||
'reservations': all_reservations,
|
||||
'warnings': warnings if warnings else None,
|
||||
'message': f'Создано {quantity} экз. комплекта "{product_kit.name}" на витрине "{showcase.name}"'
|
||||
}
|
||||
|
||||
@@ -121,6 +138,7 @@ class ShowcaseManager:
|
||||
'success': False,
|
||||
'showcase_items': [],
|
||||
'reservations': [],
|
||||
'warnings': None,
|
||||
'message': f'Ошибка резервирования: {str(e)}'
|
||||
}
|
||||
|
||||
@@ -410,7 +428,7 @@ class ShowcaseManager:
|
||||
product_kit=product_kit,
|
||||
showcase_item=showcase_item,
|
||||
status='reserved',
|
||||
defaults={'quantity': quantity_per_item},
|
||||
defaults={'quantity': quantity_per_item, 'quantity_base': quantity_per_item},
|
||||
)
|
||||
if not created:
|
||||
reservation.quantity = (reservation.quantity or Decimal('0')) + quantity_per_item
|
||||
|
||||
@@ -2065,10 +2065,10 @@ document.getElementById('confirmCreateTempKit').onclick = async () => {
|
||||
Зарезервировано компонентов: ${data.reservations_count}`;
|
||||
|
||||
// Если есть предупреждение о нехватке товара - добавляем его
|
||||
if (data.stock_warning && data.stock_warnings && data.stock_warnings.length > 0) {
|
||||
if (data.warnings && data.warnings.length > 0) {
|
||||
successMessage += '\n\n⚠️ ВНИМАНИЕ: Нехватка товара на складе!\n';
|
||||
data.stock_warnings.forEach(warning => {
|
||||
successMessage += `\n• ${warning.product_name}: не хватает ${warning.overdraft} ед.`;
|
||||
data.warnings.forEach(warning => {
|
||||
successMessage += `\n• ${warning}`;
|
||||
});
|
||||
successMessage += '\n\nПроверьте остатки и пополните склад.';
|
||||
}
|
||||
|
||||
@@ -1096,7 +1096,8 @@ def create_temp_kit_to_showcase(request):
|
||||
'kit_price': str(kit.actual_price),
|
||||
'reservations_count': len(result['reservations']),
|
||||
'showcase_item_ids': showcase_item_ids,
|
||||
'available_count': created_count
|
||||
'available_count': created_count,
|
||||
'warnings': result.get('warnings')
|
||||
})
|
||||
|
||||
except json.JSONDecodeError as e:
|
||||
|
||||
Reference in New Issue
Block a user