from django.db.models.signals import post_save, pre_save from django.dispatch import receiver from core.apps.evaluation.choices.auto import AutoEvaluationStatus from core.apps.evaluation.choices.history import EvaluationEventType from core.apps.evaluation.choices.quick import QuickEvaluationStatus from core.apps.evaluation.models import ( AutoEvaluationModel, QuickEvaluationModel, ValuationDocumentModel, ValuationModel, ) from core.apps.evaluation.services.history import EvaluationHistoryService # ───────────────────────────────────────────────────────────────────────────── # AutoEvaluation — order_created va status_changed # ───────────────────────────────────────────────────────────────────────────── @receiver(pre_save, sender=AutoEvaluationModel) def auto_eval_pre_save(sender, instance, **kwargs): """Status o'zgarishini kuzatish uchun eski qiymatni saqlaydi.""" if instance.pk: try: old = AutoEvaluationModel.objects.get(pk=instance.pk) instance._old_status = old.status except AutoEvaluationModel.DoesNotExist: instance._old_status = None else: instance._old_status = None @receiver(post_save, sender=AutoEvaluationModel) def auto_eval_post_save(sender, instance, created, **kwargs): if created: actor = None if instance.valuation_id: try: actor = instance.valuation.created_by except Exception: pass EvaluationHistoryService.log_auto( auto_evaluation=instance, event_type=EvaluationEventType.ORDER_CREATED, actor=actor, ) else: old_status = getattr(instance, "_old_status", None) if old_status is not None and old_status != instance.status: status_labels = dict(AutoEvaluationStatus.choices) EvaluationHistoryService.log_auto( auto_evaluation=instance, event_type=EvaluationEventType.STATUS_CHANGED, meta={ "from_status": old_status, "from_status_display": status_labels.get(old_status, old_status), "to_status": instance.status, "to_status_display": status_labels.get(instance.status, instance.status), }, ) # ───────────────────────────────────────────────────────────────────────────── # Valuation — evaluator_assigned (assigned_to o'zgarganda) # ───────────────────────────────────────────────────────────────────────────── @receiver(pre_save, sender=ValuationModel) def valuation_pre_save(sender, instance, **kwargs): """assigned_to o'zgarishini kuzatish uchun eski qiymatni saqlaydi.""" if instance.pk: try: old = ValuationModel.objects.get(pk=instance.pk) instance._old_assigned_to_id = old.assigned_to_id except ValuationModel.DoesNotExist: instance._old_assigned_to_id = None else: instance._old_assigned_to_id = None @receiver(post_save, sender=ValuationModel) def valuation_post_save(sender, instance, created, **kwargs): if created: return old_assigned_id = getattr(instance, "_old_assigned_to_id", None) if instance.assigned_to_id and old_assigned_id != instance.assigned_to_id: try: auto_eval = instance.auto_detail except AutoEvaluationModel.DoesNotExist: return evaluator = instance.assigned_to evaluator_name = "" if evaluator: evaluator_name = evaluator.get_full_name().strip() or str(evaluator.phone) EvaluationHistoryService.log_auto( auto_evaluation=auto_eval, event_type=EvaluationEventType.EVALUATOR_ASSIGNED, meta={ "evaluator_id": instance.assigned_to_id, "evaluator_name": evaluator_name, }, ) # ───────────────────────────────────────────────────────────────────────────── # ValuationDocument — document_uploaded # ───────────────────────────────────────────────────────────────────────────── @receiver(post_save, sender=ValuationDocumentModel) def document_post_save(sender, instance, created, **kwargs): if not created: return try: auto_eval = instance.valuation.auto_detail except (AttributeError, AutoEvaluationModel.DoesNotExist): return file_name = "" if instance.file: file_name = instance.file.name.split("/")[-1] EvaluationHistoryService.log_auto( auto_evaluation=auto_eval, event_type=EvaluationEventType.DOCUMENT_UPLOADED, actor=instance.uploaded_by, meta={ "document_type": instance.document_type, "document_type_display": instance.get_document_type_display(), "file_name": file_name, "title": instance.title or "", }, ) # ───────────────────────────────────────────────────────────────────────────── # Payment — payment_made (status COMPLETED bo'lganda) # ───────────────────────────────────────────────────────────────────────────── @receiver(pre_save, sender="payment.PaymentModel") def payment_pre_save(sender, instance, **kwargs): if instance.pk: try: old = sender.objects.get(pk=instance.pk) instance._old_payment_status = old.status except sender.DoesNotExist: instance._old_payment_status = None else: instance._old_payment_status = None @receiver(post_save, sender="payment.PaymentModel") def payment_post_save(sender, instance, created, **kwargs): old_status = getattr(instance, "_old_payment_status", None) is_newly_completed = ( instance.status == "completed" and (created or old_status != "completed") ) if not is_newly_completed: return try: auto_eval = instance.valuation.auto_detail except (AttributeError, AutoEvaluationModel.DoesNotExist): return EvaluationHistoryService.log_auto( auto_evaluation=auto_eval, event_type=EvaluationEventType.PAYMENT_MADE, actor=instance.payer, meta={ "amount": str(instance.amount), "payment_method": instance.payment_method, "transaction_id": instance.transaction_id or "", }, ) # ───────────────────────────────────────────────────────────────────────────── # QuickEvaluation — order_created va status_changed # ───────────────────────────────────────────────────────────────────────────── @receiver(pre_save, sender=QuickEvaluationModel) def quick_eval_pre_save(sender, instance, **kwargs): if instance.pk: try: old = QuickEvaluationModel.objects.get(pk=instance.pk) instance._old_status = old.status except QuickEvaluationModel.DoesNotExist: instance._old_status = None else: instance._old_status = None @receiver(post_save, sender=QuickEvaluationModel) def quick_eval_post_save(sender, instance, created, **kwargs): if created: EvaluationHistoryService.log_quick( quick_evaluation=instance, event_type=EvaluationEventType.ORDER_CREATED, actor=instance.created_by, ) else: old_status = getattr(instance, "_old_status", None) if old_status is not None and old_status != instance.status: status_labels = dict(QuickEvaluationStatus.choices) EvaluationHistoryService.log_quick( quick_evaluation=instance, event_type=EvaluationEventType.STATUS_CHANGED, meta={ "from_status": old_status, "from_status_display": status_labels.get(old_status, old_status), "to_status": instance.status, "to_status_display": status_labels.get(instance.status, instance.status), }, )