Fix product reservation system for demo orders

PROBLEM ANALYSIS:
- SQL script created orders bypassing Django ORM
- Django signals (post_save) didn't trigger
- No reservations were created automatically
- Found 51 orders with 102 items and 0 reservations

SOLUTION IMPLEMENTED:

1. Updated create_demo_orders command:
   - Added clear documentation about ORM usage
   - Already uses ORM (.save()) which triggers signals
   - Added informative messages about automatic reservations

2. Created fix_missing_reservations command:
   - Finds OrderItems without reservations
   - Creates missing Reservation records
   - Supports --dry-run mode for safety
   - Handles missing warehouses gracefully

3. Created SQL fix script:
   - Direct SQL approach for existing data
   - Creates reservations for all 102 items
   - Status: 'reserved'
   - Verified: All items now have reservations

4. Added verification scripts:
   - check_orders.py: Shows orders/items/reservations count
   - run_fix_reservations.py: Executes SQL fix

RESULTS:
- ✓ 102 reservations created for existing orders
- ✓ Future orders will use ORM and create reservations automatically
- ✓ System now works correctly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-08 00:04:55 +03:00
parent e3bab2252e
commit fcc7f2263d
5 changed files with 291 additions and 5 deletions

View File

@@ -0,0 +1,59 @@
-- Создание резервов для всех позиций заказов без резервов
SET search_path TO grach;
-- Проверяем наличие активного склада
DO $$
DECLARE
warehouse_id_val INT;
created_count INT := 0;
BEGIN
-- Получаем ID активного склада (если есть)
SELECT id INTO warehouse_id_val
FROM grach.inventory_warehouse
WHERE is_active = true
LIMIT 1;
IF warehouse_id_val IS NULL THEN
RAISE NOTICE 'WARNING: Нет активного склада, резервы будут созданы без склада';
ELSE
RAISE NOTICE 'Используем склад ID: %', warehouse_id_val;
END IF;
-- Создаем резервы для всех позиций без резервов
INSERT INTO grach.inventory_reservation (
order_item_id,
product_id,
warehouse_id,
quantity,
status,
reserved_at,
released_at,
converted_at
)
SELECT
oi.id,
COALESCE(oi.product_id, oi.product_kit_id),
warehouse_id_val,
oi.quantity,
'reserved',
CURRENT_TIMESTAMP,
NULL,
NULL
FROM grach.orders_orderitem oi
LEFT JOIN grach.inventory_reservation r ON r.order_item_id = oi.id
WHERE r.id IS NULL -- Только позиции без резервов
AND (oi.product_id IS NOT NULL OR oi.product_kit_id IS NOT NULL) -- Есть товар
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS created_count = ROW_COUNT;
RAISE NOTICE 'Создано резервов: %', created_count;
END $$;
-- Проверяем результат
SELECT
COUNT(*) as total_items,
COUNT(r.id) as items_with_reservations,
COUNT(*) - COUNT(r.id) as items_without_reservations
FROM grach.orders_orderitem oi
LEFT JOIN grach.inventory_reservation r ON r.order_item_id = oi.id;