db_kyc_project/backend/auction/models/auction.py
Даня Вакуленков 4a18a785e9 Add backend code
2024-12-10 23:31:35 +03:00

67 lines
2.7 KiB
Python

from datetime import datetime
from decimal import Decimal
from django.db import models
from django.utils import timezone
from django.db.models import F, Case, When, Max, ExpressionWrapper, Subquery, OuterRef
from users.models import BetTransaction
class AuctionManager(models.Manager):
def get_queryset(self):
return super().get_queryset().annotate(
_end_time=ExpressionWrapper(
F('initial_end_time') + F('last_call_delta') * F('times_postponed'),
output_field=models.DateTimeField()
)
).annotate(_is_active=Case(
When(_end_time__gt=timezone.now(), then=True),
default=False,
)).annotate(
_min_bet_value=Case(
When(bets__isnull=True, then=F('initial_cost')),
default=Subquery(BetTransaction.objects.filter(bet__auction=OuterRef('pk')).order_by('-value').values('value')[:1]) + Decimal('0.01')
)
).distinct()
class Auction(models.Model):
class Meta:
verbose_name = 'Аукцион'
verbose_name_plural = 'Аукционы'
product = models.ForeignKey('auction.Product', related_name='auctions', on_delete=models.CASCADE,
verbose_name='Товар')
quantity = models.PositiveIntegerField(verbose_name='Количество победителей')
betters = models.ManyToManyField('users.TGUser', through='auction.Bet', related_name='auctions',
verbose_name='Поставившие ставку')
initial_end_time = models.DateTimeField(verbose_name='Изначальная дата окончания')
last_call_delta = models.DurationField(verbose_name='Время последнего шага')
times_postponed = models.IntegerField(default=0, verbose_name='Количество переносов')
commission = models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Комиссия',
help_text='Десятичная дробь')
initial_cost = models.DecimalField(decimal_places=2, max_digits=102, verbose_name='Начальная стоимость')
objects = AuctionManager()
def __str__(self):
return f'Аукцион №{self.pk}'
def check_postpone(self):
if timezone.now() - self.last_call_delta <= self.end_time <= timezone.now():
self.times_postponed = F('times_postponed') + 1
self.save()
@property
def end_time(self):
return self._end_time
@property
def is_active(self):
return self._is_active
@property
def min_bet_value(self):
return self._min_bet_value