import logging import traceback from typing import Any from django.db.models.signals import post_save from django.dispatch import receiver from django.utils.translation import gettext_lazy as _ from engine.payments.gateways import BadLimitsError from engine.payments.models import Balance, Gateway, Transaction from engine.payments.utils.emailing import balance_deposit_email from engine.vibes_auth.models import User logger = logging.getLogger(__name__) # noinspection PyUnusedLocal @receiver(post_save, sender=User) def create_balance_on_user_creation_signal( instance: User, created: bool, **kwargs: dict[Any, Any] ) -> None: if created: Balance.objects.create(user=instance) # noinspection PyUnusedLocal @receiver(post_save, sender=Transaction) def process_transaction_changes( instance: Transaction, created: bool, **kwargs: dict[Any, Any] ) -> None: if created: if not instance.gateway: instance.gateway = Gateway.objects.can_be_used().first() try: gateway = instance.gateway.get_integration_class_object() if ( instance.gateway.minimum_transaction_amount <= instance.amount <= instance.gateway.maximum_transaction_amount ): gateway.process_transaction(instance) else: raise BadLimitsError( _( f"the transaction amount didn't fit into allowed limits: " f"{instance.gateway.minimum_transaction_amount} " f"!<= {instance.amount} " f"!<= {instance.gateway.maximum_transaction_amount}" ) ) except Exception as e: instance.process = {"status": "ERRORED", "error": str(e)} logger.error( f"Error processing transaction {instance.uuid}: {e}\n{traceback.format_exc()}" ) if not created: status = str(instance.process.get("status", "")).lower() success = instance.process.get("success", False) if ("success" in status or success) and (instance.process.get("notify", False)): balance_deposit_email.delay(str(instance.uuid))