From e2bee3aee28c4de4e7279574b709c0ce089bd86d Mon Sep 17 00:00:00 2001
From: bashmak
Date: Thu, 16 Feb 2017 17:47:58 +0300
Subject: [PATCH] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=B4?=
=?UTF-8?q?=D0=B0=D1=82=D0=B0=20=D0=B7=D0=B0=D0=B2=D0=B5=D1=80=D1=88=D0=B5?=
=?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D1=83=D1=81=D0=BB=D1=83=D0=B3=D0=B8=20?=
=?UTF-8?q?=D1=80=D0=B0=D1=81=D1=87=D0=B8=D1=82=D1=8B=D0=B2=D0=B0=D0=B5?=
=?UTF-8?q?=D1=82=D1=81=D1=8F=20=D0=BF=D1=80=D0=B8=20=D0=BF=D0=BE=D0=B4?=
=?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D0=B8=20=D1=83=D1=81?=
=?UTF-8?q?=D0=BB=D1=83=D0=B3=D0=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
abonapp/models.py | 66 +++++++++----------------
abonapp/views.py | 11 +++--
tariff_app/base_intr.py | 6 +--
tariff_app/custom_tariffs.py | 34 +++++++------
tariff_app/models.py | 2 +-
templates/abonapp/activate_service.html | 4 +-
6 files changed, 56 insertions(+), 67 deletions(-)
diff --git a/abonapp/models.py b/abonapp/models.py
index 8d20b02..2f243b9 100644
--- a/abonapp/models.py
+++ b/abonapp/models.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from django.utils import timezone
-from django.utils.datetime_safe import datetime
from django.db import models
from django.core.validators import DecimalValidator
from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult
@@ -10,14 +9,7 @@ from accounts_app.models import UserProfile
class LogicError(Exception):
- def __init__(self, value):
- self.message = value
-
- def __str__(self):
- return repr(self.message)
-
- def __str__(self):
- return repr(self.message)
+ pass
class AbonGroup(models.Model):
@@ -56,6 +48,9 @@ class AbonTariff(models.Model):
# время начала действия, остальные что не начали действие - NULL
time_start = models.DateTimeField(null=True, blank=True, default=None)
+ # время завершения услуги
+ deadline = models.DateTimeField(null=True, blank=True, default=None)
+
def priority_up(self):
# ищем услугу с большим приоритетом(число приоритета меньше)
target_abtar = AbonTariff.objects.filter(
@@ -108,21 +103,24 @@ class AbonTariff(models.Model):
# Считает текущую стоимость услуг согласно выбранной для тарифа логики оплаты (см. в документации)
def calc_amount_service(self):
- calc_obj = self.tariff.get_calc_type()
+ calc_obj = self.tariff.get_calc_type()(self)
# calc_obj - instance of tariff_app.custom_tariffs.TariffBase
- amount = calc_obj.calc_amount(self)
+ amount = calc_obj.calc_amount()
return round(amount, 2)
# Активируем тариф
def activate(self, current_user):
+ calc_obj = self.tariff.get_calc_type()(self)
amnt = self.calc_amount_service()
# если не хватает денег
if self.abon.ballance < amnt:
raise LogicError('Не хватает денег на счету')
- # дата активации услуги
+ # считаем дату активации услуги
self.time_start = timezone.now()
+ # считаем дату завершения услуги
+ self.deadline = calc_obj.calc_deadline()
# снимаем деньги за услугу
- self.abon.make_pay(current_user, amnt)
+ self.abon.make_pay(current_user, amnt, u_comment='Завершение и оплата услуги по истечению срока действия')
self.save()
# Используется-ли услуга сейчас, если время старта есть то он активирован
@@ -209,7 +207,7 @@ class Abon(UserProfile):
self.ballance += amount
# покупаем тариф
- def buy_tariff(self, tariff, author, comment=None):
+ def pick_tariff(self, tariff, author, comment=None):
assert isinstance(tariff, Tariff)
# выбераем связь ТарифАбонент с самым низким приоритетом
@@ -241,47 +239,29 @@ class Abon(UserProfile):
def activate_next_tariff(self, author):
ats = AbonTariff.objects.filter(abon=self).order_by('tariff_priority')
- nw = datetime.now(tz=timezone.get_current_timezone())
+ nw = timezone.datetime.now()
for at in ats:
- # Если активированный тариф
- if not at.is_started():
- return
-
- # время к началу месяца
- to_start_month = datetime(nw.year, nw.month, 1, tzinfo=timezone.get_current_timezone())
-
- # проверяем расстояние от Сегодня до начала этого месяца.
- # И от заказа тарифа до начала этого месяца
- if (nw - at.time_start) > (nw - to_start_month):
- # Заказ из прошлого месяца, срок действия закончен
- print('Заказ из прошлого месяца, срок действия закончен')
-
+ # если услуга просрочена
+ if nw > at.deadline:
+ print("Услуга просрочена, отключаем, и подключаем новую")
# выберем следующую по приоритету
# next_tarifs = AbonTariff.objects.filter(tariff_priority__gt = self.tariff_priority, abon=self.abon)
- next_tarifs = filter(lambda tr: tr.tariff_priority > at.tariff_priority, ats)[:2]
+ next_tarifs = [tr for tr in ats if tr.tariff_priority > at.tariff_priority][:2]
+ #next_tarifs = filter(lambda tr: tr.tariff_priority > at.tariff_priority, ats)[:2]
- # и если что-нибудь вернулось то активируем, давая время начала действия
+ # и если что-нибудь из списка следующих услуг вернулось - то активируем
if len(next_tarifs) > 0:
- next_tarifs[0].time_start = nw
- next_tarifs[0].save(update_fields=['time_start'])
+ next_tarifs[0].activate(author)
- # завершаем текущую услугу.
+ # удаляем запись о текущей услугу.
at.delete()
- # Создаём лог о завершении услуги
- AbonLog.objects.create(
- abon=self,
- amount=0,
- author=author,
- comment='Завершение услуги по истечению срока действия'
- )
-
# есть-ли доступ у абонента к услуге, смотрим в tariff_app.custom_tariffs..manage_access()
def is_access(self):
trf = self.active_tariff()
if not trf: return False
- ct = trf.get_calc_type()
+ ct = trf.get_calc_type()()
if ct.manage_access(self):
return True
else:
@@ -311,7 +291,7 @@ class InvoiceForPayment(models.Model):
author = models.ForeignKey(UserProfile, related_name='+')
def __str__(self):
- return "%s -> %d $" % (self.abon.username, self.amount)
+ return "%s -> %.2f" % (self.abon.username, self.amount)
def set_ok(self):
self.status = True
diff --git a/abonapp/views.py b/abonapp/views.py
index c911460..d4d51e9 100644
--- a/abonapp/views.py
+++ b/abonapp/views.py
@@ -285,6 +285,7 @@ def abonhome(request, gid, uid):
})
+@mydefs.require_ssl
def terminal_pay(request):
from .pay_systems import allpay
ret_text = allpay(request)
@@ -329,7 +330,7 @@ def add_invoice(request, gid, uid):
@login_required
@permission_required('abonapp.can_buy_tariff')
-def buy_tariff(request, gid, uid):
+def pick_tariff(request, gid, uid):
frm = None
grp = get_object_or_404(models.AbonGroup, id=gid)
abon = get_object_or_404(models.Abon, id=uid)
@@ -338,7 +339,7 @@ def buy_tariff(request, gid, uid):
frm = forms.BuyTariff(request.POST)
if frm.is_valid():
cd = frm.cleaned_data
- abon.buy_tariff(cd['tariff'], request.user)
+ abon.pick_tariff(cd['tariff'], request.user)
#abon.save()
messages.success(request, 'Тариф успешно выбран')
return redirect('abonapp:abon_services', gid=gid, uid=abon.id)
@@ -433,7 +434,7 @@ def activate_service(request, gid, uid, srvid):
abtar.activate(request.user)
messages.success(request, 'Услуга активирована')
- return redirect('abonapp:abon_home', gid, uid)
+ return redirect('abonapp:abon_services', gid, uid)
except NasFailedResult as e:
messages.error(request, e)
@@ -441,12 +442,14 @@ def activate_service(request, gid, uid, srvid):
messages.warning(request, e)
except models.LogicError as e:
messages.error(request, e)
+ calc_obj = abtar.tariff.get_calc_type()(abtar)
return render(request, 'abonapp/activate_service.html', {
'abon': abtar.abon,
'abon_group': abtar.abon.group,
'abtar': abtar,
'amount': amount,
- 'diff': abtar.abon.ballance - amount
+ 'diff': abtar.abon.ballance - amount,
+ 'deadline': calc_obj.calc_deadline()
})
diff --git a/tariff_app/base_intr.py b/tariff_app/base_intr.py
index 2014a5e..caa6723 100644
--- a/tariff_app/base_intr.py
+++ b/tariff_app/base_intr.py
@@ -5,12 +5,12 @@ from abc import ABCMeta, abstractmethod
class TariffBase(metaclass=ABCMeta):
@abstractmethod
- def calc_amount(self, abon_tariff):
+ def calc_amount(self):
"""Считает итоговую сумму платежа"""
@abstractmethod
- def get_avail_time(self):
- """Возвращает оставшееся время услуги в секундах"""
+ def calc_deadline(self):
+ """Считаем дату, до которой действкет тариф"""
@staticmethod
def description():
diff --git a/tariff_app/custom_tariffs.py b/tariff_app/custom_tariffs.py
index b4f0abe..7cef333 100644
--- a/tariff_app/custom_tariffs.py
+++ b/tariff_app/custom_tariffs.py
@@ -1,42 +1,46 @@
# -*- coding: utf-8 -*-
-from datetime import datetime, timedelta
+from datetime import timedelta
from django.utils import timezone
from .base_intr import TariffBase
+from calendar import monthrange
# from abonapp import AbonTariff
class TariffDefault(TariffBase):
- # Базовый функционал считает стоимость пропорционально использованному времени
- def calc_amount(self, abon_tariff):
+
+ def __init__(self, abon_tariff):
#assert isinstance(abon_tariff, AbonTariff)
+ self.abon_tariff = abon_tariff
+
+ # Базовый функционал считает стоимость пропорционально использованному времени
+ def calc_amount(self):
# сейчас
nw = timezone.now()
# сколько прошло с начала действия услуги
# если времени начала нет то это начало действия, использованное время 0
- time_diff = nw - abon_tariff.time_start if abon_tariff.time_start else timedelta(0)
+ time_diff = nw - self.abon_tariff.time_start if self.abon_tariff.time_start else timedelta(0)
# времени в этом месяце
- curr_month_time = datetime(nw.year, nw.month if nw.month == 12 else nw.month + 1, 1) - timedelta(days=1)
+ curr_month_time = timezone.datetime(nw.year, nw.month if nw.month == 12 else nw.month + 1, 1) - timedelta(days=1)
curr_month_time = timedelta(days=curr_month_time.day)
# Сколько это в процентах от всего месяца (k - коеффициент)
k = time_diff.total_seconds() / curr_month_time.total_seconds()
# результат - это полная стоимость тарифа умноженная на k
- res = k * abon_tariff.tariff.amount
+ res = k * self.abon_tariff.tariff.amount
return float(res)
- # возвращаем сколько времени осталось до завершения услуги (конца месяца)
- def get_avail_time(self):
- from calendar import monthrange
+ # Тут мы расчитываем конец действия услуги, завершение будет в конце месяца
+ def calc_deadline(self):
nw = timezone.now()
last_day = monthrange(nw.year, nw.month)[1]
- last_month_date = datetime(year=nw.year, month=nw.month, day=last_day,
- hour=23,minute=59, second=59,tzinfo=nw.tzinfo)
- return last_month_date - nw
+ last_month_date = timezone.datetime(year=nw.year, month=nw.month, day=last_day,
+ hour=23, minute=59, second=59)
+ return timezone.make_aware(last_month_date)
@staticmethod
def description():
@@ -47,8 +51,8 @@ class TariffDp(TariffDefault):
# в IS снимается вся стоимость тарифа вне зависимости от времени использования
# просто возвращаем всю стоимость тарифа
- def calc_amount(self, abon_tariff):
- return float(abon_tariff.tariff.amount)
+ def calc_amount(self):
+ return float(self.abon_tariff.tariff.amount)
@staticmethod
def description():
@@ -56,7 +60,7 @@ class TariffDp(TariffDefault):
class TariffCp(TariffDefault):
- def calc_amount(self, abon_tariff):
+ def calc_amount(self):
return 12.6
@staticmethod
diff --git a/tariff_app/models.py b/tariff_app/models.py
index 411f5c0..508276a 100644
--- a/tariff_app/models.py
+++ b/tariff_app/models.py
@@ -28,7 +28,7 @@ class Tariff(models.Model):
if len(ob) > 0:
res_type = ob[0][1]
assert issubclass(res_type, TariffBase)
- return res_type()
+ return res_type
def __str__(self):
return "%s (%.2f)" % (self.title, self.amount)
diff --git a/templates/abonapp/activate_service.html b/templates/abonapp/activate_service.html
index 14c2827..bfa6dfd 100644
--- a/templates/abonapp/activate_service.html
+++ b/templates/abonapp/activate_service.html
@@ -24,7 +24,9 @@
Вы уверены что хотите активировать абоненту эту услугу?
Обратите внимание что с его счёта снимутся деньги и откроется доступ к ресурсам оплаченной
услуги.
- Стоимость услуги: {{ amount }}руб. На счету {{ abon.ballance }} руб, останется {{ diff }} руб.
+ Стоимость услуги: {{ amount }}руб. На счету {{ abon.ballance }} руб, останется {{ diff }} руб.
+ Услуга будет действовать до {{ deadline|date:'d F Y, H:i:s' }}
+