From d8fec8b893d9311d3c7f844cfdab0a97a1ca9539 Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Sat, 8 Nov 2025 11:08:23 +0300 Subject: [PATCH] Add utility scripts for stock reservation management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add check_stock.py: script to view Stock records with reservations - Add refresh_stock_reservations.py: standalone script to recalculate quantity_reserved for all Stock records - Both scripts work with 'grach' tenant schema 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- myproject/check_stock.py | 34 +++++++++++++++++++++ myproject/refresh_stock_reservations.py | 39 +++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 myproject/check_stock.py create mode 100644 myproject/refresh_stock_reservations.py diff --git a/myproject/check_stock.py b/myproject/check_stock.py new file mode 100644 index 0000000..0797d5e --- /dev/null +++ b/myproject/check_stock.py @@ -0,0 +1,34 @@ +""" +Проверка Stock с quantity_reserved +""" +import os +import django + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') +django.setup() + +from django.db import connection + +with connection.cursor() as cursor: + cursor.execute("SET search_path TO grach") + + # Проверяем Stock с резервами + print("Stock с резервами:\n") + cursor.execute(""" + SELECT + s.id, + p.name as product_name, + s.quantity_available, + s.quantity_reserved, + (s.quantity_available - s.quantity_reserved) as free_quantity + FROM grach.inventory_stock s + JOIN grach.products_product p ON p.id = s.product_id + ORDER BY s.quantity_reserved DESC + """) + + print(f"{'ID':<5} {'Товар':<30} {'Всего':<10} {'Резерв':<10} {'Свободно':<10}") + print("=" * 75) + + for row in cursor.fetchall(): + stock_id, product_name, qty_available, qty_reserved, free_qty = row + print(f"{stock_id:<5} {product_name:<30} {qty_available:<10} {qty_reserved:<10} {free_qty:<10}") diff --git a/myproject/refresh_stock_reservations.py b/myproject/refresh_stock_reservations.py new file mode 100644 index 0000000..b70d437 --- /dev/null +++ b/myproject/refresh_stock_reservations.py @@ -0,0 +1,39 @@ +""" +Скрипт для пересчета quantity_reserved для всех Stock записей +Нужен после добавления сигналов для Reservation +""" +import os +import django + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') +django.setup() + +from django.db import connection +from inventory.models import Stock + +# Устанавливаем схему для работы с tenant +with connection.cursor() as cursor: + cursor.execute('SET search_path TO grach') + +print('[НАЧАЛО] Обновление quantity_reserved для всех Stock записей...') + +# Получаем все Stock записи +stocks = Stock.objects.all() +total_count = stocks.count() + +print(f'[INFO] Найдено Stock записей: {total_count}') + +updated_count = 0 +for stock in stocks: + try: + # Вызываем refresh_from_batches() который пересчитывает quantity_reserved + stock.refresh_from_batches() + updated_count += 1 + + if stock.quantity_reserved > 0: + print(f' [OK] Stock #{stock.id}: {stock.product.name} - зарезервировано: {stock.quantity_reserved}') + except Exception as e: + print(f' [ОШИБКА] Stock #{stock.id}: {str(e)}') + +print(f'\n[ЗАВЕРШЕНО] Обновлено записей: {updated_count} из {total_count}') +print('[OK] Все резервы пересчитаны!')