# coding=utf-8 from dateutil.relativedelta import relativedelta from django.conf import settings from django.core.mail import EmailMessage from django.db import models from django.utils import timezone from yandex_money.models import Payment from progress.models import Progress class Bill(models.Model): course_token = models.UUIDField(verbose_name="Токен курса", editable=False) user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='Плательщик', related_name='bill_user') opener = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='Ответственный сотрудник', null=True) comment = models.TextField(verbose_name='Комментарий продавца', help_text='Будет показано пользователю', blank=True, editable=False) description = models.TextField(verbose_name='Внутренняя заметка', blank=True) date = models.DateTimeField(verbose_name="Дата выставления", auto_now_add=True) freeze = models.BooleanField(verbose_name='Отказ от платежей', default=False) def __str__(self): return '%s: %s' % (self.id, self.user) def freeze_course(self, user): try: p = Progress.objects.get(user=user, course_token=self.course_token) p.freeze = True p.save() except Progress.DoesNotExist: pass self.freeze = True self.save() def get_full_price(self): return sum([i.price for i in self.invoice_set.all() if not i.price is None]) def check_validate(self, invoice_id): return self.invoice_set.filter(is_open=True).exclude(id=invoice_id).count() == 1 def check_pay(self): return self.invoice_set.filter(status="F").exists() class Meta: verbose_name = 'Счет' verbose_name_plural = 'Счета' unique_together = ( ('course_token', 'user',), ) class Invoice(models.Model): BILL_METHOD = ( ('C', 'Наличные'), ('H', 'JustClick'), ('A', 'Альфа-Банк'), ('S', 'SimplePay'), ('Y', 'YandexKassa') ) BILL_STATUSES = ( ('W', 'Ожидание согласия'), ('P', 'На оплате'), ('F', 'Оплачен'), ('C', 'Отклонен'), ) status = models.CharField(verbose_name='Статус', max_length=1, default='W', choices=BILL_STATUSES) price = models.IntegerField(verbose_name='Сумма', editable=False, null=True, blank=True) #Todo На самом деле тут не далжно быть значений null real_price = models.FloatField(verbose_name='Полученная сумма', null=True, blank=True, help_text='Сумма, минус комиссия', editable=False) method = models.CharField(verbose_name='Способ оплаты', max_length=2, default='Y', choices=BILL_METHOD) key = models.CharField(verbose_name='Ключ платежа', max_length=255, editable=False, blank=True) yandex_pay = models.OneToOneField(to=Payment, blank=True, null=True) comment = models.TextField(verbose_name='Комментарий продавца', help_text='Будет показано пользователю', blank=True, editable=False) bill = models.ForeignKey(to=Bill, verbose_name="Связный счёт") is_open = models.BooleanField(default=True, verbose_name="Открывает ли платёж курс") date = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания платежа") expected_date = models.DateTimeField(default=timezone.now, verbose_name="Ожидаемая дата платежа") date_of_payment = models.DateTimeField(verbose_name="Дата фактической оплаты", blank=True, null=True) def get_comment(self): return '''Вам выставлен счёт,''' if \ self.comment == "" else self.comment def send_link(self): msg = EmailMessage( 'Вам выставлен новый счёт', """%s для оплаты перейдите по ссылке %s/api/v1/finance/payment/%s/""" % (self.get_comment(), settings.DOMAIN, self.yandex_pay.id), to=[self.yandex_pay.cps_email], bcc=[self.bill.opener.email], reply_to=[self.bill.opener.email], ) msg.send() def __str__(self): return '%s:%s %s' % (self.id, self.get_status_display(), self.bill.user) class Meta: verbose_name = 'Платёж' verbose_name_plural = 'Платежи' class InvoiceRebilling(Invoice): rebilling_on = models.BooleanField(verbose_name='Повторять платеж', default=False, editable=False) def create_child_pays(self, count): for idx in range(int(count)-1): InvoiceRebilling.objects.create( bill=self.bill, comment=self.comment, method=self.method, status='W', is_open=self.is_open, price=self.price, rebilling_on=False, expected_date=(timezone.now() + relativedelta(months=idx+1)), ) class Meta: verbose_name = 'Повторный платёж' verbose_name_plural = 'Повторные платежи'