diff --git a/finance/admin.py b/finance/admin.py index 8143c83..2c74c0c 100755 --- a/finance/admin.py +++ b/finance/admin.py @@ -1,12 +1,13 @@ # coding=utf-8 from django.contrib import admin -from finance.models import Bill, Invoice +from finance.models import Bill, Invoice, InvoiceRebilling class InvoiceAdmin(admin.ModelAdmin): - list_display = ('__str__', 'rebilling_on', 'rebilling') + list_display = ('__str__', 'rebilling_on',) admin.site.register(Bill) -admin.site.register(Invoice, InvoiceAdmin) +admin.site.register(Invoice) +admin.site.register(InvoiceRebilling, InvoiceAdmin) diff --git a/finance/migrations/0007_auto_20180330_1452.py b/finance/migrations/0007_auto_20180330_1452.py new file mode 100644 index 0000000..0cd2288 --- /dev/null +++ b/finance/migrations/0007_auto_20180330_1452.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-03-30 14:52 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('finance', '0006_auto_20180330_1121'), + ] + + operations = [ + migrations.RemoveField( + model_name='invoice', + name='rebilling', + ), + migrations.RemoveField( + model_name='invoice', + name='rebilling_on', + ), + ] diff --git a/finance/migrations/0008_invoicerebilling.py b/finance/migrations/0008_invoicerebilling.py new file mode 100644 index 0000000..215016d --- /dev/null +++ b/finance/migrations/0008_invoicerebilling.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-03-30 14:52 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('finance', '0007_auto_20180330_1452'), + ] + + operations = [ + migrations.CreateModel( + name='InvoiceRebilling', + fields=[ + ('invoice_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='finance.Invoice')), + ('rebilling_on', models.BooleanField(default=False, editable=False, verbose_name='Повторять платеж')), + ], + options={ + 'verbose_name': 'Повторный платёж', + 'verbose_name_plural': 'Повторные платежи', + }, + bases=('finance.invoice',), + ), + ] diff --git a/finance/migrations/0009_invoicerebilling_pay_count.py b/finance/migrations/0009_invoicerebilling_pay_count.py new file mode 100644 index 0000000..89e388d --- /dev/null +++ b/finance/migrations/0009_invoicerebilling_pay_count.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-03-30 15:03 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('finance', '0008_invoicerebilling'), + ] + + operations = [ + migrations.AddField( + model_name='invoicerebilling', + name='pay_count', + field=models.SmallIntegerField(default=2, editable=False, verbose_name='Всего платежей'), + preserve_default=False, + ), + ] diff --git a/finance/models.py b/finance/models.py index e72e348..30310e0 100755 --- a/finance/models.py +++ b/finance/models.py @@ -59,8 +59,6 @@ class Invoice(models.Model): bill = models.ForeignKey(to=Bill, verbose_name="Связный счёт") is_open = models.BooleanField(default=True, verbose_name="Открывает ли платёж курс") date = models.DateTimeField(auto_now_add=True) - rebilling_on = models.BooleanField(verbose_name='Повторять платеж', default=False, editable=False) - rebilling = models.BooleanField(verbose_name='Повторный платеж', default=False, editable=False) def get_comment(self): return '''Вам выставлен счёт,''' if \ @@ -71,4 +69,13 @@ class Invoice(models.Model): class Meta: verbose_name = 'Платёж' - verbose_name_plural = 'Платежи' \ No newline at end of file + verbose_name_plural = 'Платежи' + + +class InvoiceRebilling(Invoice): + rebilling_on = models.BooleanField(verbose_name='Повторять платеж', default=False, editable=False) + pay_count = models.SmallIntegerField(verbose_name='Всего платежей', editable=False) + + class Meta: + verbose_name = 'Повторный платёж' + verbose_name_plural = 'Повторные платежи' diff --git a/finance/signals.py b/finance/signals.py index 9d62f16..ea0f3cf 100644 --- a/finance/signals.py +++ b/finance/signals.py @@ -16,7 +16,7 @@ def invoice_signal(instance, **kwargs): course = Course.objects.get(token=instance.bill.course_token) - if instance.yandex_pay and instance.method == 'Y' and instance.status == 'P' and not instance.rebilling: + if instance.yandex_pay and instance.method == 'Y' and instance.status == 'P': msg = EmailMessage( 'Вам выставлен новый счёт', """%s для оплаты перейдите по ссылке @@ -27,7 +27,7 @@ def invoice_signal(instance, **kwargs): ) msg.send() - if instance.status == 'F' and not instance.rebilling: + if instance.status == 'F': if instance.is_open: try: Progress.objects.get( diff --git a/finance/views.py b/finance/views.py index 87d9a66..95bd1d9 100644 --- a/finance/views.py +++ b/finance/views.py @@ -19,7 +19,7 @@ from django.utils.html import strip_tags from courses.models import Course from courses.api import CourseParamsApi -from finance.models import Bill, Invoice +from finance.models import Bill, Invoice, InvoiceRebilling from finance.serializers import BillSerializer, InvoiceSerializer from finance.tasks import setup_periodic_billing from lms.global_decorators import transaction_decorator @@ -99,6 +99,8 @@ class InvoiceDetailView(APIView): price = request.JSON.get('price', None) comment = request.JSON.get('comment', None) real_price = request.JSON.get('real_price', None) + rebilling_on = request.JSON.get('is_rebilling', False) + pay_count = request.JSON.get('pay_count', None) if bill_id is None: return Response("Не передан id счёта", status=400) @@ -117,22 +119,32 @@ class InvoiceDetailView(APIView): if bill.check_validate(invoice_id) and is_open: return Response("Уже есть платёж открывающий курс", status=400) - try: - invoice = Invoice.objects.get(id=invoice_id) - except Invoice.DoesNotExist: - if not invoice_id == 0: - return Response("Платёж не найден", status=404) - - if bill.check_pay(): - return Response( - "Нельзя добавить новый платёж, так как один из платежей по счёту уже оплачен", status=400) - invoice = Invoice.objects.create( + if rebilling_on: + invoice = InvoiceRebilling.objects.create( bill=bill, method=method, status=status, is_open=is_open, + pay_count=pay_count, ) + else: + try: + invoice = Invoice.objects.get(id=invoice_id) + except Invoice.DoesNotExist: + if not invoice_id == 0: + return Response("Платёж не найден", status=404) + + if bill.check_pay(): + return Response( + "Нельзя добавить новый платёж, так как один из платежей по счёту уже оплачен", status=400) + invoice = Invoice.objects.create( + bill=bill, + method=method, + status=status, + is_open=is_open, + ) + if invoice.status == "F": return Response(InvoiceSerializer(invoice).data, status=200) @@ -248,6 +260,10 @@ class YandexPay(APIView): def get(request, pk): try: pay = Payment.objects.get(id=pk) + try: + inv = InvoiceRebilling.objects.get(yandex_pay=pay) + except InvoiceRebilling: + inv = None r = requests.post('https://money.yandex.ru/eshop.xml', data={ 'shopId': pay.shop_id, 'scid': pay.scid, @@ -255,7 +271,7 @@ class YandexPay(APIView): 'customerNumber': pay.customer_number, 'orderNumber': pay.order_number, 'cps_email': pay.cps_email, - 'rebillingOn': pay.invoice.rebilling_on, + 'rebillingOn': False if inv is None else inv.rebilling_on, 'shopSuccessURL': settings.YANDEX_MONEY_SUCCESS_URL, 'shopFailURL': settings.YANDEX_MONEY_FAIL_URL, }) diff --git a/template/mail/sales/back_set_bill.html b/template/mail/sales/back_set_bill.html deleted file mode 100644 index f7e5884..0000000 --- a/template/mail/sales/back_set_bill.html +++ /dev/null @@ -1,10 +0,0 @@ - - -
- -