Files
octopus/myproject/fix_order_119.py
Andrey Smakotin 920dbf4273 Добавлена защита от повторного списания + команда исправления дубликатов
Проблема: Сигнал post_save срабатывает несколько раз,
создавая дубликаты Sale для одного заказа.

Решения:
1. Добавлена проверка Sale.objects.filter(order=instance).exists()
   перед созданием продаж (inventory/signals.py:74-75)
2. Создана management команда fix_duplicate_sales для исправления
   существующих дубликатов

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 22:15:33 +03:00

61 lines
2.7 KiB
Python

"""
Скрипт для исправления дубликатов продаж в заказе 119
"""
from django.db import connection, transaction
from orders.models import Order
from inventory.models import Sale, SaleBatchAllocation, Stock, StockBatch
connection.set_schema('buba')
order = Order.objects.get(order_number='119')
sales = Sale.objects.filter(order=order).order_by('date')
print(f"Заказ {order.order_number}: найдено {sales.count()} продаж")
if sales.count() <= 1:
print("Дубликатов нет, всё в порядке")
else:
# Оставляем первую продажу, остальные удаляем
first_sale = sales.first()
duplicate_sales = sales.exclude(id=first_sale.id)
print(f"\nОставляем продажу ID {first_sale.id}")
print(f"Удаляем {duplicate_sales.count()} дубликатов:")
with transaction.atomic():
for sale in duplicate_sales:
print(f" - Продажа ID {sale.id}: {sale.product.name} x {sale.quantity}")
# Получаем SaleBatchAllocation для восстановления товара
allocations = SaleBatchAllocation.objects.filter(sale=sale)
# Восстанавливаем товар в партиях
for alloc in allocations:
batch = alloc.batch
print(f" Восстанавливаем партию ID {batch.id}: +{alloc.quantity}")
batch.quantity += alloc.quantity
batch.is_active = True
batch.save()
# Удаляем продажу (каскадно удалятся и SaleBatchAllocation)
sale.delete()
# Обновляем Stock
for item in order.items.all():
product = item.product or item.product_kit
if product:
warehouse = order.pickup_warehouse or Warehouse.objects.filter(is_active=True).first()
if warehouse:
stock, _ = Stock.objects.get_or_create(product=product, warehouse=warehouse)
stock.refresh_from_batches()
print(f"\nStock обновлен для {product.name}:")
print(f" quantity_available: {stock.quantity_available}")
print(f" quantity_reserved: {stock.quantity_reserved}")
print(f" quantity_free: {stock.quantity_free}")
print("\n✅ Дубликаты удалены, товар восстановлен на складе")
# Проверяем результат
sales_after = Sale.objects.filter(order=order)
print(f"\nПосле исправления: {sales_after.count()} продаж")