diff --git a/finance/migrations/0010_auto_20180412_1628.py b/finance/migrations/0010_auto_20180412_1628.py new file mode 100644 index 0000000..ef554ce --- /dev/null +++ b/finance/migrations/0010_auto_20180412_1628.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-04-12 16:28 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('finance', '0009_invoicerebilling_pay_count'), + ] + + operations = [ + migrations.RemoveField( + model_name='invoicerebilling', + name='pay_count', + ), + migrations.AddField( + model_name='bill', + name='freeze', + field=models.BooleanField(default=False, verbose_name='Отказ от платежей'), + ), + migrations.AddField( + model_name='invoice', + name='date_of_payment', + field=models.DateTimeField(blank=True, null=True, verbose_name='Дата фактической оплаты'), + ), + migrations.AddField( + model_name='invoice', + name='expected_date', + field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='Ожидаемая дата платежа'), + ), + migrations.AlterField( + model_name='invoice', + name='date', + field=models.DateTimeField(auto_now_add=True, verbose_name='Дата создания платежа'), + ), + ] diff --git a/finance/models.py b/finance/models.py index 434e562..98d749c 100755 --- a/finance/models.py +++ b/finance/models.py @@ -1,7 +1,10 @@ # 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 @@ -13,6 +16,7 @@ class Bill(models.Model): 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) @@ -59,7 +63,9 @@ class Invoice(models.Model): 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) + 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 \ @@ -86,7 +92,18 @@ class Invoice(models.Model): class InvoiceRebilling(Invoice): rebilling_on = models.BooleanField(verbose_name='Повторять платеж', default=False, editable=False) - pay_count = models.SmallIntegerField(verbose_name='Всего платежей', editable=False) + + def create_child_pays(self, count): + for idx in range(count-1): + InvoiceRebilling.objects.create( + bill=self.bill, + comment=self.comment, + method=self.method, + status=self.status, + is_open=self.is_open, + rebilling_on=False, + expected_date=(timezone.now() + relativedelta(months=idx+1)), + ) class Meta: verbose_name = 'Повторный платёж' diff --git a/finance/tasks.py b/finance/tasks.py index a28b3ae..b7912e4 100644 --- a/finance/tasks.py +++ b/finance/tasks.py @@ -8,7 +8,7 @@ import requests from django_celery_beat.models import CrontabSchedule, PeriodicTask from yandex_money.models import Payment -from finance.models import Invoice +from finance.models import InvoiceRebilling from lms import celery_app from django.conf import settings @@ -19,12 +19,11 @@ logger_yandex = logging.getLogger('yandex_money') def setup_periodic_billing(order_number): # TODO: настроить периодичность и срок окончания # 12:00 первого числа каждого месяца + logger_yandex.info("Оформдение новой рассрочки") + schedule, _ = CrontabSchedule.objects.get_or_create( minute='0', - hour='12', - day_of_week='*', - day_of_month='1', - month_of_year='*' + hour='*/3', ) PeriodicTask.objects.create( crontab=schedule, @@ -40,18 +39,18 @@ def setup_periodic_billing(order_number): @celery_app.task def periodic_billing(order_number): try: - sample = Invoice.objects.get(yandex_pay__order_number=order_number) - except Invoice.DoesNotExist: + sample = InvoiceRebilling.objects.get(yandex_pay__order_number=order_number) + except InvoiceRebilling.DoesNotExist: raise ValueError('Номер заказа {} не найден'.format(order_number)) bill = sample.bill - invoice = Invoice.objects.create( + invoice = InvoiceRebilling.objects.create( status='P', price=sample.price, method=sample.method, - rebilling=True, - bill=bill + is_open=sample.is_open, + bill=bill, ) if invoice.method == 'Y': @@ -66,7 +65,7 @@ def periodic_billing(order_number): invoice.yandex_pay = yandex_pay invoice.save() - repeat_card_payment(invoice) + repeat_card_payment(invoice) def repeat_card_payment(invoice): diff --git a/finance/views.py b/finance/views.py index 3a79e0d..313228d 100644 --- a/finance/views.py +++ b/finance/views.py @@ -135,8 +135,10 @@ class InvoiceDetailView(APIView): method=method, status=status, is_open=is_open, - pay_count=pay_count, + rebilling_on=True, ) + invoice.create_child_pays(pay_count) + else: try: invoice = Invoice.objects.get(id=invoice_id) @@ -409,10 +411,13 @@ class YandexAvisoView(APIView): @staticmethod def post(request): data = dict() + rebilling = None for i in request.body.decode('utf-8').split('&'): key = i.split('=')[0] val = i.split('=')[1] data[key] = val + if key == 'rebillingOn': + rebilling = val try: pay = Payment.objects.get(order_number=data['orderNumber']) @@ -457,11 +462,9 @@ class YandexAvisoView(APIView): msg.attach_alternative(html_content, "text/html") msg.send() - try: + if rebilling: InvoiceRebilling.objects.get(yandex_pay=pay) setup_periodic_billing(pay.order_number) - except InvoiceRebilling.DoesNotExist: - pass return HttpResponse(xml_res, content_type='application/xml') @@ -470,7 +473,7 @@ class YandexFailView(APIView): renderer_classes = (JSONRenderer,) @staticmethod - def post(request): + def get(request): data = dict() for i in request.body.decode('utf-8').split('&'): key = i.split('=')[0]