Fix cart lock validation and error handling improvements

## 1. Add cart lock validation to sell_from_showcase()
- Prevent selling showcase kits locked in another cashier's cart
- Check cart_lock_expires_at before allowing direct sales
- Return clear error message with lock holder's name and time remaining
- File: inventory/services/showcase_manager.py

## 2. Improve error handling in POS create_temp_kit_to_showcase()
- Add detailed logging for all error types (JSON, validation, generic)
- Provide user-friendly error messages instead of generic 500
- Log full context (kit name, showcase ID, items, user) for debugging
- Categorize errors: stock issues, integrity, locks, not found
- File: pos/views.py

## 3. Fix critical bug in create_temporary_kit()
- Replace non-existent is_active field with status='active'
- Affects 3 locations: kit creation, product lookup, kit duplication
- This was causing 500 errors when creating temporary kits from order edit
- File: products/services/kit_service.py

## 4. Improve error handling in create_temporary_kit_api()
- Add comprehensive logging for order creation endpoint
- Provide specific error messages for common failure scenarios
- Help diagnose issues when creating kits from order editing UI
- File: products/views/api_views.py

These changes complete the Soft Lock system and fix the 500 error issue.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-21 00:24:59 +03:00
parent 33e33ecbac
commit 08a5527ba7
7 changed files with 135 additions and 16 deletions

View File

@@ -4,9 +4,13 @@ API представления для приложения products.
from django.http import JsonResponse
from django.db import models
from django.core.cache import cache
from django.core.exceptions import ValidationError
import logging
from ..models import Product, ProductVariantGroup, ProductKit
logger = logging.getLogger(__name__)
def search_products_and_variants(request):
"""
@@ -629,20 +633,68 @@ def create_temporary_kit_api(request):
})
except ValueError as e:
logger.warning(f'Validation error при создании временного комплекта: {str(e)}')
return JsonResponse({
'success': False,
'error': str(e)
}, status=400)
except json.JSONDecodeError:
except json.JSONDecodeError as e:
logger.error(f'JSON decode error при создании временного комплекта: {str(e)}')
return JsonResponse({
'success': False,
'error': 'Некорректный JSON'
'error': 'Некорректный JSON в запросе'
}, status=400)
except ValidationError as e:
logger.error(f'Django ValidationError при создании временного комплекта: {str(e)}', exc_info=True)
return JsonResponse({
'success': False,
'error': f'Ошибка валидации: {str(e)}'
}, status=400)
except Exception as e:
return JsonResponse({
'success': False,
'error': f'Ошибка при создании комплекта: {str(e)}'
}, status=500)
# Детальное логирование для диагностики 500 ошибок
try:
data = json.loads(request.body)
name = data.get('name', 'N/A')
order_id = data.get('order_id', 'N/A')
components_count = len(data.get('components', []))
except:
name = 'N/A'
order_id = 'N/A'
components_count = 'N/A'
logger.error(
f'Непредвиденная ошибка при создании временного комплекта:\n'
f' Название: {name}\n'
f' Заказ ID: {order_id}\n'
f' Количество компонентов: {components_count}\n'
f' Пользователь: {request.user.username if request.user.is_authenticated else "Anonymous"}\n'
f' Ошибка: {str(e)}',
exc_info=True
)
# Проверяем на типичные ошибки и даём понятные сообщения
error_msg = str(e).lower()
if 'недостаточно' in error_msg or 'insufficient' in error_msg or 'stock' in error_msg:
return JsonResponse({
'success': False,
'error': f'Недостаточно товара на складе. {str(e)}'
}, status=400)
elif 'integrity' in error_msg or 'constraint' in error_msg:
return JsonResponse({
'success': False,
'error': 'Ошибка целостности данных. Проверьте, что все товары существуют.'
}, status=400)
elif 'not found' in error_msg or 'does not exist' in error_msg or 'не найден' in error_msg:
return JsonResponse({
'success': False,
'error': f'Объект не найден: {str(e)}'
}, status=404)
else:
return JsonResponse({
'success': False,
'error': f'Не удалось создать комплект: {str(e)}. Проверьте консоль сервера для деталей.'
}, status=500)
def create_tag_api(request):