""" Signals для приложения products. Логирует изменения себестоимости товара через CostPriceHistory. FIX: SKU counter bug - инкрементирует счётчик после успешного создания Product. """ from django.db.models.signals import post_save from django.dispatch import receiver from django.db import models import re from .models import Product, CostPriceHistory, SKUCounter @receiver(post_save, sender=Product) def log_cost_price_changes(sender, instance, created, **kwargs): """ Логирует изменения себестоимости товара. Срабатывает при создании или обновлении товара. Создает запись в CostPriceHistory если себестоимость изменилась. """ if created: # При создании товара себестоимость обычно 0, логируем только если не 0 if instance.cost_price != 0: CostPriceHistory.objects.create( product=instance, old_cost_price=0, new_cost_price=instance.cost_price, reason='system', notes='Начальная себестоимость при создании товара' ) return # Получаем предыдущее значение себестоимости try: previous = Product.objects.get(pk=instance.pk) old_cost_price = previous.cost_price except Product.DoesNotExist: # Товар был удален, не логируем return # Если себестоимость изменилась, логируем if old_cost_price != instance.cost_price: CostPriceHistory.objects.create( product=instance, old_cost_price=old_cost_price, new_cost_price=instance.cost_price, reason='recalculation', notes='Себестоимость пересчитана на основе партий товара' ) @receiver(post_save, sender=Product) def increment_sku_counter_after_save(sender, instance, created, **kwargs): """ FIX: SKU counter bug - increment only after successful save Инкрементирует счётчик SKU ПОСЛЕ успешного создания товара с автогенерированным артикулом. Это предотвращает пропуски номеров при ошибках сохранения (например, валидация cost_price). Счётчик инкрементируется только если: - Товар только что создан (created=True) - SKU соответствует автогенерированному формату (PROD-XXXXXX) """ if not created: return # Проверяем что SKU был автогенерирован (формат PROD-XXXXXX) if instance.sku and re.match(r'^PROD-\d{6}$', instance.sku): # Инкрементируем счётчик product SKUCounter.increment_counter('product')