Добавлена защита от повторного списания + команда исправления дубликатов
Проблема: Сигнал 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>
This commit is contained in:
60
myproject/fix_order_119.py
Normal file
60
myproject/fix_order_119.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""
|
||||
Скрипт для исправления дубликатов продаж в заказе 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()} продаж")
|
||||
Reference in New Issue
Block a user