Исправлена критическая проблема с резервами при смене статуса заказа
Проблема: - При смене статуса заказа на 'Выполнен' товар списывался со склада - Резервы обновлялись на статус 'converted_to_sale' - НО Stock.quantity_reserved не обновлялся автоматически - В результате резервы продолжали 'держать' товар, хотя он уже продан Решение: 1. Изменен сигнал create_sale_on_order_completion: - Используется .save(update_fields=[...]) вместо .update() - Это вызывает сигнал update_stock_on_reservation_change - Убран костыль с ручным вызовом refresh_from_batches() 2. Оптимизирован сигнал update_stock_on_reservation_change: - Stock обновляется ТОЛЬКО при изменении status или quantity - При изменении других полей (даты и т.д.) Stock НЕ пересчитывается - Предотвращены лишние пересчёты и улучшена производительность 3. Добавлены диагностические инструменты: - check_stock_103.py - для диагностики проблем с Stock - fix_stock_after_sale.py - команда для исправления старых заказов - diagnose_reservation_issue.py - универсальная диагностика Результат: - Элегантное решение без дублирования логики - Stock автоматически обновляется при изменении резервов - Работает везде, не только в заказах - Оптимизировано для производительности
This commit is contained in:
@@ -132,6 +132,8 @@ class TenantCreationIntegrationTest(TransactionTestCase):
|
||||
def test_new_tenant_gets_order_statuses(self):
|
||||
"""
|
||||
Тест: Новый тенант получает системные статусы заказов.
|
||||
|
||||
КРИТИЧЕСКИ ВАЖНО: Должен быть минимум ОДИН позитивный и ОДИН негативный финальный статус.
|
||||
"""
|
||||
# Создаём и активируем тенант
|
||||
registration = TenantRegistration.objects.create(
|
||||
@@ -165,9 +167,48 @@ class TenantCreationIntegrationTest(TransactionTestCase):
|
||||
self.assertIsNotNone(draft_status, "Статус 'draft' не создан")
|
||||
self.assertTrue(draft_status.is_system)
|
||||
|
||||
# КРИТИЧЕСКАЯ ПРОВЕРКА #1: Позитивный финальный статус
|
||||
positive_statuses = OrderStatus.objects.filter(is_positive_end=True)
|
||||
self.assertGreaterEqual(
|
||||
positive_statuses.count(),
|
||||
1,
|
||||
"Должен быть минимум ОДИН позитивный финальный статус (is_positive_end=True)"
|
||||
)
|
||||
|
||||
# Проверяем что есть 'completed' (основной позитивный статус)
|
||||
completed_status = OrderStatus.objects.filter(code='completed').first()
|
||||
self.assertIsNotNone(completed_status, "Статус 'completed' не создан")
|
||||
self.assertTrue(completed_status.is_system)
|
||||
self.assertIsNotNone(
|
||||
completed_status,
|
||||
"Статус 'completed' не создан (основной позитивный статус)"
|
||||
)
|
||||
self.assertTrue(
|
||||
completed_status.is_system,
|
||||
"'completed' должен быть системным"
|
||||
)
|
||||
self.assertTrue(
|
||||
completed_status.is_positive_end,
|
||||
"'completed' должен быть позитивным финальным статусом"
|
||||
)
|
||||
|
||||
# КРИТИЧЕСКАЯ ПРОВЕРКА #2: Негативный финальный статус
|
||||
negative_statuses = OrderStatus.objects.filter(is_negative_end=True)
|
||||
self.assertGreaterEqual(
|
||||
negative_statuses.count(),
|
||||
1,
|
||||
"Должен быть минимум ОДИН негативный финальный статус (is_negative_end=True)"
|
||||
)
|
||||
|
||||
# Проверяем что есть 'cancelled' или другой негативный статус
|
||||
# Проверяем первый найденный негативный статус
|
||||
first_negative_status = negative_statuses.first()
|
||||
self.assertTrue(
|
||||
first_negative_status.is_system,
|
||||
f"Негативный статус '{first_negative_status.code}' должен быть системным"
|
||||
)
|
||||
self.assertTrue(
|
||||
first_negative_status.is_negative_end,
|
||||
f"Статус '{first_negative_status.code}' должен быть негативным финальным"
|
||||
)
|
||||
|
||||
def test_new_tenant_gets_system_customer(self):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user