Рефакторинг: убрано дублирование валидации витринных комплектов
Проблема: Валидация showcase_items выполнялась в двух местах: 1. В pos/views.py - проверка status='in_cart' БЕЗ блокировки БД 2. В showcase_manager.py - перезагрузка с select_for_update() и повторная проверка Это создавало: - Дублирование кода и логики - Возможность race condition между двумя запросами - Избыточные обращения к БД - Мертвый код (неработающие logger.info) Решение (best practices): 1. Views только загружают объекты по ID без фильтров по статусу 2. ВСЯ валидация и бизнес-логика в одном месте - ShowcaseManager.sell_showcase_items 3. select_for_update() гарантирует актуальность данных и блокировку на уровне БД 4. Удален мертвый код (logger.info которые не выполнялись) 5. Убрано избыточное логирование ошибок валидации Результат: - Единое место ответственности (Single Responsibility) - Нет дублирования - Атомарная транзакция с блокировкой - Чистый, понятный код без костылей
This commit is contained in:
@@ -1468,26 +1468,10 @@ def pos_checkout(request):
|
||||
|
||||
# Продаём экземпляры через ShowcaseManager
|
||||
if showcase_item_ids:
|
||||
# Логируем для отладки
|
||||
logger.info(f'POS Checkout: попытка продать showcase_item_ids={showcase_item_ids}')
|
||||
|
||||
# Проверяем что все экземпляры заблокированы на текущего пользователя
|
||||
# ShowcaseManager.sell_showcase_items выполнит всю валидацию с блокировкой БД
|
||||
showcase_items = list(ShowcaseItem.objects.filter(
|
||||
id__in=showcase_item_ids,
|
||||
status='in_cart',
|
||||
locked_by_user=request.user
|
||||
id__in=showcase_item_ids
|
||||
))
|
||||
|
||||
logger.info(f'POS Checkout: найдено {len(showcase_items)} заблокированных экземпляров из {len(showcase_item_ids)} запрошенных')
|
||||
|
||||
if len(showcase_items) != len(showcase_item_ids):
|
||||
# Не все экземпляры доступны
|
||||
missing_ids = set(showcase_item_ids) - set(item.id for item in showcase_items)
|
||||
logger.warning(f'POS Checkout: недоступные showcase_item_ids={missing_ids}')
|
||||
raise ValidationError(
|
||||
f'Некоторые экземпляры букета уже не заблокированы на вас. '
|
||||
f'Обновите страницу и попробуйте снова.'
|
||||
)
|
||||
|
||||
if showcase_items:
|
||||
result = ShowcaseManager.sell_showcase_items(showcase_items, order_item)
|
||||
@@ -1532,10 +1516,8 @@ def pos_checkout(request):
|
||||
})
|
||||
|
||||
except (Customer.DoesNotExist, Warehouse.DoesNotExist, Product.DoesNotExist, ProductKit.DoesNotExist) as e:
|
||||
logger.error(f'POS Checkout: объект не найден: {str(e)}')
|
||||
return JsonResponse({'success': False, 'error': 'Объект не найден'}, status=404)
|
||||
except ValidationError as e:
|
||||
logger.error(f'POS Checkout: ошибка валидации: {str(e)}', exc_info=True)
|
||||
return JsonResponse({'success': False, 'error': str(e)}, status=400)
|
||||
except json.JSONDecodeError:
|
||||
return JsonResponse({'success': False, 'error': 'Неверный формат JSON'}, status=400)
|
||||
|
||||
Reference in New Issue
Block a user