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

@@ -7,13 +7,17 @@ from django.db import transaction
from django.db.models import Prefetch, OuterRef, Subquery, DecimalField
from django.db.models.functions import Coalesce
from django.utils import timezone
from django.core.exceptions import ValidationError
from decimal import Decimal, InvalidOperation
import json
import logging
from products.models import Product, ProductCategory, ProductKit, KitItem
from inventory.models import Showcase, Reservation, Warehouse, Stock
from inventory.services import ShowcaseManager
logger = logging.getLogger(__name__)
def get_pos_warehouse(request):
"""
@@ -939,16 +943,59 @@ def create_temp_kit_to_showcase(request):
'reservations_count': len(result['reservations'])
})
except json.JSONDecodeError:
except json.JSONDecodeError as e:
logger.error(f'JSON decode error при создании временного комплекта: {str(e)}')
return JsonResponse({
'success': False,
'error': 'Неверный формат данных'
'error': 'Неверный формат данных корзины'
}, status=400)
except Showcase.DoesNotExist:
logger.warning(f'Попытка создать комплект на несуществующей витрине (ID: {request.POST.get("showcase_id")})')
return JsonResponse({
'success': False,
'error': 'Выбранная витрина не найдена'
}, status=404)
except ValidationError as e:
logger.error(f'Validation error при создании временного комплекта: {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 ошибок
logger.error(
f'Непредвиденная ошибка при создании временного комплекта:\n'
f' Название: {request.POST.get("kit_name")}\n'
f' Витрина ID: {request.POST.get("showcase_id")}\n'
f' Товары: {request.POST.get("items")}\n'
f' Пользователь: {request.user.username}\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 'lock' in error_msg or 'blocked' in error_msg or 'заблокирован' in error_msg:
return JsonResponse({
'success': False,
'error': f'Конфликт блокировки: {str(e)}'
}, status=409)
else:
return JsonResponse({
'success': False,
'error': f'Не удалось создать комплект: {str(e)}. Проверьте консоль сервера для деталей.'
}, status=500)
@login_required