diff --git a/finance/tasks.py b/finance/tasks.py index 33a0615..4577298 100644 --- a/finance/tasks.py +++ b/finance/tasks.py @@ -1,61 +1,62 @@ import logging - import os + import requests -from dateutil.relativedelta import relativedelta +from django.conf import settings +from django.db import transaction +from django.utils import timezone from yandex_money.models import Payment from finance.models import InvoiceRebilling from lms import celery_app -from django.conf import settings -from django.utils import timezone logger_yandex = logging.getLogger('yandex_money') @celery_app.task def periodic_billing(): - try: logger_yandex.info("start periodic billing task") invoices = InvoiceRebilling.objects.filter(method='Y').exclude(status='F') - - for invoice in invoices.filter( - expected_date__gt=timezone.now(), expected_date__lt=timezone.now() + relativedelta(days=1)): - # TODO выбирать все, даже прошлые неотработанные - что бы не потерять - - user = invoice.bill.user - yandex_pay = Payment.objects.create( - order_amount=invoice.price, - customer_number=user.id, - user=user, - cps_email=user.email, - shop_id=settings.YANDEX_MONEY_REBILLING_SHOP_ID, - scid=settings.YANDEX_MONEY_REBILLING_SCID - ) - invoice.yandex_pay = yandex_pay - invoice.save() - - repeat_card_payment(invoice) - except Exception as exc: - logger_yandex.error('periodic billing Exception', exc_info=True, extra={ - 'exc': exc - }) - # TODO записывать в invoice.comments ошибку яндекса - - -def repeat_card_payment(invoice): - resp = requests.post(settings.YANDEX_MONEY_MWS_URL + 'repeatCardPayment', - data={ - 'clientOrderId': invoice.id, # уникальное возрастающее целое число - 'invoiceId': invoice.key, - 'amount': invoice.price, - 'orderNumber': invoice.yandex_pay.order_number - }, - cert=( - os.path.join(settings.SSL_ROOT, 'skillbox.cer'), - os.path.join(settings.SSL_ROOT, 'skillbox.key') - ), - verify=os.path.join(settings.SSL_ROOT, 'yamoney_chain.cer')) + for invoice in invoices.filter(expected_date__lt=timezone.now()): + # выбираем все необработанные из прошлого + with transaction.atomic(): + try: + _yandex_repeat_card_payment(invoice) + except Exception as exc: + logger_yandex.critical('periodic billing Exception', exc_info=True, extra={ + 'invoice id': invoice.id, 'exc': exc + }) + invoice.comment = 'Ошибка при попытке повторного платежа, свяжитесь с клиентской службой' + invoice.save() + + +def _yandex_repeat_card_payment(invoice): + user = invoice.bill.user + yandex_pay = Payment.objects.create( + order_amount=invoice.price, + customer_number=user.id, + user=user, + cps_email=user.email, + shop_id=settings.YANDEX_MONEY_REBILLING_SHOP_ID, + scid=settings.YANDEX_MONEY_REBILLING_SCID + ) + invoice.yandex_pay = yandex_pay + + resp = requests.post( + url=settings.YANDEX_MONEY_MWS_URL + 'repeatCardPayment', + data={ + 'clientOrderId': invoice.id, # уникальное возрастающее целое число + 'invoiceId': invoice.key, + 'amount': invoice.price, + 'orderNumber': invoice.yandex_pay.order_number + }, + cert=( + os.path.join(settings.SSL_ROOT, 'skillbox.cer'), + os.path.join(settings.SSL_ROOT, 'skillbox.key') + ), + verify=os.path.join(settings.SSL_ROOT, 'yamoney_chain.cer') + ) + # TODO тут проверять нет ли ошибки яндекса (даже при 200 ответе) logger_yandex.info('periodic billing finish', exc_info=True, extra={ 'response': resp.text, 'code': resp.status_code, })