from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator from django.db import models from django.db.models import Sum from django.utils import timezone from users.models import User TYPES = ( ('minus', 'Снятие'), ('plus', 'Приход'), ) class Wallet(models.Model): customer = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True) balance = models.DecimalField(max_digits=10, decimal_places=0, default=0) def __str__(self): return str(self.balance) class InvoiceHistory(models.Model): TYPES = ( ('score', 'Счет'), ('history', 'История'), ) comment = models.TextField(blank=True) created = models.DateTimeField(default=timezone.now) sum = models.DecimalField(max_digits=10, decimal_places=0, default=0, null=True, blank=True) balance = models.DecimalField(max_digits=10, decimal_places=0, default=0) type = models.CharField(max_length=20, choices=TYPES, default='score') user = models.ForeignKey(User, related_name='invoice_history') def __str__(self): return self.comment def save(self, *args, **kwargs): if self.pk is None: current_sum_info = InvoiceHistory.objects.filter(user=self.user, type="score").aggregate(Sum('sum')) current_sum = current_sum_info['sum__sum'] or 0 if self.type == "score": self.balance = current_sum + self.sum else: self.balance = current_sum super().save(*args, **kwargs) class Meta: verbose_name = 'Счет(История)' verbose_name_plural = 'Счет(История)' ordering = ('-created',) class WithDraw(models.Model): complete = models.BooleanField(default=False) created = models.DateTimeField(default=timezone.now) passport = models.CharField(max_length=50) phone = models.CharField(max_length=30) sum = models.DecimalField(max_digits=10, decimal_places=0, validators=[MinValueValidator(1)]) user = models.ForeignKey(User, related_name='with_draw') yandex_card = models.CharField(max_length=30) def __str__(self): return self.yandex_card def clean(self): if not self.pk: current_score_info = InvoiceHistory.objects.filter(user=self.user, type="score").aggregate(Sum('sum')) withdraw_sum_not_complete = WithDraw.objects.filter(user=self.user, complete=False).aggregate(Sum('sum')) current_score = current_score_info['sum__sum'] or 0 sum_not_complete = withdraw_sum_not_complete['sum__sum'] or 0 current_score -= sum_not_complete if not self.sum is None and self.sum > current_score: raise ValidationError("Сумма должна быть меньше " + str(current_score)) class Meta: verbose_name = 'Заявка на вывод средств' verbose_name_plural = 'Заявки на вывод средств' ordering = ('-created',) class Transaction(models.Model): TYPES = ( ('add', 'Пополнение'), ('reservation', 'Резервирование'), ) complete = models.BooleanField(default=False, editable=False) # Not editable in admin created_at = models.DateTimeField(default=timezone.now, editable=False) customer = models.ForeignKey(User, related_name='customer_transactions') voids_at = models.DateTimeField() sum = models.DecimalField(max_digits=20, decimal_places=0, default=0) type = models.CharField(max_length=20, choices=TYPES, default='add') stages_id = models.CharField(max_length=100, null=True, blank=True) def save(self, *args, **kwargs): if not self.pk and self.created_at: self.voids_at = self.created_at + timezone.timedelta(minutes=9000) super().save(*args, **kwargs) def is_void(self): return timezone.now() > self.voids_at def __str__(self): return str(self.pk) class PayFromScore(models.Model): customer = models.ForeignKey(User, related_name='customer_payfromscore') sum = models.DecimalField(max_digits=20, decimal_places=0, default=0) stages_id = models.CharField(max_length=100, null=True, blank=True) created_at = models.DateTimeField(default=timezone.now, editable=False) def __str__(self): return str(self.pk) class Meta: ordering = ('-created_at',) verbose_name = 'Оплата со счета' verbose_name_plural = 'Оплата со счета'