import uuid from django.contrib.auth.models import AbstractUser from django.db import models # from core.lib.customers import get_or_create, update_customer_fields from core.util import logs log = logs.get_logger(__name__) SERVICE_CHOICES = (("nordigen", "Nordigen"),) PLATFORM_SERVICE_CHOICES = (("agora", "Agora"),) class User(AbstractUser): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) payment_provider_id = models.CharField(max_length=255, null=True, blank=True) billing_provider_id = models.CharField(max_length=255, null=True, blank=True) email = models.EmailField(unique=True) def get_notification_settings(self): return NotificationSettings.objects.get_or_create(user=self)[0] class NotificationSettings(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) ntfy_topic = models.CharField(max_length=255, null=True, blank=True) ntfy_url = models.CharField(max_length=255, null=True, blank=True) def __str__(self): return f"Notification settings for {self.user}" class Aggregator(models.Model): """ A connection to an API aggregator to pull transactions from bank accounts. """ id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) user = models.ForeignKey(User, on_delete=models.CASCADE) name = models.CharField(max_length=255) service = models.CharField(max_length=255, choices=SERVICE_CHOICES) secret_id = models.CharField(max_length=1024, null=True, blank=True) secret_key = models.CharField(max_length=1024, null=True, blank=True) access_token = models.CharField(max_length=1024, null=True, blank=True) access_token_expires = models.DateTimeField(null=True, blank=True) poll_interval = models.IntegerField(default=10) account_info = models.JSONField(default=dict) currencies = models.JSONField(default=list) fetch_accounts = models.BooleanField(default=True) enabled = models.BooleanField(default=True) def __str__(self): return f"Aggregator ({self.service}) for {self.user}" @classmethod def get_by_id(cls, obj_id, user): return cls.objects.get(id=obj_id, user=user) @property def client(self): pass @classmethod def get_for_platform(cls, platform): return cls.objects.filter(user=platform.user, enabled=True) @classmethod def get_currencies_for_platform(cls, platform): aggregators = Aggregator.get_for_platform(platform) currencies = set() for aggregator in aggregators: for currency in aggregator.currencies: currencies.add(currency) return list(currencies) @classmethod def get_account_info_for_platform(cls, platform): aggregators = Aggregator.get_for_platform(platform) account_info = {} for agg in aggregators: for bank, accounts in agg.account_info.items(): if bank not in account_info: account_info[bank] = [] for account in accounts: account_info[bank].append(account) return account_info class Platform(models.Model): """ A connection to an arbitrage platform like AgoraDesk. """ id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) user = models.ForeignKey(User, on_delete=models.CASCADE) name = models.CharField(max_length=255) service = models.CharField(max_length=255, choices=PLATFORM_SERVICE_CHOICES) token = models.CharField(max_length=1024) password = models.CharField(max_length=1024) otp_token = models.CharField(max_length=1024, null=True, blank=True) username = models.CharField(max_length=255) send = models.BooleanField(default=True) cheat = models.BooleanField(default=False) dummy = models.BooleanField(default=False) cheat_interval_seconds = models.IntegerField(default=600) margin = models.FloatField(default=1.20) max_margin = models.FloatField(default=1.30) min_margin = models.FloatField(default=1.15) min_trade_size_usd = models.FloatField(default=10) max_trade_size_usd = models.FloatField(default=4000) accept_within_usd = models.FloatField(default=1) no_reference_amount_check_max_usd = models.FloatField(default=400) enabled = models.BooleanField(default=True) @property def currencies(self): return Aggregator.get_currencies_for_platform(self) @property def account_info(self): return Aggregator.get_account_info_for_platform(self)