From e201ba444e9f238e3be0a4f15a5f60ecd3c08a43 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sun, 26 Mar 2017 16:30:13 +0300 Subject: [PATCH] license: some refactoring --- project/customer/admin.py | 13 ---- project/customer/context_processors.py | 36 ++++++++--- project/customer/models.py | 88 +++++++++++++++----------- project/customer/tasks.py | 14 ++-- project/customer/utils.py | 66 ++++++++++--------- 5 files changed, 122 insertions(+), 95 deletions(-) diff --git a/project/customer/admin.py b/project/customer/admin.py index dc49a05..c1b394e 100644 --- a/project/customer/admin.py +++ b/project/customer/admin.py @@ -12,23 +12,10 @@ class UserProfileAdmin(admin.ModelAdmin): class LicenseAdmin(admin.ModelAdmin): list_display = ('get_company', 'term', 'status', 'order_date', 'date_from', 'date_to') - list_display_links = list_display search_fields = ('company__email', ) list_filter = ('status', 'term', 'order_date', 'date_from', 'date_to') -#TODO прописать fieldsets -# fieldsets = [ -# (None, {'fields': ['user',]}), -# (None, {'fields': ['profile_type',]}), -# (None, {'fields': ['name', 'phone_code', 'phone', 'address', 'inn',]}), -# (None, {'fields': ['add_glavbuh_sign', 'glavbuh_fio',]}), -# (None, {'fields': ['v_litce', 'na_osnovanii',]}), -# (u'ИП', {'fields': ['ip_surname', 'ip_name', 'ip_midname', 'ip_kod_okpo',]}), -# (u'Организация', {'fields': ['org_boss_name', 'org_kpp',]}), -# (u'Печать и подписи', {'fields': ['boss_sign', 'glavbuh_sign', 'stamp',]}), -# ] - class BankAccountAdmin(admin.ModelAdmin): class Media: diff --git a/project/customer/context_processors.py b/project/customer/context_processors.py index 7edabc0..c65681f 100644 --- a/project/customer/context_processors.py +++ b/project/customer/context_processors.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- from datetime import datetime, timedelta + from django.core.cache import cache + from .models import License @@ -13,22 +15,36 @@ def license_check_soon_ends(request): license_15days = cache.get('license_15_%s' % (request.user.username,), None) days_left = cache.get('days_left_%s' % (request.user.username,), None) cur_license = cache.get('cur_license_%s' % (request.user.username,), None) + + now_ = datetime.today() + if not days_left or not cur_license: - now = datetime.today() - cur_license = License.objects.filter(company=request.user.profile, date_from__lte=now, date_to__gte=now, - status__in=[consts.LICENSE_TEST_PERIOD, consts.LICENSE_PAID, consts.LICENSE_ACTIVE], deleted=False) + cur_license = License.objects.filter( + company=request.user.profile, + date_from__lte=now_, + date_to__gte=now_, + status__in=[consts.LICENSE_TEST_PERIOD, consts.LICENSE_PAID, consts.LICENSE_ACTIVE], + deleted=False + ) if cur_license: cur_license = cur_license[0] - days_left = (cur_license.date_to - now.date()).days + + days_left = (cur_license.date_to - now_.date()).days + cache.set('days_left_%s' % (request.user.username,), days_left, cache_duration) cache.set('cur_license_%s' % (request.user.username,), cur_license, cache_duration) if not license_cookie: - now = datetime.today() if license_15days is None: - licenses_ends = License.objects.filter(company=request.user.profile, date_to__lte=now + timedelta(consts.LICENSE_LEFT_DAYS), - status__in=[consts.LICENSE_TEST_PERIOD, consts.LICENSE_PAID, consts.LICENSE_ACTIVE], deleted=False) + licenses_ends = License.objects.filter( + company=request.user.profile, + date_to__lte = now_ + timedelta(days=consts.LICENSE_LEFT_DAYS), + status__in=[consts.LICENSE_TEST_PERIOD, consts.LICENSE_PAID, consts.LICENSE_ACTIVE], + deleted=False + ) + next_licenses = License.objects.filter(company=request.user.profile, status=consts.LICENSE_PAID, deleted=False) + if licenses_ends and not next_licenses: days_to_end = licenses_ends[0].date_to cache.set('license_15_%s' % (request.user.username,), days_to_end, cache_duration) @@ -37,9 +53,9 @@ def license_check_soon_ends(request): license_15days = '' return { - 'license_15days': license_15days, - 'license_days': days_left, - 'cur_license': cur_license, + 'license_15days': license_15days, + 'license_days': days_left, + 'cur_license': cur_license, } except Exception as e: # print e diff --git a/project/customer/models.py b/project/customer/models.py index f7628fa..67c7037 100644 --- a/project/customer/models.py +++ b/project/customer/models.py @@ -417,40 +417,48 @@ class License(models.Model): term = models.IntegerField(verbose_name=u'срок лицензии') date_from = models.DateField(u'дата начала', null=True, blank=True) date_to = models.DateField(u'дата окончания', null=True, blank=True) - payform = models.IntegerField(verbose_name=u'форма оплаты', - choices=consts.PAYFORMS, default=consts.PAYFORM_BEZNAL) - status = models.IntegerField(verbose_name=u'статус лицензии', - choices=consts.LICENSE_STATUSES, default=consts.LICENSE_UNPAID) + payform = models.IntegerField(verbose_name=u'форма оплаты', choices=consts.PAYFORMS, default=consts.PAYFORM_BEZNAL) + status = models.IntegerField(verbose_name=u'статус лицензии', choices=consts.LICENSE_STATUSES, default=consts.LICENSE_UNPAID) order_date = models.DateField(verbose_name=u'дата заказа', auto_now_add=True) paid_date = models.DateField(verbose_name=u'дата оплаты', null=True, blank=True) pay_sum= models.IntegerField(verbose_name=u'сумма оплаты') deleted = models.BooleanField(u'удалено', default=False) + + class Meta: + verbose_name = u'Лицензия' + verbose_name_plural = u'Лицензии' + def __init__(self, *args, **kwargs): super(License, self).__init__(*args, **kwargs) - self.__prev_date = self.paid_date + self.__prev_paid_date = self.paid_date def __unicode__(self): return u'%s - %s %s (%d %s)' % ( - self.company.get_company_name(), - self.term, - numeral.choose_plural(self.term, u"месяц, месяца, месяцев"), - self.pay_sum, - numeral.choose_plural(self.pay_sum, u"рубль, рубля, рублей"), - ) + self.company.get_company_name(), + self.term, + numeral.choose_plural(self.term, u"месяц, месяца, месяцев"), + self.pay_sum, + numeral.choose_plural(self.pay_sum, u"рубль, рубля, рублей"), + ) def save(self, *args, **kwargs): - if not self.__prev_date and self.paid_date: + if not self.__prev_paid_date and self.paid_date: max_date_license = License.objects.filter(company=self.company).aggregate(Max('date_to'))['date_to__max'] - today = datetime.now().date() - if max_date_license < today: - max_date_license = today - timedelta(1) + + now_ = datetime.now() + if max_date_license < now_.today(): + max_date_license = now_.today() - timedelta(days=1) + self.date_from = max_date_license + relativedelta(days=1) self.date_to = self.date_from + relativedelta(months=self.term, days=-1) + self.company.active = True self.company.save() + self.status = consts.LICENSE_PAID - utils.check_one_profile(self.company, License, datetime.now(), manual=True) + + utils.check_one_profile(self.company, License, now_, manual=True) super(License, self).save(*args, **kwargs) @@ -461,55 +469,61 @@ class License(models.Model): if self.status == consts.LICENSE_UNPAID: if self.payform == consts.PAYFORM_BEZNAL: return u'Скачать счёт' % reverse('customer_license_get_doc', kwargs={'order_num': self.id}) + elif self.payform == consts.PAYFORM_CARD: return u'Оплатить счёт' + elif self.payform == consts.PAYFORM_SBER_KVITANZ: # не используется. однако могут быть старые лицензии с данной формой оплаты return u'Скачать квитанцию' % reverse('customer_license_get_doc', kwargs={'order_num': self.id}) + elif self.status in [consts.LICENSE_PAID, consts.LICENSE_ACTIVE]: return u'История операций' + else: return '' def get_term(self): if self.term == consts.LICENSE_TEST_PERIOD_TERM: - return u'%d дней' % consts.LICENSE_TEST_PERIOD_DAYS + return u'%d %s' % (consts.LICENSE_TEST_PERIOD_DAYS, numeral.choose_plural(self.term, u'день, дня, дней'),) else: - return u'%s %s' % (self.term, - numeral.choose_plural(self.term, u"месяц, месяца, месяцев"), - ) + return u'%s %s' % (self.term, numeral.choose_plural(self.term, u"месяц, месяца, месяцев"),) def get_paid_status(self): if self.status == consts.LICENSE_PAID: return u'Лицензия оплачена, ещё не активирована' + elif self.status in [consts.LICENSE_ACTIVE, consts.LICENSE_TEST_PERIOD]: left = relativedelta(self.date_to, datetime.today()) if left.months: - left_str = '%d %s %d %s' % (left.months, - numeral.choose_plural(left.months, u"месяц, месяца, месяцев"), - left.days, - numeral.choose_plural(left.days, u"день, дня, дней"), - ) + left_str = u'%d %s %d %s' % ( + left.months, + numeral.choose_plural(left.months, u"месяц, месяца, месяцев"), + left.days, + numeral.choose_plural(left.days, u"день, дня, дней"), + ) else: - left_str = '%d %s' % ( - left.days, - numeral.choose_plural(left.days, u"день, дня, дней"), - ) + left_str = u'%d %s' % ( + left.days, + numeral.choose_plural(left.days, u"день, дня, дней"), + ) return u'Лицензия активирована: осталось %s' % left_str + elif self.status == consts.LICENSE_EXPIRED: return u'Время истекло' + else: return None class LicensePrice(models.Model): - term = models.IntegerField(verbose_name=u'срок лицензии', - choices=consts.TERMS) - price = models.IntegerField(verbose_name=u'сумма оплаты') + term = models.IntegerField(u'срок лицензии', choices=consts.TERMS) + price = models.IntegerField(u'сумма оплаты') def __unicode__(self): - return u'%s %s (%d %s)' % (self.term, - numeral.choose_plural(self.term, u"месяц, месяца, месяцев"), - self.price, - numeral.choose_plural(self.price, u"рубль, рубля, рублей"), - ) + return u'%s %s (%d %s)' % ( + self.term, + numeral.choose_plural(self.term, u"месяц, месяца, месяцев"), + self.price, + numeral.choose_plural(self.price, u"рубль, рубля, рублей"), + ) diff --git a/project/customer/tasks.py b/project/customer/tasks.py index c8e1e54..139ae67 100644 --- a/project/customer/tasks.py +++ b/project/customer/tasks.py @@ -7,25 +7,27 @@ import traceback from django.core.mail import mail_admins from celery import shared_task -from .models import License, UserProfile -from .utils import check_one_profile +from project.customer.models import License, UserProfile +from project.customer.utils import check_one_profile from project.customer import consts @shared_task def check_license(): profiles = UserProfile.objects.all() - now = datetime.today() + now_ = datetime.today() - #licenses = License.objects.filter(date_to__lt=now, status__in=[consts.LICENSE_TEST_PERIOD, consts.LICENSE_ACTIVE], deleted=False) + #licenses = License.objects.filter(date_to__lt=now_, status__in=[consts.LICENSE_TEST_PERIOD, consts.LICENSE_ACTIVE], deleted=False) #licenses.update(status=consts.LICENSE_EXPIRED) - licenses = License.objects.filter(order_date__lte=now - timedelta(consts.LICENSE_PAY_DAYS), status=consts.LICENSE_UNPAID, deleted=False) + licenses = License.objects.filter(order_date__lte = now_ - timedelta(days=consts.LICENSE_PAY_DAYS), + status=consts.LICENSE_UNPAID, deleted=False) + licenses.update(status=consts.LICENSE_SUSPENDED) for profile in profiles: try: - check_one_profile(profile, License, now) + check_one_profile(profile, License, now_) except Exception as e: mail_admins(subject=u'customer: check_license error', message=u'Profile id=%s.\n\n%s' % (profile.pk, traceback.format_exc(e)) diff --git a/project/customer/utils.py b/project/customer/utils.py index 937bc9e..846d520 100644 --- a/project/customer/utils.py +++ b/project/customer/utils.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- from datetime import timedelta -from django.conf import settings from django.core.mail import EmailMessage from django.template.loader import render_to_string +from django.conf import settings from project.customer import consts @@ -11,16 +11,18 @@ from project.customer import consts SUPPORT_EMAIL = getattr(settings, 'SUPPORT_EMAIL') -def check_one_profile(profile, License, now, manual=False): +def check_one_profile(profile, License, now_, manual=False): profile_is_active = profile.active - licenses = License.objects.filter(company=profile, date_from__lte=now, date_to__gte=now, + + licenses = License.objects.filter(company=profile, date_from__lte=now_, date_to__gte=now_, status__in=[consts.LICENSE_TEST_PERIOD, consts.LICENSE_PAID, consts.LICENSE_ACTIVE], deleted=False) + licenses.filter(status=consts.LICENSE_PAID).update(status=consts.LICENSE_ACTIVE) + profile.active = False if licenses: profile.active = True - else: - profile.active = False + profile.save() user_email = profile.users.get().email @@ -28,61 +30,67 @@ def check_one_profile(profile, License, now, manual=False): if profile.active and not profile_is_active: template_name = 'myauth/license_activated.txt' subject = u'Документор: Профиль активирован' - dict_context = {'user_email': user_email, - 'support_email': SUPPORT_EMAIL, - 'license_starts': licenses[0].date_from, - 'license_ends': licenses[0].date_to, - } + dict_context = { + 'user_email': user_email, + 'support_email': SUPPORT_EMAIL, + 'license_starts': licenses[0].date_from, + 'license_ends': licenses[0].date_to, + } email_body = render_to_string(template_name, dict_context) email = EmailMessage(subject=subject, to=(user_email,), body=email_body) email.send() - licenses_remain = License.objects.filter(company=profile, date_from__gt=now + timedelta(1), + licenses_remain = License.objects.filter(company=profile, date_from__gt = now_ + timedelta(days=1), status=consts.LICENSE_PAID, deleted=False) + licenses_to_pay = License.objects.filter(company=profile, status=consts.LICENSE_UNPAID, deleted=False) if not licenses_remain and not manual: - licenses = License.objects.filter(company=profile, date_to__lt=now, + licenses = License.objects.filter(company=profile, date_to__lt=now_, status__in=[consts.LICENSE_TEST_PERIOD, consts.LICENSE_ACTIVE], deleted=False) - licenses.update(status=status=consts.LICENSE_EXPIRED) + + licenses.update(status=consts.LICENSE_EXPIRED) if licenses: template_name = 'myauth/license_ended.txt' subject = u'Документор: срок действия лицензии окончен' - dict_context = {'user_email': user_email, - 'support_email': SUPPORT_EMAIL, - 'license_ends': licenses[0].date_to, - 'licenses_to_pay': licenses_to_pay, - } + dict_context = { + 'user_email': user_email, + 'support_email': SUPPORT_EMAIL, + 'license_ends': licenses[0].date_to, + 'licenses_to_pay': licenses_to_pay, + } email_body = render_to_string(template_name, dict_context) email = EmailMessage(subject=subject, to=(user_email,), body=email_body) email.send() - licenses = License.objects.filter(company=profile, date_to=now + timedelta(1), + licenses = License.objects.filter(company=profile, date_to = now_ + timedelta(days=1), status__in=[consts.LICENSE_TEST_PERIOD, consts.LICENSE_ACTIVE], deleted=False) if licenses: template_name = 'myauth/license_ends.txt' subject = u'Документор: окончание срока действия лицензии' - dict_context = {'user_email': user_email, - 'support_email': SUPPORT_EMAIL, - 'license_ends': licenses[0].date_to, - 'licenses_to_pay': licenses_to_pay, - } + dict_context = { + 'user_email': user_email, + 'support_email': SUPPORT_EMAIL, + 'license_ends': licenses[0].date_to, + 'licenses_to_pay': licenses_to_pay, + } email_body = render_to_string(template_name, dict_context) email = EmailMessage(subject=subject, to=(user_email,), body=email_body) email.send() if not manual: - licenses = License.objects.filter(company=profile, order_date=now - timedelta(consts.LICENSE_PAY_DAYS-1), - status=status=consts.LICENSE_UNPAID, deleted=False) + licenses = License.objects.filter(company=profile, order_date = now_ - timedelta(days = consts.LICENSE_PAY_DAYS - 1), + status=consts.LICENSE_UNPAID, deleted=False) if licenses: template_name = 'myauth/license_to_pay.txt' subject = u'Документор: есть неоплаченные счета' - dict_context = {'user_email': user_email, - 'support_email': SUPPORT_EMAIL, - } + dict_context = { + 'user_email': user_email, + 'support_email': SUPPORT_EMAIL, + } email_body = render_to_string(template_name, dict_context) email = EmailMessage(subject=subject, to=(user_email,), body=email_body) email.send()