from django.db import models from django.db.models import Count, Sum, F from django.db.models.functions import Coalesce from BaseModels.base_models import BaseModel from django.utils.translation import gettext_lazy as _ from colorfield.fields import ColorField from datetime import datetime, timedelta # options_list 29.05.2024 # СМС уведомления # push уведомления # выделение заявки цветом (20 заявок) + 70 поднятий # выделение заявок цветом (3 заявки) + 5 поднятий # уведомление на e-mail о появлении перевозчика по заданным критериям # размещение заявок # просмотр контактов class SubscribeOption(BaseModel): allow_route_rising_count = models.IntegerField( verbose_name=_('Количество поднятий объявлений') ,default=0) allow_route_highlight_count = models.IntegerField( verbose_name=_('Количество выделений объявлений'), default=0) route_highlight_hours = models.IntegerField( verbose_name=_('Количество часов выделения цветом объявлений'), default=24) class Meta: verbose_name = _('Опция подписки') verbose_name_plural = _('Опции подписки') ordering = ['order'] class Subscribe(BaseModel): price = models.FloatField(verbose_name='Стоимость', default=0) options = models.ManyToManyField( SubscribeOption, verbose_name=_('Подключенные опции'), blank=True, related_name='rel_subscribes_for_option' ) period_name = models.CharField(max_length=250, verbose_name=_('Название периода')) period = models.IntegerField(default=0, verbose_name=_('Длительность подписки в часах')) bg_color = ColorField(default='#FFFFFF', verbose_name=_('Цвет фона')) text_color = ColorField(default='#000000', verbose_name=_('Цвет текста')) def get_last_order(self, user): order = None orders = self.subscribe_orders_for_subscribe.filter(user=user, enable=True).order_by('-createDT') if orders: order = orders[0] return order class Meta: verbose_name = _('Подписка') verbose_name_plural = _('Подписки') class SubscribeForUser(BaseModel): from AuthApp.models import User user = models.ForeignKey( User, verbose_name=_('Пользователь'), related_name='rel_userSubscribes_for_user', on_delete=models.CASCADE) subscribe = models.ForeignKey( Subscribe, verbose_name=_('Подписка'), null=True, blank=True, related_name='rel_userSubscribes_for_subscribe', on_delete=models.SET_NULL ) last_paid_DT = models.DateTimeField(verbose_name=_('Последняя дата оплаты'), blank=True, null=True) paid_period_from_DT = models.DateTimeField(verbose_name=_('Оплаченный период с'), blank=True, null=True) paid_period_to_DT = models.DateTimeField(verbose_name=_('Оплаченный период до'), blank=True, null=True) auto_continue = models.BooleanField(default=False, verbose_name=_('Автопродление')) receive_finish_subscribe_msg = models.BooleanField( default=False, verbose_name=_('Получать сообщения о окончании периода')) used_route_rising_count = models.IntegerField(verbose_name=_('Использовано поднятий объявлений'), default=0) used_route_highlight_count = models.IntegerField(verbose_name=_('Использовано выделений объявлений'), default=0) class Meta: verbose_name = _('Пользовательская подписка') verbose_name_plural = _('Пользовательские подписки') def __str__(self): res = 'Подписка' if self.subscribe: res += f' {self.subscribe.name}' if self.user: res += f' для {self.user.username}' if not res: res += f' {str(self.id)}' return res def get_highlight_hours(self): options = self.subscribe.options.filter( allow_route_highlight_count__gt=0, ) if options: return options[0].route_highlight_hours return 0 def remains_route_adding_options(self): total_data = SubscribeOption.objects.filter( enable=True, rel_subscribes_for_option=self.subscribe ).aggregate( total_route_rising_count = Coalesce(Sum('allow_route_rising_count'), 0), total_route_highlight_count = Coalesce(Sum('allow_route_highlight_count'), 0), ) total_data.update({ 'used_route_rising_count': self.used_route_rising_count, 'used_route_highlight_count': self.used_route_highlight_count, 'remains_route_rising_count': total_data['total_route_rising_count'] - self.used_route_rising_count, 'remains_route_highlight_count': total_data['total_route_highlight_count'] - self.used_route_highlight_count, }) return total_data def get_days_to_finish(self): days = (self.paid_period_to_DT - datetime.now()).days return days def extension(self, order=None): if not order and self.subscribe.price > 0: return {'error': 'not paid'} if self.subscribe.price == 0: self.activate( paid_period_from_DT=datetime.now(), paid_period_to_DT=datetime.now() + timedelta(hours=self.subscribe.period) ) def activate(self, paid_period_from_DT=None, paid_period_to_DT=None): self.enable = True if paid_period_from_DT: self.paid_period_from_DT = paid_period_from_DT if paid_period_to_DT: self.paid_period_to_DT = paid_period_to_DT self.save() subscribes_for_user = SubscribeForUser.objects.filter( user=self.user ).exclude( id=self.id ) subscribes_for_user.update( enable=False, used_route_rising_count=0, used_route_highlight_count=0, ) return self