diff --git a/finance/models.py b/finance/models.py index 89a59f4..f2d50b9 100755 --- a/finance/models.py +++ b/finance/models.py @@ -43,15 +43,54 @@ class Bill(models.Model): 'user': self.user, }) + msg = EmailMessage( + 'Вы откозались от оплаты по счёту', + """Вы откозались от оплаты по счёту. + Вы сможете продолжить оплату в личном кабинете""", + to=[self.user.email], + bcc=[self.opener.email], + reply_to=[self.opener.email], + ) + msg.send() + self.freeze = True self.save() else: - logger_business_rules.warning('Попытка нарушения правила отказа от плотежей', exc_info=True, extra={ + logger_business_rules.warning('Попытка нарушения правила отказа от платежей', exc_info=True, extra={ 'description': 'All payments already paid', 'user': self.user, }) + def unfreeze_course(self, force=False): + if force or self.invoice_set.exclude(status='F')\ + .filter(expected_date__lt=timezone.now() + relativedelta(days=1)).exists(): + if self.invoice_set.filter(status='F').exclude(expected_date__lt=timezone.now()).exists(): + try: + p = Progress.objects.get(user=self.user, course_token=str(self.course_token)) + p.is_freeze = False + p.save() + except Progress.DoesNotExist: + pass + + msg = EmailMessage( + 'Вы возобновили оплату по счёту', + """Вы возобновили оплату по счёту.""", + to=[self.user.email], + bcc=[self.opener.email], + reply_to=[self.opener.email], + ) + msg.send() + + self.freeze = False + self.save() + + else: + logger_business_rules.warning('Попытка нарушения правила возобновления платежей', exc_info=True, extra={ + 'description': 'Excepted date more than one day', + 'user': self.user, + }) + def get_full_price(self): return sum([i.price for i in self.invoice_set.all() if not i.price is None]) diff --git a/finance/tasks.py b/finance/tasks.py index b7912e4..d3d7244 100644 --- a/finance/tasks.py +++ b/finance/tasks.py @@ -1,62 +1,24 @@ -import json -from datetime import datetime, timedelta - import logging import os import requests -from django_celery_beat.models import CrontabSchedule, PeriodicTask from yandex_money.models import Payment from finance.models import InvoiceRebilling from lms import celery_app from django.conf import settings - 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='*/3', - ) - PeriodicTask.objects.create( - crontab=schedule, - name='Periodic billing (order_number={})'.format(order_number), - task='finance.tasks.periodic_billing', - kwargs=json.dumps({ - 'order_number': order_number - }), - expires=datetime.utcnow() + timedelta(days=180) # в течение полугода - ) - - @celery_app.task -def periodic_billing(order_number): - try: - sample = InvoiceRebilling.objects.get(yandex_pay__order_number=order_number) - except InvoiceRebilling.DoesNotExist: - raise ValueError('Номер заказа {} не найден'.format(order_number)) - - bill = sample.bill +def periodic_billing(): + logger_yandex.info("start periodic billing task") - invoice = InvoiceRebilling.objects.create( - status='P', - price=sample.price, - method=sample.method, - is_open=sample.is_open, - bill=bill, - ) + for invoice in InvoiceRebilling.objects.filter(method='Y').exclude(status='F'): - if invoice.method == 'Y': - user = bill.user + user = invoice.bill.user yandex_pay = Payment.objects.create( - invoice_id=sample.yandex_pay.invoice_id, order_amount=invoice.price, customer_number=user.id, user=user, @@ -72,7 +34,7 @@ def repeat_card_payment(invoice): resp = requests.post(settings.YANDEX_MONEY_MWS_URL + 'repeatCardPayment', data={ 'clientOrderId': invoice.id, # уникальное возрастающее целое число - 'invoiceId': invoice.yandex_pay.invoice_id, + 'invoiceId': invoice.key, 'amount': invoice.price, 'orderNumber': invoice.yandex_pay.order_number }, diff --git a/finance/views.py b/finance/views.py index 66a7df3..c866150 100644 --- a/finance/views.py +++ b/finance/views.py @@ -21,7 +21,6 @@ from courses.models import Course from courses.api import CourseParamsApi 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 from lms.tools import get_real_name from django.utils import timezone @@ -60,13 +59,13 @@ class UnFreezeView(APIView): @staticmethod def post(request, pk): - if request.user.is_authenticated: - try: - bill = Bill.objects.get(id=pk) - bill.freeze = False - bill.save() - except Bill.DoesNotExist: - return Response("Счёт не найден", status=404) + try: + bill = Bill.objects.get(id=pk) + except Bill.DoesNotExist: + return Response("Счёт не найден", status=404) + + if request.user.is_authenticated and request.user.email == bill.user.email: + bill.unfreeze_course() return Response(status=204) return Response("Permission denied", status=403) @@ -444,13 +443,10 @@ 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']) @@ -465,6 +461,9 @@ class YandexAvisoView(APIView): }) pay.shop_amount = data['shopSumAmount'] + invoice = pay.invoice + invoice.key = data['invoiceId'] + invoice.save() pay.status = Payment.STATUS.SUCCESS now = timezone.now() pay.performed_datetime = now.isoformat() @@ -495,10 +494,6 @@ class YandexAvisoView(APIView): msg.attach_alternative(html_content, "text/html") msg.send() - if rebilling: - InvoiceRebilling.objects.get(yandex_pay=pay) - setup_periodic_billing(pay.order_number) - return HttpResponse(xml_res, content_type='application/xml') diff --git a/lms/celery.py b/lms/celery.py index 5f3c106..fb1f536 100644 --- a/lms/celery.py +++ b/lms/celery.py @@ -3,6 +3,8 @@ import os from celery import Celery from raven import Client from raven.contrib.celery import register_signal, register_logger_signal +from celery.schedules import crontab + # set the default Django settings module for the 'celery' program. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lms.settings') @@ -13,11 +15,19 @@ app.config_from_object('django.conf:settings', namespace='CELERY') app.autodiscover_tasks() -client = Client('http://caaea487274f4e23a9107862484c79f3:3d463ad4717942508536f7a659921950@sentry.skillbox.ru/3') +client = Client('http://caaea487274f4e23a9107862484c79f3:3d463ad4717942508536f7a659921950@sentry.skillbox.ru/7') register_logger_signal(client) register_signal(client) @app.task(bind=True) def debug_task(self): - print('Request: {0!r}'.format(self.request)) \ No newline at end of file + print('Request: {0!r}'.format(self.request)) + + +CELERY_BEAT_SCHEDULE = { + 'periodic_billing': { + 'task': 'finance.tasks.periodic_billing', + 'schedule': crontab(minute='0',hour='*/3',), + }, +} \ No newline at end of file