diff --git a/pytest.ini b/pytest.ini index 5050d8a..01221a8 100644 --- a/pytest.ini +++ b/pytest.ini @@ -16,3 +16,4 @@ flake8-ignore = **/conf/** ALL **/migrations/** ALL **/templates/** ALL + **/public/** ALL diff --git a/src/commons/management/commands/dummydata.py b/src/commons/management/commands/dummydata.py index 4579439..66da354 100644 --- a/src/commons/management/commands/dummydata.py +++ b/src/commons/management/commands/dummydata.py @@ -1,8 +1,4 @@ # -*- coding: utf-8 -*- -from random import randint - -from django.conf import settings - from django.core.management.base import BaseCommand from factories import models as f diff --git a/src/customer/forms.py b/src/customer/forms.py index 1b7ebf8..049ebad 100644 --- a/src/customer/forms.py +++ b/src/customer/forms.py @@ -4,7 +4,6 @@ from django.utils.encoding import force_text from django.utils.safestring import mark_safe from django.conf import settings -from yandex_money.forms import PaymentForm from commons.forms import MyBaseModelForm, set_field_error from customer import consts, models @@ -533,8 +532,3 @@ class LicenseForm(forms.Form): empty_label=None) payform = forms.ChoiceField(choices=consts.PAYFORMS[1:], widget=forms.RadioSelect, label=u'Форма оплаты') - - -class YaForm(PaymentForm): - def get_display_field_names(self): - return () diff --git a/src/customer/models.py b/src/customer/models.py index cc89218..53eca00 100644 --- a/src/customer/models.py +++ b/src/customer/models.py @@ -659,7 +659,6 @@ class License(models.Model): else: return 'Счет оплачен' - @property def account_sub_status(self): if self.status == 4: diff --git a/src/customer/urls.py b/src/customer/urls.py index c63ee79..44634c8 100644 --- a/src/customer/urls.py +++ b/src/customer/urls.py @@ -19,8 +19,6 @@ urlpatterns = [ name='customer_delete_license'), url(r'^get_doc/(?P\d+)/$', documents.get_doc, name='customer_license_get_doc'), - url(r'^payment/confirm/(?P\d+)$', license.yandex_pay, - name='yamoney_confirm'), url(r'^payment/result/$', license.payment_result, name='yamoney_result'), url(r'^payment/success/$', license.payment_success, name='yamoney_success'), url(r'^payment/fail/$', license.payment_fail, name='yamoney_fail'), diff --git a/src/customer/views/license.py b/src/customer/views/license.py index 2bbb6ee..f836625 100644 --- a/src/customer/views/license.py +++ b/src/customer/views/license.py @@ -14,25 +14,11 @@ from django.template.response import TemplateResponse from django.core.urlresolvers import reverse from django.views.decorators.csrf import csrf_protect -from yandex_money.models import Payment - from customer.models import License, LicensePrice -from customer.forms import LicenseForm, YaForm +from customer.forms import LicenseForm from customer.utils import raise_if_no_profile -@login_required -@csrf_protect -def yandex_pay(request, payment_id): - template_name = 'customer/profile/yandex.html' - payment = Payment.objects.get(id=payment_id) - if payment.user != request.user: - raise - form = YaForm(instance=payment) - return render(request, template_name, {'form': form, - 'ya_url': settings.YANDEX_MONEY_PAYMENT_URL}) - - @login_required @csrf_protect def order_license(request): @@ -55,17 +41,6 @@ def order_license(request): pay_sum=form.cleaned_data['term'].price ) new_license.save() - if form.cleaned_data['payform'] == '1': - payment, _ = Payment.objects.get_or_create( - order_amount=form.cleaned_data['term']. - price, - payment_type=Payment.PAYMENT_TYPE.AC, - order_number=new_license.id - ) - payment.user = request.user - payment.customer_number = request.user.email - payment.save() - return redirect(reverse('yamoney_confirm', kwargs={'payment_id': payment.id})) return redirect(reverse('customer-orders')) diff --git a/src/dokumentor/settings/common.py b/src/dokumentor/settings/common.py index 3965e4e..4a4c91c 100644 --- a/src/dokumentor/settings/common.py +++ b/src/dokumentor/settings/common.py @@ -158,7 +158,6 @@ INSTALLED_APPS = [ # 'cmsplugin_filer_video', 'captcha', - # 'yandex_money', 'filer', 'easy_thumbnails', 'treebeard', diff --git a/src/dokumentor/settings/local.py b/src/dokumentor/settings/local.py index 3e418b9..20bd0c6 100644 --- a/src/dokumentor/settings/local.py +++ b/src/dokumentor/settings/local.py @@ -27,13 +27,3 @@ DATABASES = { EMAIL_BACKEND = 'eml_email_backend.EmailBackend' EMAIL_FILE_PATH = os.path.join(ROOT_DIR, 'tmp_emails') - -YANDEX_MONEY_DEBUG = False -YANDEX_MONEY_SCID = 92585 -YANDEX_MONEY_SHOP_ID = 546996 -YANDEX_MONEY_SHOP_PASSWORD = 'sQuMtorHE02U' -YANDEX_MONEY_FAIL_URL = 'https://dokumentor.ru/my/payment/fail/' -YANDEX_MONEY_SUCCESS_URL = 'https://dokumentor.ru/my/payment/success/' -YANDEX_MONEY_PAYMENT_URL = 'https://demomoney.yandex.ru/eshop.xml' -# информировать о случаях, когда модуль вернул Яндекс.Кассе ошибку -YANDEX_MONEY_MAIL_ADMINS_ON_PAYMENT_ERROR = True diff --git a/src/dokumentor/urls.py b/src/dokumentor/urls.py index c8a4922..0f3ce07 100644 --- a/src/dokumentor/urls.py +++ b/src/dokumentor/urls.py @@ -25,7 +25,6 @@ urlpatterns = [ url(r'^user/', include('myauth.urls')), url(r'^captcha/', include('captcha.urls')), - url(r'^yandex-money/', include('yandex_money.urls')), url(r'^', include('cms.urls')), ] diff --git a/src/tests/test_models.py b/src/tests/test_models.py index aaf4d7f..d2d8ec2 100644 --- a/src/tests/test_models.py +++ b/src/tests/test_models.py @@ -44,8 +44,8 @@ def test_license_account_sub_status_not_paid(lic, days): lic.status = consts.STATUS_NOT_PAID lic.order_date = timezone.now().date() - timezone.timedelta(days) lic.save() - if days != 4: - assert f'{4 - days}' in lic.account_sub_status + if days != 5: + assert f'{5 - days}' in lic.account_sub_status else: assert 'будет заморожен' in lic.account_sub_status diff --git a/src/yandex_money/__init__.py b/src/yandex_money/__init__.py deleted file mode 100644 index b170e40..0000000 --- a/src/yandex_money/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -default_app_config = "yandex_money.apps.YandexMoneyConfig" diff --git a/src/yandex_money/admin.py b/src/yandex_money/admin.py deleted file mode 100644 index 7fa5ff8..0000000 --- a/src/yandex_money/admin.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- - -from django.contrib import admin -from .models import Payment - - -class PaymentAdmin(admin.ModelAdmin): - list_display_links = ('customer_number',) - list_display = ( - 'customer_number', - 'payment_type', - 'order_number', - 'order_amount', - 'shop_amount', - 'shop_currency', - 'invoice_id', - 'status', - 'pub_date', - 'user', - 'cps_phone', - ) - list_filter = ( - 'pub_date', - 'status', - ) - search_fields = ( - 'customer_number', - 'cps_email', - 'cps_phone', - 'scid', - 'shop_id', - 'invoice_id', - 'order_number', - ) - - def has_add_permission(self, obj): - return False - - -admin.site.register(Payment, PaymentAdmin) diff --git a/src/yandex_money/apps.py b/src/yandex_money/apps.py deleted file mode 100644 index e931bbb..0000000 --- a/src/yandex_money/apps.py +++ /dev/null @@ -1,7 +0,0 @@ -# -*- coding: utf-8 -*- -from django.apps import AppConfig - - -class YandexMoneyConfig(AppConfig): - name = 'yandex_money' - verbose_name = 'Яндекс.Деньги' diff --git a/src/yandex_money/forms.py b/src/yandex_money/forms.py deleted file mode 100644 index 056929e..0000000 --- a/src/yandex_money/forms.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- - -from hashlib import md5 -from django import forms -from django.conf import settings -from .models import Payment - - -class BasePaymentForm(forms.Form): - """ - shopArticleId - scid scid - sum amount - customerNumber user - orderNumber id - shopSuccessURL success_url - shopFailURL fail_url - cps_provider payment_type - cps_email cps_email - cps_phone cps_phone - paymentType payment_type - shopId shop_id - invoiceId invoice_id - orderCreatedDatetime - orderSumAmount order_amount - orderSumCurrencyPaycash order_currency - orderSumBankPaycash - shopSumAmount shop_amount - shopSumCurrencyPaycash shop_currency - shopSumBankPaycash - paymentPayerCode payer_code - paymentDatetime - cms_name django - """ - - class ERROR_MESSAGE_CODES: - BAD_SCID = 0 - BAD_SHOP_ID = 1 - - error_messages = { - ERROR_MESSAGE_CODES.BAD_SCID: u'scid не совпадает с YANDEX_MONEY_SCID', - ERROR_MESSAGE_CODES.BAD_SHOP_ID: u'scid не совпадает с YANDEX_MONEY_SHOP_ID' - } - - class ACTION: - CHECK = 'checkOrder' - CPAYMENT = 'paymentAviso' - - CHOICES = ( - (CHECK, u'Проверка заказа'), - (CPAYMENT, u'Уведомления о переводе'), - ) - - shopId = forms.IntegerField(initial=settings.YANDEX_MONEY_SHOP_ID) - scid = forms.IntegerField(initial=settings.YANDEX_MONEY_SCID) - orderNumber = forms.CharField(min_length=1, max_length=64) - customerNumber = forms.CharField(min_length=1, max_length=64) - paymentType = forms.CharField(label=u'Способ оплаты', - widget=forms.Select(choices=Payment.PAYMENT_TYPE.CHOICES), - min_length=2, max_length=2, - initial=Payment.PAYMENT_TYPE.PC) - orderSumBankPaycash = forms.IntegerField() - - md5 = forms.CharField(min_length=32, max_length=32) - action = forms.CharField(max_length=16) - - def __init__(self, *args, **kwargs): - super(BasePaymentForm, self).__init__(*args, **kwargs) - if hasattr(settings, 'YANDEX_ALLOWED_PAYMENT_TYPES'): - allowed_payment_types = settings.YANDEX_ALLOWED_PAYMENT_TYPES - self.fields['paymentType'].widget.choices = filter( - lambda x: x[0] in allowed_payment_types, - self.fields['paymentType'].widget.choices) - - @classmethod - def make_md5(cls, cd): - """ - action; - orderSumAmount; - orderSumCurrencyPaycash; - orderSumBankPaycash; - shopId;invoiceId; - customerNumber; - shopPassword - """ - return md5(';'.join(map(str, ( - cd['action'], - cd['orderSumAmount'], - cd['orderSumCurrencyPaycash'], - cd['orderSumBankPaycash'], - cd['shopId'], - cd['invoiceId'], - cd['customerNumber'], - settings.YANDEX_MONEY_SHOP_PASSWORD, - )))).hexdigest().upper() - - @classmethod - def check_md5(cls, cd): - return cls.make_md5(cd) == cd['md5'] - - def clean_scid(self): - scid = self.cleaned_data['scid'] - if ( - scid != settings.YANDEX_MONEY_SCID and - scid not in Payment.get_used_scids() - ): - raise forms.ValidationError(self.error_messages[self.ERROR_MESSAGE_CODES.BAD_SCID]) - return scid - - def clean_shopId(self): - shop_id = self.cleaned_data['shopId'] - if ( - shop_id != settings.YANDEX_MONEY_SHOP_ID and - shop_id not in Payment.get_used_shop_ids() - ): - raise forms.ValidationError(self.error_messages[self.ERROR_MESSAGE_CODES.BAD_SHOP_ID]) - return shop_id - - -class PaymentForm(BasePaymentForm): - sum = forms.FloatField(label='Сумма заказа') - - cps_email = forms.EmailField(label='Email', required=False) - cps_phone = forms.CharField(label='Телефон', - max_length=15, required=False) - - shopFailURL = forms.URLField(initial=settings.YANDEX_MONEY_FAIL_URL) - shopSuccessURL = forms.URLField(initial=settings.YANDEX_MONEY_SUCCESS_URL) - - def __init__(self, *args, **kwargs): - instance = kwargs.pop('instance') - super(PaymentForm, self).__init__(*args, **kwargs) - - self.fields.pop('md5') - self.fields.pop('action') - self.fields.pop('orderSumBankPaycash') - - if not getattr(settings, 'YANDEX_MONEY_DEBUG', False): - for name in self.fields: - if name not in self.get_display_field_names(): - self.fields[name].widget = forms.HiddenInput() - - if instance: - self.fields['sum'].initial = instance.order_amount - self.fields['paymentType'].initial = instance.payment_type - self.fields['customerNumber'].initial = instance.customer_number - self.fields['orderNumber'].initial = instance.order_number - if instance.fail_url: - self.fields['shopFailURL'].initial = instance.fail_url - if instance.success_url: - self.fields['shopSuccessURL'].initial = instance.success_url - if instance.cps_email: - self.fields['cps_email'].initial = instance.cps_email - if instance.cps_phone: - self.fields['cps_phone'].initial = instance.cps_phone - - def get_display_field_names(self): - return ['paymentType', 'cps_email', 'cps_phone'] - - -class CheckForm(BasePaymentForm): - invoiceId = forms.IntegerField() - orderSumAmount = forms.DecimalField(min_value=0, decimal_places=2) - orderSumCurrencyPaycash = forms.IntegerField() - shopSumAmount = forms.DecimalField(min_value=0, decimal_places=2) - shopSumCurrencyPaycash = forms.IntegerField() - paymentPayerCode = forms.IntegerField(min_value=1) - - -class NoticeForm(BasePaymentForm): - invoiceId = forms.IntegerField(min_value=1) - orderSumAmount = forms.DecimalField(min_value=0, decimal_places=2) - orderSumCurrencyPaycash = forms.IntegerField() - shopSumAmount = forms.DecimalField(min_value=0, decimal_places=2) - shopSumCurrencyPaycash = forms.IntegerField() - paymentPayerCode = forms.IntegerField(min_value=1) - cps_email = forms.EmailField(required=False) - cps_phone = forms.CharField(max_length=15, required=False) diff --git a/src/yandex_money/models.py b/src/yandex_money/models.py deleted file mode 100644 index 26e1057..0000000 --- a/src/yandex_money/models.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- - -from uuid import uuid4 - -from django.conf import settings -from django.db import models - -from .signals import payment_process -from .signals import payment_completed - - -class Payment(models.Model): - class STATUS: - PROCESSED = 'processed' - SUCCESS = 'success' - FAIL = 'fail' - - CHOICES = ( - (PROCESSED, 'Processed'), - (SUCCESS, 'Success'), - (FAIL, 'Fail'), - ) - - class PAYMENT_TYPE: - PC = 'PC' - AC = 'AC' - GP = 'GP' - MC = 'MC' - WM = 'WM' - SB = 'SB' - AB = 'AB' - MA = 'MA' - PB = 'PB' - QW = 'QW' - QP = 'QP' - - CHOICES = ( - (PC, u'Кошелек Яндекс.Деньги'), - (AC, u'Банковская карта'), - (GP, u'Наличными через кассы и терминалы'), - (MC, u'Счет мобильного телефона'), - (WM, u'Кошелек WebMoney'), - (SB, u'Сбербанк: оплата по SMS или Сбербанк Онлайн'), - (AB, u'Альфа-Клик'), - (MA, u'MasterPass'), - (PB, u'Интернет-банк Промсвязьбанка'), - (QW, u'QIWI Wallet'), - (QP, u'Доверительный платеж (Куппи.ру)'), - ) - - class CURRENCY: - RUB = 643 - TEST = 10643 - - CHOICES = ( - (RUB, u'Рубли'), - (TEST, u'Тестовая валюта'), - ) - - user = models.ForeignKey( - settings.AUTH_USER_MODEL, blank=True, null=True, - verbose_name=u'Пользователь') - pub_date = models.DateTimeField(u'Время создания', auto_now_add=True) - - # Required request fields - shop_id = models.PositiveIntegerField( - u'ID магазина', default=settings.YANDEX_MONEY_SHOP_ID) - scid = models.PositiveIntegerField( - u'Номер витрины', default=settings.YANDEX_MONEY_SCID) - customer_number = models.CharField( - u'Идентификатор плательщика', max_length=64, - default=lambda: str(uuid4()).replace('-', '')) - order_amount = models.DecimalField( - u'Сумма заказа', max_digits=15, decimal_places=2) - - # Non-required fields - article_id = models.PositiveIntegerField( - u'Идентификатор товара', blank=True, null=True) - payment_type = models.CharField( - u'Способ платежа', max_length=2, default=PAYMENT_TYPE.PC, - choices=PAYMENT_TYPE.CHOICES) - order_number = models.CharField( - u'Номер заказа', max_length=64, - default=lambda: str(uuid4()).replace('-', '')) - cps_email = models.EmailField( - u'Email плательщика', max_length=100, blank=True, null=True) - cps_phone = models.CharField( - u'Телефон плательщика', max_length=15, blank=True, null=True) - success_url = models.URLField( - u'URL успешной оплаты', default=settings.YANDEX_MONEY_SUCCESS_URL) - fail_url = models.URLField( - u'URL неуспешной оплаты', default=settings.YANDEX_MONEY_FAIL_URL) - - # Transaction info - status = models.CharField( - u'Статус', max_length=16, choices=STATUS.CHOICES, - default=STATUS.PROCESSED) - invoice_id = models.PositiveIntegerField( - u'Номер транзакции оператора', blank=True, null=True) - shop_amount = models.DecimalField( - u'Сумма полученная на р/с', max_digits=15, decimal_places=2, blank=True, - null=True, help_text=u'За вычетом процента оператора') - order_currency = models.PositiveIntegerField( - u'Валюта', default=CURRENCY.RUB, choices=CURRENCY.CHOICES) - shop_currency = models.PositiveIntegerField( - u'Валюта полученная на р/с', blank=True, null=True, - default=CURRENCY.RUB, choices=CURRENCY.CHOICES) - performed_datetime = models.DateTimeField( - u'Время выполнение запроса', blank=True, null=True) - - @property - def is_payed(self): - return self.status == self.STATUS.SUCCESS - - def send_signals(self): - status = self.status - if status == self.STATUS.PROCESSED: - payment_process.send(sender=self) - if status == self.STATUS.SUCCESS: - payment_completed.send(sender=self) - - @classmethod - def get_used_shop_ids(cls): - return cls.objects.values_list('shop_id', flat=True).distinct() - - @classmethod - def get_used_scids(cls): - return cls.objects.values_list('scid', flat=True).distinct() - - class Meta: - ordering = ('-pub_date',) - unique_together = ( - ('shop_id', 'order_number'), - ) - verbose_name = u'платёж' - verbose_name_plural = u'платежи' - app_label = 'yandex_money' - - def __unicode__(self): - return u'[Payment id={}, order_number={}, payment_type={}, status={}]'.format( - self.id, self.order_number, self.payment_type, self.status) - - def __str__(self): - return u'[Payment id={}, order_number={}, payment_type={}, status={}]'.format( - self.id, self.order_number, self.payment_type, self.status) diff --git a/src/yandex_money/signals.py b/src/yandex_money/signals.py deleted file mode 100644 index 53f663f..0000000 --- a/src/yandex_money/signals.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- - -from django.dispatch import Signal - -payment_process = Signal() -payment_completed = Signal() diff --git a/src/yandex_money/urls.py b/src/yandex_money/urls.py deleted file mode 100644 index e9cdc3e..0000000 --- a/src/yandex_money/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -# -*- coding: utf-8 -*- - -from django.conf.urls import url -from .views import NoticeFormView -from .views import CheckOrderFormView - - -urlpatterns = [ - url(r'^check/$', CheckOrderFormView.as_view(), name='yandex_money_check'), - url(r'^aviso/$', NoticeFormView.as_view(), name='yandex_money_notice'), -] diff --git a/src/yandex_money/utils.py b/src/yandex_money/utils.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/yandex_money/views.py b/src/yandex_money/views.py deleted file mode 100644 index 46d5346..0000000 --- a/src/yandex_money/views.py +++ /dev/null @@ -1,151 +0,0 @@ -# -*- coding: utf-8 -*- - -import logging -from datetime import datetime, date - -from django.http import HttpResponse -from django.utils.decorators import method_decorator -from django.views.decorators.csrf import csrf_exempt -from django.views.generic import View -from django.conf import settings -from django.core.mail import mail_admins -from lxml import etree -from lxml.builder import E - -from .forms import CheckForm -from .forms import NoticeForm -from .models import Payment -from customer.models import License - - -logger = logging.getLogger('yandex_money') - - -class YandexValidationError(Exception): - params = None - - def __init__(self, params=None): - super(YandexValidationError, self).__init__() - self.params = params if params is not None else {} - - -class BaseView(View): - form_class = None - - @method_decorator(csrf_exempt) - def dispatch(self, *args, **kwargs): - return super(BaseView, self).dispatch(*args, **kwargs) - - def post(self, request, *args, **kwargs): - form = self.form_class(request.POST) - if form.is_valid(): - cd = form.cleaned_data - if form.check_md5(cd): - payment = self.get_payment(cd) - if payment: - try: - self.validate(cd, payment) - except YandexValidationError as exc: - params = exc.params - else: - params = self.get_response_params(payment, cd) - self.mark_payment(payment, cd) - payment.send_signals() - else: - params = {'code': '1000'} - else: - params = {'code': '1'} - else: - params = {'code': '200'} - - self.logging(request, params) - content = self.get_xml(params) - - if ( - getattr(settings, 'YANDEX_MONEY_MAIL_ADMINS_ON_PAYMENT_ERROR', True) and - params.get('code') != '0' - ): - mail_admins( - 'yandexmoney_django error', f'post data: {request.POST}\n\nresponse:{content}') - - return HttpResponse(content, content_type='application/xml') - - def validate(self, data, payment): - pass - - def get_payment(self, cd): - try: - payment = Payment.objects.get( - order_number=cd['orderNumber'], shop_id=cd['shopId']) - except Payment.DoesNotExist: - payment = None - return payment - - def get_response_params(self, payment, cd): - if payment: - now = datetime.now() - - payment.performed_datetime = now - payment.save() - - return {'code': '0', - 'shopId': str(cd['shopId']), - 'invoiceId': str(cd['invoiceId']), - 'performedDatetime': now.isoformat()} - return {'code': '100'} - - def mark_payment(self, payment, cd): - pass - - def get_xml(self, params): - element = self.get_xml_element(**params) - return etree.tostring(element, - pretty_print=True, - xml_declaration=True, - encoding='UTF-8') - - def get_xml_element(self, **params): - raise NotImplementedError() - - def logging(self, request, params): - message = 'Action %s has code %s for customerNumber "%s"' % ( - request.POST.get('action', ''), params['code'], - request.POST.get('customerNumber', '')) - logger.info(message) - - -class CheckOrderFormView(BaseView): - form_class = CheckForm - - def validate(self, data, payment): - if payment.order_amount != data['orderSumAmount']: - params = { - 'code': '100', - 'message': u'Неверно указана сумма платежа', - } - raise YandexValidationError(params=params) - - def get_xml_element(self, **params): - return E.checkOrderResponse(**params) - - -class NoticeFormView(BaseView): - form_class = NoticeForm - - def get_xml_element(self, **params): - return E.paymentAvisoResponse(**params) - - def mark_payment(self, payment, cd): - payment.cps_email = cd.get('cps_email', '') - payment.cps_phone = cd.get('cps_phone', '') - payment.order_currency = cd.get('orderSumCurrencyPaycash') - payment.shop_amount = cd.get('shopSumAmount') - payment.shop_currency = cd.get('shopSumCurrencyPaycash') - payment.payer_code = cd.get('paymentPayerCode') - payment.payment_type = cd.get('paymentType') - payment.status = payment.STATUS.SUCCESS - payment.save() - license = License.objects.get(id=payment.order_number) - license.paid_date = date.today() - license.status = 1 - license.save() diff --git a/tox.ini b/tox.ini index 6c02c02..26881ba 100644 --- a/tox.ini +++ b/tox.ini @@ -1,4 +1,4 @@ [flake8] ignore = E731 F405 max-line-length = 99 -exclude = ./venv/*, ./node_modules/*, **/conf/**, **/migrations/**, **/templates/**, static/*, conf/* +exclude = ./venv/*, ./node_modules/*, **/conf/**, **/migrations/**, **/templates/**, static/*, conf/*, public/*