Files
octopus/fix_product_in_stock.py
Andrey Smakotin 83412f3447 fix: Исправить логику обновления Product.in_stock из Stock остатков
Проблема: товары отображались как "нет в наличии" несмотря на наличие остатков на складе.

Причина: сигналы на обновление Product.in_stock срабатывают только при изменении Stock через Django ORM.
Если Stock была создана напрямую (импорт, миграция и т.д.), сигналы не срабатывали.

Решение:

1. Исправлена логика сигналов (inventory/signals.py):
   - Добавлен импорт post_delete для правильной обработки удаления Stock
   - Изменён pre_delete на post_delete для более надёжной проверки остатков
   - Сигналы теперь правильно срабатывают при любом изменении Stock

2. Добавлена миграция (products/migrations/0004_fix_product_in_stock.py):
   - Пересчитывает in_stock для всех существующих товаров на основе Stock.quantity_available
   - Товар считается в наличии если есть хотя бы один Stock с quantity_available > 0
   - Обратима и безопасна (может быть отменена)

3. Добавлена команда управления (products/management/commands/update_product_in_stock.py):
   - Позволяет вручную пересчитать in_stock если потребуется
   - Поддерживает параметр --verbose для подробного логирования
   - Может быть запущена по расписанию или вручную

После этого исправления:
- Все товары с остатками на складе автоматически обновляют статус in_stock
- Сигналы срабатывают при любом изменении Stock (создание, обновление, удаление)
- Отображение наличия товаров в UI будет корректным

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 23:42:20 +03:00

81 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python
"""
Скрипт для исправления статуса Product.in_stock на основе текущих остатков в Stock.
Пересчитывает in_stock для всех товаров, которые имеют остатки на складе.
"""
import os
import sys
import django
# Добавляем путь к myproject
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'myproject'))
os.chdir(os.path.join(os.path.dirname(__file__), 'myproject'))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
django.setup()
from decimal import Decimal
from products.models import Product
from inventory.models import Stock
def fix_product_in_stock():
"""
Исправить статус in_stock для всех товаров.
Логика:
- Если для товара есть Stock с quantity_available > 0 → in_stock = True
- Если нет таких Stock или все пусты → in_stock = False
"""
print("\n" + "="*80)
print("ИСПРАВЛЕНИЕ СТАТУСА НАЛИЧИЯ ТОВАРОВ")
print("="*80 + "\n")
# Получаем все товары
all_products = Product.all_objects.all()
total = all_products.count()
updated = 0
no_stock = 0
print(f"Всего товаров в системе: {total}\n")
for product in all_products:
# Проверяем есть ли остаток
has_stock = Stock.objects.filter(
product=product,
quantity_available__gt=0
).exists()
# Обновляем in_stock если статус изменился
if product.in_stock != has_stock:
Product.all_objects.filter(id=product.id).update(in_stock=has_stock)
status = "ДОБАВЛЕН В НАЛИЧИЕ" if has_stock else "УБРАН ИЗ НАЛИЧИЯ"
print(f"{product.name:50}{status}")
updated += 1
else:
if not has_stock:
no_stock += 1
print("\n" + "="*80)
print(f"РЕЗУЛЬТАТЫ:")
print(f" - Всего товаров: {total}")
print(f" - Обновлено: {updated}")
print(f" - Товаров без наличия: {no_stock}")
print("="*80 + "\n")
# Проверка
print("ПРОВЕРКА:")
in_stock_count = Product.all_objects.filter(in_stock=True).count()
out_of_stock_count = Product.all_objects.filter(in_stock=False).count()
print(f" - Товаров в наличии: {in_stock_count}")
print(f" - Товаров не в наличии: {out_of_stock_count}")
print("="*80 + "\n")
if __name__ == '__main__':
try:
fix_product_in_stock()
except Exception as e:
print(f"\nОШИБКА: {e}")
import traceback
traceback.print_exc()