from constance import config from django.contrib.postgres.indexes import GinIndex from django.db.models import CASCADE, CharField, FloatField, ForeignKey, JSONField, OneToOneField, QuerySet from django.utils.translation import gettext_lazy as _ from core.abstract import NiceModel class Transaction(NiceModel): amount: float = FloatField(null=False, blank=False) # type: ignore balance: "Balance" = ForeignKey( "payments.Balance", on_delete=CASCADE, blank=True, null=True, related_name="transactions" ) # type: ignore currency: str = CharField(max_length=3, null=False, blank=False) # type: ignore payment_method: str = CharField(max_length=20, null=True, blank=True) # type: ignore order = ForeignKey( # type: ignore "core.Order", on_delete=CASCADE, blank=True, null=True, help_text=_("order to process after paid"), related_name="payments_transactions", ) process: dict = JSONField(verbose_name=_("processing details"), default=dict) # type: ignore def __str__(self): return f"{self.balance.user.email} | {self.amount}" def save(self, **kwargs): if self.amount != 0.0 and ( (config.PAYMENT_GATEWAY_MINIMUM <= self.amount <= config.PAYMENT_GATEWAY_MAXIMUM) or (config.PAYMENT_GATEWAY_MINIMUM == 0 and config.PAYMENT_GATEWAY_MAXIMUM == 0) ): if len(str(self.amount).split(".")[1]) > 2: self.amount = round(self.amount, 2) super().save(**kwargs) return self raise ValueError( _(f"transaction amount must fit into {config.PAYMENT_GATEWAY_MINIMUM}-{config.PAYMENT_GATEWAY_MAXIMUM}") ) class Meta: verbose_name = _("transaction") verbose_name_plural = _("transactions") indexes = [ GinIndex(fields=["process"]), ] class Balance(NiceModel): amount: float = FloatField(null=False, blank=False, default=0) # type: ignore user = OneToOneField( # type: ignore to="vibes_auth.User", on_delete=CASCADE, blank=True, null=True, related_name="payments_balance" ) transactions: QuerySet["Transaction"] def __str__(self): return f"{self.user.email} | {self.amount}" class Meta: verbose_name = _("balance") verbose_name_plural = _("balances") def save(self, **kwargs): if self.amount != 0.0 and len(str(self.amount).split(".")[1]) > 2: self.amount = round(self.amount, 2) super().save(**kwargs)