diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po index 5be7d30..8ee31a6 100644 --- a/abonapp/locale/ru/LC_MESSAGES/django.po +++ b/abonapp/locale/ru/LC_MESSAGES/django.po @@ -57,10 +57,6 @@ msgstr "Не хватает денег на счету" msgid "finish service perm" msgstr "Снятие со счёта средств" -#: abonapp/models.py:145 -msgid "activate service perm" -msgstr "Активация услуги абонента" - #: abonapp/models.py:162 msgid "Digital field" msgstr "Цифровое поле" @@ -94,10 +90,6 @@ msgstr "Может просматривать паспортные данные" msgid "Buy service default log" msgstr "Покупка тарифного плана через админку" -#: abonapp/models.py:303 -msgid "service overdue log" -msgstr "Услуга просрочена, отключаем, и подключаем новую" - #: abonapp/models.py:346 msgid "Ip address already exist" msgstr "Такой ip уже у кого-то есть" @@ -598,10 +590,6 @@ msgstr "Не найдены улицы для группы" msgid "Services of subscriber" msgstr "Купленные абонентом услуги (назначенные тарифные планы)" -#: abonapp/templates/abonapp/services.html:9 -msgid "Priority" -msgstr "Приоритет" - #: abonapp/templates/abonapp/services.html:12 msgid "Input speed" msgstr "Входящая скорость" @@ -614,18 +602,6 @@ msgstr "Исходящая скорость" msgid "Works until" msgstr "Действует до" -#: abonapp/templates/abonapp/services.html:15 -msgid "Do" -msgstr "Действия" - -#: abonapp/templates/abonapp/services.html:52 -msgid "Priority up" -msgstr "Повысить приоритет" - -#: abonapp/templates/abonapp/services.html:58 -msgid "Priority down" -msgstr "Понизить приоритет" - #: abonapp/templates/abonapp/services.html:64 msgid "Delete service" msgstr "Удалить услугу" @@ -902,3 +878,9 @@ msgstr "Звонки не найдены" msgid "Dialing" msgstr "Звонки" + +msgid "That service already activated" +msgstr "Эта услуга уже подключена" + +msgid "Service already activated" +msgstr "Услуга уже подключена" diff --git a/abonapp/models.py b/abonapp/models.py index 3e0fb45..f291155 100644 --- a/abonapp/models.py +++ b/abonapp/models.py @@ -41,107 +41,42 @@ class AbonLog(models.Model): class AbonTariff(models.Model): - abon = models.ForeignKey('Abon') + + def __init__(self, deadline=None, *args, **kwargs): + super(AbonTariff, self).__init__(*args, **kwargs) + calc_obj = self.tariff.get_calc_type()(self) + self.time_start = timezone.now() + if deadline is None: + self.deadline = calc_obj.calc_deadline() + else: + self.deadline = deadline + tariff = models.ForeignKey(Tariff, related_name='linkto_tariff') - tariff_priority = models.PositiveSmallIntegerField(default=0) - # время начала действия, остальные что не начали действие - 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( - abon=self.abon, - tariff_priority__lt=self.tariff_priority - ).order_by('-tariff_priority')[:1] - if target_abtar.count() > 0: - target_abtar = target_abtar[0] - else: - return - - # Ищем текущий тариф абонента - active_abtar = AbonTariff.objects.filter( - abon=self.abon - )[:1] - if active_abtar.count() > 0: - active_abtar = active_abtar[0] - else: - return - - # Если услуга с которой хотим поменяться приоритетом является текущей то нельзя меняться - if active_abtar == target_abtar: - return - - # Swap приоритетов у текущего и найденного с меньшим tariff_priority (большим приоритетом) - tmp_prior = target_abtar.tariff_priority - target_abtar.tariff_priority = self.tariff_priority - target_abtar.save(update_fields=['tariff_priority']) - self.tariff_priority = tmp_prior - self.save(update_fields=['tariff_priority']) - - def priority_down(self): - # ищем услугу с меньшим приоритетом - target_abtar = AbonTariff.objects.filter( - abon=self.abon, - tariff_priority__gt=self.tariff_priority - )[:1] - if target_abtar.count() > 0: - target_abtar = target_abtar[0] - else: - # меньше нет, это самая последняя услуга - return - - # Swap приоритетов у текущего и найденного с большим tariff_priority (меньшим приоритетом) - tmp_pr = self.tariff_priority - self.tariff_priority = target_abtar.tariff_priority - target_abtar.tariff_priority = tmp_pr - target_abtar.save(update_fields=['tariff_priority']) - self.save(update_fields=['tariff_priority']) - - # Считает текущую стоимость услуг согласно выбранной для тарифа логики оплаты (см. в документации) def calc_amount_service(self): amount = self.tariff.amount return round(amount, 2) - # Активируем тариф - def activate(self, current_user, deadline=None): - calc_obj = self.tariff.get_calc_type()(self) - amnt = self.tariff.amount - # если не хватает денег - if self.abon.ballance < amnt: - raise LogicError(_('not enough money')) - # считаем дату активации услуги - self.time_start = timezone.now() - # считаем дату завершения услуги - if deadline is None: - self.deadline = calc_obj.calc_deadline() - else: - self.deadline = deadline - # снимаем деньги за услугу - self.abon.make_pay(current_user, amnt) - self.save() - # Используется-ли услуга сейчас, если время старта есть то он активирован def is_started(self): - return True if self.time_start is not None else False + return False if self.time_start is None else True def __str__(self): - return "%d: '%s' - '%s'" % ( - self.tariff_priority, + return "'%s' - '%s'" % ( self.tariff.title, self.abon.get_short_name() ) class Meta: - ordering = ('tariff_priority',) db_table = 'abonent_tariff' - unique_together = (('abon', 'tariff', 'tariff_priority'),) permissions = ( - ('can_complete_service', _('finish service perm')), - ('can_activate_service', _('activate service perm')) + ('can_complete_service', _('finish service perm')) ) @@ -211,7 +146,7 @@ class Opt82(models.Model): class Abon(UserProfile): - current_tariffs = models.ManyToManyField(Tariff, through=AbonTariff) + current_tariff = models.ForeignKey(AbonTariff, null=True, blank=True, on_delete=models.SET_NULL) group = models.ForeignKey(AbonGroup, models.SET_NULL, blank=True, null=True) ballance = models.FloatField(default=0.0) ip_address = MyGenericIPAddressField(blank=True, null=True) @@ -221,20 +156,9 @@ class Abon(UserProfile): extra_fields = models.ManyToManyField(ExtraFieldsModel, blank=True) opt82 = models.ForeignKey(Opt82, null=True, blank=True, on_delete=models.SET_NULL) - _act_tar_cache = None - - # возвращает текущий тариф для абонента - def active_tariff(self, use_cache=True): - if self._act_tar_cache and use_cache: - return self._act_tar_cache - - ats = AbonTariff.objects.filter(abon=self).exclude(time_start=None) - - if ats.count() > 0: - self._act_tar_cache = ats[0].tariff - return ats[0].tariff - else: - self._act_tar_cache = None + # возвращает связь с текущим тарифом для абонента + def active_tariff(self): + return self.current_tariff class Meta: db_table = 'abonent' @@ -262,23 +186,28 @@ class Abon(UserProfile): def pick_tariff(self, tariff, author, comment=None, deadline=None): assert isinstance(tariff, Tariff) - # выбераем связь ТарифАбонент с самым низким приоритетом - abtrf = AbonTariff.objects.filter(abon=self).order_by('-tariff_priority')[:1] - abtrf = abtrf[0] if abtrf.count() > 0 else None + amount = round(tariff.amount, 2) - # создаём новую связь с приоритетом ещё ниже - new_abtar = AbonTariff( - abon=self, - tariff=tariff, - tariff_priority=abtrf.tariff_priority + 1 if abtrf else -1 - ) + if self.current_tariff is not None: + if self.current_tariff.tariff == tariff: + # Эта услуга уже подключена + raise LogicError(_('That service already activated')) + else: + # Не надо молча заменять услугу если какая-то уже есть + raise LogicError(_('Service already activated')) - # Если это первая услуга в списке (фильтр по приоритету ничего не вернул) - if not abtrf: - # значит пробуем её активировать - new_abtar.activate(author, deadline) - else: - new_abtar.save() + # если не хватает денег + if self.ballance < amount: + raise LogicError(_('not enough money')) + + new_abtar = AbonTariff(deadline=deadline, tariff=tariff) + new_abtar.save() + self.current_tariff = new_abtar + + # снимаем деньги за услугу + self.ballance -= amount + + self.save() # Запись об этом в лог AbonLog.objects.create( @@ -287,43 +216,23 @@ class Abon(UserProfile): comment=comment or _('Buy service default log') ) - # Пробует подключить новую услугу если пришло время - def activate_next_tariff(self, author): - ats = AbonTariff.objects.filter(abon=self).order_by('tariff_priority') - + # Производим расчёт услуги абонента, т.е. завершаем если пришло время + def bill_service(self, author): + abon_tariff = self.active_tariff() nw = timezone.now() - - for at in ats: - # услуга не активна, продолжаем - if at.deadline is None: - continue - # если услуга просрочена - if nw > at.deadline: - print(_('service overdue log')) - # выберем следующую по приоритету - # next_tarifs = AbonTariff.objects.filter(tariff_priority__gt = self.tariff_priority, abon=self.abon) - 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].activate(author) - - # удаляем запись о текущей услугу. - at.delete() - return + # если услуга просрочена + if nw > abon_tariff.deadline: + print("Service %s for user %s is overdued, end service" % (abon_tariff.tariff, self)) + abon_tariff.delete() # есть-ли доступ у абонента к услуге, смотрим в tariff_app.custom_tariffs..manage_access() def is_access(self): - ats = AbonTariff.objects.filter(abon=self).exclude(time_start=None) - if not ats or ats.count() < 1: - return False - trf = ats[0].tariff - ct = trf.get_calc_type()(ats[0]) - if ct.manage_access(self): - return True - else: + abon_tariff = self.active_tariff() + if abon_tariff is None: return False + trf = abon_tariff.tariff + ct = trf.get_calc_type()(abon_tariff) + return ct.manage_access(self) # создаём абонента из структуры агента def build_agent_struct(self): @@ -331,16 +240,17 @@ class Abon(UserProfile): user_ip = ip2int(self.ip_address) else: return - inst_tariff = self.active_tariff() - if inst_tariff: - agent_trf = TariffStruct(inst_tariff.id, inst_tariff.speedIn, inst_tariff.speedOut) - else: + abon_tariff = self.active_tariff() + if abon_tariff is None: agent_trf = TariffStruct() + else: + trf = abon_tariff.tariff + agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut) return AbonStruct(self.pk, user_ip, agent_trf, bool(self.is_active)) def save(self, *args, **kwargs): # проверяем не-ли у кого такого-же ip - if Abon.objects.filter(ip_address=self.ip_address).exclude(pk=self.pk).count() > 0: + if self.ip_address is not None and Abon.objects.filter(ip_address=self.ip_address).exclude(pk=self.pk).count() > 0: self.is_bad_ip = True raise LogicError(_('Ip address already exist')) super(Abon, self).save(*args, **kwargs) @@ -467,40 +377,5 @@ def abon_del_signal(sender, instance, **kwargs): return True -def abontariff_post_save(sender, instance, **kwargs): - # Тут или подключение абону услуги, или изменение приоритета - if not kwargs['created']: - # если изменение приоритета то не говорим об этом NAS'у - return - if instance.abon.ip_address is None: - return - try: - agent_abon = instance.abon.build_agent_struct() - if agent_abon is None: - return True - tm = Transmitter() - tm.update_user(agent_abon) - except (NasFailedResult, NasNetworkError): - return True - - -def abontariff_del_signal(sender, instance, **kwargs): - if not instance.is_started(): - # если удаляем не активную услугу то говорить об этом NAS'у не обязательно - return - if instance.abon.ip_address is None: - # если у абонента нет ip то и создавать правило не на кого - return - try: - agent_abon = instance.abon.build_agent_struct() - tm = Transmitter() - tm.pause_user(agent_abon) - except (NasFailedResult, NasNetworkError): - return True - - -models.signals.post_save.connect(abon_post_save, sender=Abon) -models.signals.post_delete.connect(abon_del_signal, sender=Abon) - -models.signals.post_save.connect(abontariff_post_save, sender=AbonTariff) -models.signals.post_delete.connect(abontariff_del_signal, sender=AbonTariff) +#models.signals.post_save.connect(abon_post_save, sender=Abon) +#models.signals.post_delete.connect(abon_del_signal, sender=Abon) diff --git a/abonapp/templates/abonapp/buy_tariff.html b/abonapp/templates/abonapp/buy_tariff.html index ab4aad9..3b968e7 100644 --- a/abonapp/templates/abonapp/buy_tariff.html +++ b/abonapp/templates/abonapp/buy_tariff.html @@ -22,7 +22,7 @@
{% csrf_token %}
- +
diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html index ad334f7..079a32e 100644 --- a/abonapp/templates/abonapp/peoples.html +++ b/abonapp/templates/abonapp/peoples.html @@ -50,7 +50,7 @@ {% if order_by == 'house' %}{% endif %} {% trans 'Telephone' %} - + {% trans 'Service' %} {% trans 'Ballance' %} @@ -83,16 +83,16 @@ {{ human.street|default:_('Not assigned') }} {{ human.house|default:_('Not assigned') }} {{ human.telephone }} - + + {% if human.active_tariff %} + {% if perms.tariff_app.change_tariff %} + {{ human.active_tariff.tariff.title }} + {% else %} + {{ human.active_tariff.tariff.title }} + {% endif %} + {% else %}——— + {% endif %} + {{ human.ballance }} {% if perms.abonapp.delete_abon %} @@ -104,7 +104,7 @@ {% empty %} - + {% trans 'Subscribers not found' %}. {% if perms.abonapp.add_abon %} {% trans 'Add abon' %} @@ -115,7 +115,7 @@ - + {% if perms.abonapp.add_abon %} {% trans 'Add abon' %} diff --git a/abonapp/templates/abonapp/service.html b/abonapp/templates/abonapp/service.html new file mode 100644 index 0000000..17f81c0 --- /dev/null +++ b/abonapp/templates/abonapp/service.html @@ -0,0 +1,54 @@ +{% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %} +{% load i18n %} +{% block content %} + +
+
+ +
+
+

{% trans 'Services of subscriber' %}

+
+
+ {% if abon_tariff %} +

+ {% trans 'Service' %}: + {% if perms.tariff_app.change_tariff %} + + {{ abon_tariff.tariff.title }} + + {% else %} + {{ abon_tariff.tariff.title }} + {% endif %} +

+ {% trans 'Sum' %}: {{ abon_tariff.tarif.amount }} руб. +

{% trans 'Input speed' %}: {{ abon_tariff.tariff.speedIn }}

+

{% trans 'Output speed' %}: {{ abon_tariff.tariff.speedOut }}

+

{% trans 'Works until' %}: {{ abon_tariff.deadline|date:"d E Y, l" }}

+

{{ abon_tariff.tarif.descr }}

+ {% else %} + No service, + {% trans 'Buy service' %} + + {% endif %} + +
+
+
+
+
+
+

Услуги для заказа

+
+
+
+
+
+
+
+ + + + + +{% endblock %} diff --git a/abonapp/templates/abonapp/services.html b/abonapp/templates/abonapp/services.html deleted file mode 100644 index 47b67a9..0000000 --- a/abonapp/templates/abonapp/services.html +++ /dev/null @@ -1,101 +0,0 @@ -{% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %} -{% load i18n %} -{% block content %} - - {% trans 'Services of subscriber' %} - - - - - - - - - - - - - - - {% for trf in abon_tarifs %} - - - - - - - - {% if trf.id != active_abontariff_id %} - - {% else %} - - {% endif %} - - {% empty %} - - - - {% endfor %} - - {% if perms.abonapp.can_buy_tariff %} - - - - - - {% endif %} -
{% trans 'Priority' %}{% trans 'Service' %}{% trans 'Sum' %}{% trans 'Input speed' %}{% trans 'Output speed' %}{% trans 'Works until' %}{% trans 'Do' %}
{{ trf.tariff_priority }} - - {% if perms.tariff_app.change_tariff %} - - {{ trf.tariff.title }} - - {% else %} - {{ trf.tariff.title }} - {% endif %} - - {{ trf.tariff.amount }}{{ trf.tariff.speedIn }}{{ trf.tariff.speedOut }}{{ trf.deadline|date:"d E Y, l" }} - - {% if perms.abonapp.can_activate_service %} - {% if not active_abontariff_id %} - - - - {% endif %} - {% endif %} - - - - - - - - - - - - {% if perms.abonapp.delete_abontariff %} - - - - {% endif %} - - - {% trans 'Finish service' %} - -
{% trans 'Services of subscribers not found' %}. - {% if perms.abonapp.can_buy_tariff %} - {% trans 'Buy' %} - {% endif %} -
- - {% trans 'Buy service' %} - -
- - -{% endblock %} \ No newline at end of file diff --git a/abonapp/tests.py b/abonapp/tests.py deleted file mode 100644 index b66baf8..0000000 --- a/abonapp/tests.py +++ /dev/null @@ -1,225 +0,0 @@ -from django.shortcuts import resolve_url -from django.test import TestCase -from django.test.client import Client -from agent import NasNetworkError -from .models import AbonTariff, Abon, AbonGroup, AbonRawPassword -from tariff_app.models import Tariff -from mydefs import LogicError - - -class AbonTestCase(TestCase): - def setUp(self): - try: - Tariff.objects.create( - title='test_tariff', - descr='taroff descr', - speedIn=1.2, - speedOut=3.0, - amount=3 - ) - abon = Abon() - abon.username = '1234567' - abon.fio = 'mainuser' - abon.telephone = '+79788328884' - abon.set_password('ps') - abon.is_superuser = True - abon.save() - abon_group = AbonGroup.objects.create(title='abon_group') - abon_group.profiles.add(abon) - except NasNetworkError: - pass - - # проверка на пополнение счёта - def test_add_ballance(self): - try: - abon = Abon.objects.get(username='1234567') - ballance = abon.ballance - abon.add_ballance(abon, 13, 'test pay') - abon.save(update_fields=['ballance']) - self.assertEqual(abon.ballance, ballance+13) - ballance = abon.ballance - abon.add_ballance(abon, 5.34, 'test float pay') - abon.save(update_fields=['ballance']) - self.assertEqual(abon.ballance, ballance+5.34) - except NasNetworkError: - pass - - # пробуем выбрать услугу - def test_pick_tariff(self): - try: - tariff = Tariff.objects.get(title='test_tariff') - abon = Abon.objects.get(username='1234567') - try: - abon.pick_tariff(tariff, abon) - # нет денег, должно всплыть исключение и сюда дойти мы не должны - self.assertFalse(True) - except LogicError: - pass - act_tar = abon.active_tariff() - # если недостаточно денег на счету - assert abon.ballance <= tariff.amount - # У абонента на счету 0, не должна быть куплена услуга - self.assertEqual(act_tar, None) - # Раз услуги нет то и доступа быть не должно - self.assertTrue(not abon.is_access()) - - # с деньгами - abon.add_ballance(abon, 7.34, 'add pay for test pick tariff') - abon.pick_tariff(tariff, abon) - act_tar = abon.active_tariff() - # должны получить указанную услугу - self.assertEqual(act_tar, tariff) - # и получить доступ - self.assertTrue(abon.is_access()) - except NasNetworkError: - pass - - # тестим очередь услуг - def test_services_queue(self): - abon = Abon.objects.get(username='1234567') - tariff = Tariff.objects.get(title='test_tariff') - abon.add_ballance(abon, 9, 'add pay for test services queue') - abon.save() - abon.pick_tariff(tariff, abon) - abon.pick_tariff(tariff, abon) - abon.pick_tariff(tariff, abon) - # снять деньги должно было только за первый выбор, остальные стают в очередь услуг - self.assertEqual(abon.ballance, 6) - - c = Client() - # login - c.post(resolve_url('acc_app:login'), {'login': '1234567', 'password': 'ps'}) - url = resolve_url('abonapp:compl_srv', gid=1, uid=1, srvid=1) - resp = c.get(url) - print('RESP:', resp) - self.assertEqual(resp.status_code, 200) - resp = c.post(url, data={ - 'finish_confirm': 'yes' - }) - print('RESP:', resp) - # при успешной остановке услуги идёт редирект на др страницу - self.assertEqual(resp.status_code, 302) - # текущей услуги быть не должно - act_tar = abon.active_tariff() - self.assertIsNone(act_tar) - # не активных услуг останется 2 - noact_count = AbonTariff.objects.filter(abon=abon).filter(time_start=None).count() - self.assertEqual(noact_count, 2) - - # проверяем платёжку alltime - def test_allpay(self): - from hashlib import md5 - from djing.settings import pay_SECRET, pay_SERV_ID - import xmltodict - - def sig(act, pay_account, pay_id): - md = md5() - s = '_'.join((str(act), str(pay_account), pay_SERV_ID, str(pay_id), pay_SECRET)) - md.update(bytes(s, 'utf-8')) - return md.hexdigest() - - c = Client() - url = resolve_url('abonapp:terminal_pay') - r = c.get(url, { - 'ACT': 1, 'PAY_ACCOUNT': '1234567', - 'SERVICE_ID': pay_SERV_ID, - 'PAY_ID': 3561234, - 'TRADE_POINT': 377, - 'SIGN': sig(1, 1234567, 3561234) - }) - xobj = xmltodict.parse(r.content) - self.assertEqual(int(xobj['pay-response']['status_code']), 21) - r = c.get(url, { - 'ACT': 4, 'PAY_ACCOUNT': '1234567', - 'SERVICE_ID': pay_SERV_ID, - 'PAY_ID': 3561234, - 'PAY_AMOUNT': 1.0, - 'TRADE_POINT': 377, - 'SIGN': sig(4, 1234567, 3561234) - }) - xobj = xmltodict.parse(r.content) - self.assertEqual(int(xobj['pay-response']['status_code']), 22) - r = c.get(url, { - 'ACT': 4, 'PAY_ACCOUNT': '1234567', - 'SERVICE_ID': pay_SERV_ID, - 'PAY_ID': 3561234, - 'PAY_AMOUNT': 1.0, - 'TRADE_POINT': 377, - 'SIGN': sig(4, 1234567, 3561234) - }) - xobj = xmltodict.parse(r.content) - self.assertEqual(int(xobj['pay-response']['status_code']), -100) - r = c.get(url, { - 'ACT': 7, 'PAY_ACCOUNT': '1234567', - 'SERVICE_ID': pay_SERV_ID, - 'PAY_ID': 3561234, - 'PAY_AMOUNT': 1.0, - 'TRADE_POINT': 377, - 'SIGN': sig(7, 1234567, 3561234) - }) - xobj = xmltodict.parse(r.content) - self.assertEqual(int(xobj['pay-response']['status_code']), 11) - abon = Abon.objects.get(username='1234567') - self.assertEqual(abon.ballance, 1) - - # пробуем добавить группу абонентов - def test_add_abongroup(self): - abon = Abon.objects.get(username='1234567') - ag = AbonGroup.objects.create(title='%&34%$&*(') - ag.profiles.add(abon) - - # пробуем добавить абонента - def test_add_abon(self): - c = Client() - c.login(username='1234567', password='ps') - url = resolve_url('abonapp:add_abon', gid=1) - r = c.get(url) - # поглядим на страницу добавления абонента - self.assertEqual(r.status_code, 200) - r = c.post(url, { - 'username': '123', - 'password': 'ps', - 'fio': 'Abon Fio', - 'telephone': '+79783753914', - 'is_active': True - }) - self.assertEqual(r.status_code, 302) - r = c.get(resolve_url('abonapp:add_abon', gid=324)) - self.assertEqual(r.status_code, 404) - try: - abn = Abon.objects.get(username='123') - self.assertIsNotNone(abn) - psw = AbonRawPassword.objects.get(account=abn, passw_text='ps') - self.assertIsNotNone(psw) - except Abon.DoesNotExist: - # абонент должен был создаться - self.assertTrue(False) - except AbonRawPassword.DoesNotExist: - # должен быть пароль абонента простым текстом - self.assertTrue(False) - - # пробуем удалить абонента - def test_view_delentity(self): - c = Client() - c.login(username='1234567', password='ps') - url = resolve_url('abonapp:del_abon') + '?t=a&id=1' - r = c.get('/abons/1/addabon') - - -class AbonTariffTestCase(TestCase): - def setUp(self): - abon = Abon.objects.create( - username='1234567', - telephone='+79788328884' - ) - tariff = Tariff.objects.create( - title='test_tariff', - descr='taroff descr', - speedIn=1.2, - speedOut=3.0, - amount=3 - ) - AbonTariff.objects.create( - abon=abon, - tariff=tariff - ) diff --git a/abonapp/urls_abon.py b/abonapp/urls_abon.py index 1de99da..9636922 100644 --- a/abonapp/urls_abon.py +++ b/abonapp/urls_abon.py @@ -15,10 +15,8 @@ urlpatterns = [ url(r'^(?P\d+)/addinvoice$', views.add_invoice, name='add_invoice'), url(r'^(?P\d+)/pick$', views.pick_tariff, name='pick_tariff'), - url(r'^(?P\d+)/chpriority$', views.chpriority, name='chpriority_tariff'), url(r'^(?P\d+)/passport_view$', views.passport_view, name='passport_view'), url(r'^(?P\d+)/complete_service(?P\d+)$', views.complete_service, name='compl_srv'), - url(r'^(?P\d+)/activate_service(?P\d+)$', views.activate_service, name='activate_service'), url(r'^(?P\d+)/opt82$', views.opt82, name='opt82'), url(r'^(?P\d+)/chart$', views.charts, name='charts'), url(r'^(?P\d+)/dials$', views.dials, name='dials'), diff --git a/abonapp/views.py b/abonapp/views.py index db135c9..5fd3f9b 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -245,14 +245,10 @@ def pay_history(request, gid, uid): @mydefs.only_admins def abon_services(request, gid, uid): abon = get_object_or_404(models.Abon, pk=uid) - abon_tarifs = models.AbonTariff.objects.filter(abon=uid) - active_abontariff = abon_tarifs.exclude(time_start=None) - - return render(request, 'abonapp/services.html', { + return render(request, 'abonapp/service.html', { 'abon': abon, - 'abon_tarifs': abon_tarifs, - 'active_abontariff_id': active_abontariff[0].id if active_abontariff.count() > 0 else None, + 'abon_tariff': abon.current_tariff, 'abon_group': abon.group }) @@ -434,28 +430,6 @@ def pick_tariff(request, gid, uid): }) -@login_required -@mydefs.only_admins -def chpriority(request, gid, uid): - t = request.GET.get('t') - act = request.GET.get('a') - - current_abon_tariff = get_object_or_404(models.AbonTariff, pk=t) - - try: - if act == 'up': - current_abon_tariff.priority_up() - elif act == 'down': - current_abon_tariff.priority_down() - except (NasFailedResult, NasNetworkError) as e: - messages.error(request, e) - except mydefs.MultipleException as errs: - for err in errs.err_list: - messages.add_message(request, messages.constants.ERROR, err) - - return redirect('abonapp:abon_home', gid=gid, uid=uid) - - @login_required @permission_required('abonapp.can_complete_service') def complete_service(request, gid, uid, srvid): @@ -515,38 +489,6 @@ def complete_service(request, gid, uid, srvid): }) -@login_required -@permission_required('abonapp.can_activate_service') -def activate_service(request, gid, uid, srvid): - abtar = get_object_or_404(models.AbonTariff, pk=srvid) - amount = abtar.calc_amount_service() - - try: - if request.method == 'POST': - if request.POST.get('finish_confirm') != 'yes': - return HttpResponse(_('Not confirmed')) - - abtar.activate(request.user) - messages.success(request, _('Service has been activated successfully')) - return redirect('abonapp:abon_services', gid, uid) - - except (NasFailedResult, mydefs.LogicError) as e: - messages.error(request, e) - except NasNetworkError as e: - messages.warning(request, e) - except mydefs.MultipleException as errs: - for err in errs.err_list: - messages.add_message(request, messages.constants.ERROR, err) - 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, - 'deadline': calc_obj.calc_deadline() - }) - @login_required @permission_required('abonapp.delete_abontariff') @@ -743,7 +685,8 @@ def charts(request, gid, uid): abontariff = abon.active_tariff() if abontariff is not None: - high = abontariff.speedIn + abontariff.speedOut + trf = abontariff.tariff + high = trf.speedIn + trf.speedOut if high > 100: high = 100 @@ -888,7 +831,7 @@ def dials(request, gid, uid): def abons(request): ablist = [{ 'id': abn.pk, - 'tarif_id': abn.active_tariff().pk if abn.active_tariff() else 0, + 'tarif_id': abn.active_tariff().tariff.pk if abn.active_tariff() is not None else 0, 'ip': abn.ip_address.int_ip(), 'is_active': abn.is_active } for abn in models.Abon.objects.all()] diff --git a/bugs.txt b/bugs.txt index fa0bb2e..ba9cf41 100644 --- a/bugs.txt +++ b/bugs.txt @@ -8,3 +8,6 @@ - Не надо коннектиться к микротику когда не собираемся ничего изменять. А то при сохранении залогинились и вышли без действий - Не удаляет просроченные услуги если не пингуется NAS - Надо отменить учёт временной зоны +!!! Обязательно проверить как отрабатывает на NAS удаление и изменение AbonTariff +!!! Удалить всё что связано с активацией услуги +!!! Убрать досрочное завершение услуги diff --git a/clientsideapp/views.py b/clientsideapp/views.py index fb3d785..b40f628 100644 --- a/clientsideapp/views.py +++ b/clientsideapp/views.py @@ -54,7 +54,7 @@ def buy_service(request, srv_id): else: return render_to_text('clientsideapp/modal_service_buy.html', { 'service': service, - 'current_service': current_service + 'current_service': current_service.tariff if current_service is not None else None }, request=request) except LogicError as e: messages.error(request, e) diff --git a/cron.py b/cron.py index e42d2d8..1369392 100755 --- a/cron.py +++ b/cron.py @@ -16,7 +16,7 @@ def main(): for user in users: try: # бдим за услугами абонента: просроченные отключить, заказанные подключить - user.activate_next_tariff(user) + user.bill_service(user) # если нет ip то и нет смысла лезть в NAS if user.ip_address is None: diff --git a/djing/utils/save_from_nodeny.py b/djing/utils/save_from_nodeny.py index ab5cc4b..c8dfc76 100755 --- a/djing/utils/save_from_nodeny.py +++ b/djing/utils/save_from_nodeny.py @@ -102,7 +102,7 @@ class DumpAbon(object): self.passw = raw_passw srv = obj.active_tariff() if srv is not None: - self.service = DumpService.build_from_db(srv) + self.service = DumpService.build_from_db(srv.tariff) else: self.service = None if obj.opt82 is not None and obj.opt82.mac is not None and obj.opt82.port is not None: