diff --git a/abonapp/models.py b/abonapp/models.py index e74866a..021509d 100644 --- a/abonapp/models.py +++ b/abonapp/models.py @@ -4,11 +4,11 @@ from django.http import Http404 from django.shortcuts import get_object_or_404 from django.utils import timezone from django.utils.datetime_safe import datetime -from agent import get_TransmitterClientKlass, Abonent, Tariff as AgentTariff +from agent import get_TransmitterClientKlass from ip_pool.models import IpPoolItem from tariff_app.models import Tariff from django.db import models -from djing import settings +from django.conf import settings from django.core.validators import DecimalValidator from accounts_app.models import UserProfile @@ -63,7 +63,7 @@ class AbonTariffManager(models.Manager): for at in abon_tariff_list: at.tariff_priority = at_pr at_pr += 1 - at.save() + at.save(update_fields=['tariff_priority']) class AbonTariff(models.Model): @@ -103,9 +103,9 @@ class AbonTariff(models.Model): # Swap приоритетов у текущего и найденного с меньшим tariff_priority (большим приоритетом) tmp_prior = target_abtar.tariff_priority target_abtar.tariff_priority = self.tariff_priority - target_abtar.save() + target_abtar.save(update_fields=['tariff_priority']) self.tariff_priority = tmp_prior - self.save() + self.save(update_fields=['tariff_priority']) def priority_down(self): # ищем услугу с меньшим приоритетом @@ -123,8 +123,8 @@ class AbonTariff(models.Model): tmp_pr = self.tariff_priority self.tariff_priority = target_abtar.tariff_priority target_abtar.tariff_priority = tmp_pr - target_abtar.save() - self.save() + target_abtar.save(update_fields=['tariff_priority']) + self.save(update_fields=['tariff_priority']) # Считает текущую стоимость услуг согласно выбранной для тарифа логики оплаты (см. в документации) def calc_amount_service(self): @@ -133,33 +133,21 @@ class AbonTariff(models.Model): amount = calc_obj.calc_amount(self) return round(amount, 2) - # досрочно завершает услугу - def finish_and_activate_next_tariff(self, author): - - # выберем следующие по приоритету услуги - next_tarifs = AbonTariff.objects.filter(tariff_priority__gt = self.tariff_priority, abon=self.abon)[:1] - - if next_tarifs.count() < 1: - raise LogicError('У абонента нет следующих назначенных услуг') - - # 0й элемент это следующая подключаемая услуга - next_tarifs[0].time_start = timezone.now() - next_tarifs[0].save() - - # сколько денег стоят потраченные ресурсы - used_services = self.calc_amount_service() - - #теперь к текущему баллансу добавляем сумму не потраченных ресурсов, т.к. полная сумма тарифа списывается при покупке тарифа - ret_amount = self.tariff.amount - used_services - self.abon.ballance += ret_amount - self.abon.save() + # Активируем тариф + def activate(self, current_user): + amnt = self.calc_amount_service() + # если не хватает денег + if self.abon.ballance > amnt: + raise LogicError(u'Не хватает денег на счету') + # дата активации услуги + self.time_start = timezone.now() + # снимаем деньги за услугу + self.abon.make_pay(current_user, amnt) + self.save() - AbonLog.objects.create( - abon = self.abon, - amount = ret_amount, - author = author, - comment = u'Досрочное завершение услуги %s' % (self.tariff.title) - ) + # Используется-ли услуга сейчас, если время старта есть то он активирован + def is_started(self): + return True if self.time_start is not None else False def __unicode__(self): return "%d: '%s' - '%s'" % ( @@ -184,11 +172,11 @@ class Abon(UserProfile): _act_tar_cache = None # возвращает текущий тариф для абонента - def active_tariff(self): - if self._act_tar_cache: + 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)[:1] + ats = AbonTariff.objects.filter(abon=self).exclude(time_start=None) if ats.count() > 0: self._act_tar_cache = ats[0].tariff @@ -217,6 +205,7 @@ class Abon(UserProfile): class Meta: db_table = 'abonent' + # Платим за что-то def make_pay(self, curuser, how_match_to_pay=0.0): AbonLog.objects.create( abon = self, @@ -226,6 +215,7 @@ class Abon(UserProfile): ) self.ballance -= how_match_to_pay + # Пополняем счёт def add_ballance(self, current_user, amount): AbonLog.objects.create( abon = self, @@ -235,55 +225,34 @@ class Abon(UserProfile): ) self.ballance += amount + # покупаем тариф def buy_tariff(self, tariff, author): - if self.ballance >= tariff.amount: - # денег достаточно, можно покупать - self.ballance -= tariff.amount - - # Пытаемся подключиться к NAS агенту - tc = get_TransmitterClientKlass()() - - # выбераем связь ТарифАбонент с самым низким приоритетом - abtrf = AbonTariff.objects.filter(abon=self).order_by('-tariff_priority')[:1] - abtrf = abtrf[0] if abtrf.count() > 0 else None - - # создаём новую связь с приоритетом ещё ниже - new_abtar = AbonTariff( - abon=self, - tariff=tariff, - tariff_priority=abtrf.tariff_priority+1 if abtrf else -1 - ) - - # Если это первая услуга в списке (фильтр по приоритету ничего не вернул) - if not abtrf: - # значит она сразу стаёт активной - new_abtar.time_start = timezone.now() - - new_abtar.save() - - # шлём сигнал о том что абонент купил первую услугу, а значит можно пользоваться инетом - # сигнал можно слать только после того как будет сохранён новый объект AbonTariff - if self.is_active and not abtrf: - act_tar = self.active_tariff() - agent_abon = Abonent( - self.id, - self.ip_address.int_ip(), - AgentTariff( - act_tar.id if act_tar else 0, - act_tar.speedIn if act_tar else 0.0, - act_tar.speedOut if act_tar else 0.0 - ) - ) - tc.signal_abon_refresh(agent_abon) - - # Запись об этом в лог - AbonLog.objects.create( - abon = self, amount = -tariff.amount, - author = author, - comment = u'Покупка тарифного плана через админку, тариф "%s"' % tariff.title - ) - else: - raise LogicError(u'Недостаточно денег на счету абонента') + assert isinstance(tariff, Tariff) + + # выбераем связь ТарифАбонент с самым низким приоритетом + abtrf = AbonTariff.objects.filter(abon=self).order_by('-tariff_priority')[:1] + abtrf = abtrf[0] if abtrf.count() > 0 else None + + # создаём новую связь с приоритетом ещё ниже + new_abtar = AbonTariff( + abon=self, + tariff=tariff, + tariff_priority=abtrf.tariff_priority+1 if abtrf else -1 + ) + + # Если это первая услуга в списке (фильтр по приоритету ничего не вернул) + if not abtrf: + # значит она сразу стаёт активной + new_abtar.time_start = timezone.now() + + new_abtar.save() + + # Запись об этом в лог + AbonLog.objects.create( + abon = self, amount = -tariff.amount, + author = author, + comment = u'Покупка тарифного плана через админку, тариф "%s"' % tariff.title + ) # Пробует подключить новую услугу если пришло время def activate_next_tariff(self, author): @@ -292,8 +261,8 @@ class Abon(UserProfile): nw = datetime.now(tz=timezone.get_current_timezone()) for at in ats: - # Если времени активации нет, то это ещё не активированный тариф - if not at.time_start: + # Если активированный тариф + if not at.is_started(): return # время к началу месяца @@ -363,15 +332,15 @@ class InvoiceForPayment(models.Model): def abon_post_save(sender, instance, **kwargs): if kwargs['created']: - print 'abon_pre_save CREATED' + print 'abon_post_save CREATED' else: - print 'abon_pre_save CHANGED' - # подключение к NAS'у в начале для того чтоб если исключение то ничего не сохранялось и сразу показать ошибку + print 'abon_post_save CHANGED' tc = get_TransmitterClientKlass()() # обновляем абонента на NAS tc.signal_abon_refresh(instance) + def abon_del_signal(sender, instance, **kwargs): print 'abon_del_signal' # подключаемся к NAS'у @@ -388,14 +357,24 @@ def abon_del_signal(sender, instance, **kwargs): #tc = get_TransmitterClientKlass()()''' -def tarif_del_signal(sender, instance, **kwargs): - print 'tarif_del_signal' - abon = instance.abon - abon.save() +def abontariff_post_save(sender, instance, **kwargs): + if kwargs['created']: + print('abontariff CREATED', kwargs) + else: + print('abontariff CHANGED', kwargs) + # Тут или подключение абону услуги, или изменение приоритета + tc = get_TransmitterClientKlass()() + tc.signal_abon_refresh(instance.abon) + + +def abontariff_del_signal(sender, instance, **kwargs): + print('abontariff_del_signal', instance.abon) + tc = get_TransmitterClientKlass()() + tc.signal_abon_refresh(instance.abon) models.signals.post_save.connect(abon_post_save, sender=Abon) models.signals.post_delete.connect(abon_del_signal, sender=Abon) -#models.signals.pre_save.connect(tarif_pre_save, sender=AbonTariff) -models.signals.post_delete.connect(tarif_del_signal, sender=AbonTariff) +models.signals.post_save.connect(abontariff_post_save, sender=AbonTariff) +models.signals.post_delete.connect(abontariff_del_signal, sender=AbonTariff) diff --git a/abonapp/urls.py b/abonapp/urls.py index e5c3e37..b4878ec 100644 --- a/abonapp/urls.py +++ b/abonapp/urls.py @@ -15,6 +15,8 @@ urlpatterns = [ url(r'^pay$', views.terminal_pay, name='abonapp_terminalpay_link'), + url(r'^debtors$', views.debtors, name='abonapp_debtors'), + # Api's url(r'^api/abons$', views.abons) diff --git a/abonapp/urls_abon.py b/abonapp/urls_abon.py index 2db45dd..ac23a76 100644 --- a/abonapp/urls_abon.py +++ b/abonapp/urls_abon.py @@ -15,5 +15,8 @@ urlpatterns = [ url(r'^(?P\d+)/addinvoice$', views.add_invoice, name='abonapp_addinvoice_link'), url(r'^(?P\d+)/buy$', views.buy_tariff, name='abonapp_buy_tariff'), url(r'^(?P\d+)/chpriority$', views.chpriority, name='abonapp_chpriority_tariff'), - url(r'^(?P\d+)/complete_service_(?P\d+)$', views.complete_service, name='abonapp_compl_srv'), + url(r'^(?P\d+)/complete_service(?P\d+)$', views.complete_service, name='abonapp_compl_srv'), + url(r'^(?P\d+)/activate_service(?P\d+)$', views.activate_service, name='abonapp_activate_service'), + + url(r'^(?P\d+)/unsubscribe_service(?P\d+)$', views.unsubscribe_service, name='abonapp_unsubscribe_service') ] diff --git a/abonapp/views.py b/abonapp/views.py index 6e84711..b9a1d8c 100644 --- a/abonapp/views.py +++ b/abonapp/views.py @@ -152,7 +152,7 @@ def abonamount(request, gid, uid): if abonid == int(uid): amnt = mydefs.safe_float(request.POST.get('amount')) abon.add_ballance(request.user, amnt) - abon.save() + abon.save(update_fields=['ballance']) return redirect('abonhome_link', gid=gid, uid=uid) else: warning_text = u'Не правильно выбран абонент как цель для пополнения' @@ -193,18 +193,14 @@ def pay_history(request, gid, uid): @mydefs.only_admins def abon_services(request, gid, uid): abon = get_object_or_404(models.Abon, id=uid) - abon_tarifs = models.AbonTariff.objects.filter(abon=abon).order_by('tariff_priority') - - warntext='' - if int(gid) != abon.group.id: - warntext = 'Группа абонента не совпадает с переданным номером группы' + abon_tarifs = models.AbonTariff.objects.filter(abon=uid) + active_abontariff = abon_tarifs.exclude(time_start=None) return render(request, 'abonapp/services.html', { - 'warntext': warntext, 'abon': abon, 'abon_tarifs': abon_tarifs, - 'active_abontariff_id': abon_tarifs[0].id if abon_tarifs.count() > 0 else None, + 'active_abontariff_id': active_abontariff[0].id if active_abontariff.count() > 0 else None, 'abon_group': abon.group }) @@ -275,7 +271,7 @@ def terminal_pay(request): abon.add_ballance(kernel_user, amount) - abon.save() + abon.save(update_fields=['ballance']) return HttpResponse('ok') @@ -334,7 +330,8 @@ def buy_tariff(request, gid, uid): warntext = e.value except NetExcept as e: - warntext = e.value + warntext = e.value+u', но услуга уже подключена, она будет применена когда будет восстановлен доступ к NAS серверу.'\ + u' Вернуться' % resolve_url('abonhome_link', gid=gid, uid=abon.id) return render(request, 'abonapp/buy_tariff.html', { 'warntext': warntext, @@ -364,39 +361,20 @@ def chpriority(request, gid, uid): @mydefs.only_admins def complete_service(request, gid, uid, srvid): abtar = get_object_or_404(models.AbonTariff, id=srvid) - abon_group = get_object_or_404(models.AbonGroup, id=gid) if abtar.abon.id != int(uid): return HttpResponse('

uid not equal uid from service

') try: if request.method == 'POST': - abon = abtar.abon # досрочно завершаем услугу - try: - # пробуем активировать следующую услугу - abtar.finish_and_activate_next_tariff(request.user) - - except models.LogicError: - # Значит у абонента нет следующих услуг. Игнорим, далее в tariff.manage_access() всё разрулится - pass - - # завершаем текущую услугу. - abtar.delete() - - # Переупорядочиваем приоритеты - models.AbonTariff.objects.update_priorities(abon) - - return redirect('abonhome_link', gid, uid) - - next_tariff = models.AbonTariff.objects.filter( - abon=abtar.abon, - tariff_priority__gt=abtar.tariff_priority - )[:1] - - if not abtar.time_start: - abtar.time_start = timezone.now() - abtar.save() + finish_confirm = request.POST.get('finish_confirm') + if finish_confirm == 'yes': + # удаляем запись о текущей услуге. + abtar.delete() + return redirect('abonhome_link', gid, uid) + else: + raise models.LogicError('Действие не подтверждено') time_use = timezone.now() - abtar.time_start time_use = { @@ -407,9 +385,8 @@ def complete_service(request, gid, uid, srvid): return render(request, 'abonapp/complete_service.html', { 'abtar': abtar, 'abon': abtar.abon, - 'next_tariff': next_tariff[0] if next_tariff.count() > 0 else None, 'time_use': time_use, - 'abon_group': abon_group + 'abon_group': get_object_or_404(models.AbonGroup, id=gid) }) except models.LogicError as e: @@ -422,10 +399,39 @@ def complete_service(request, gid, uid, srvid): 'abtar': abtar, 'abon': abtar.abon, 'warntext': warntext, - 'abon_group': abon_group + 'abon_group': get_object_or_404(models.AbonGroup, id=gid) + }) + + +@login_required +@mydefs.only_admins +def activate_service(request, gid, uid, srvid): + abtar = get_object_or_404(models.AbonTariff, id=srvid) + + if request.method == 'POST': + if request.POST.get('finish_confirm') != 'yes': + return HttpResponse('

Request not confirmed

') + + abtar.activate(request.user) + return redirect('abonhome_link', gid, uid) + + amount = abtar.calc_amount_service() + return render(request, 'abonapp/activate_service.html', { + 'abon': abtar.abon, + 'abon_group': abtar.abon.group, + 'abtar': abtar, + 'amount': amount, + 'diff': abtar.abon.ballance - amount }) +@login_required +@mydefs.only_admins +def unsubscribe_service(request, gid, uid, srvid): + get_object_or_404(models.AbonTariff, id=int(srvid)).delete() + return redirect('abonhome_link', gid=gid, uid=uid) + + @login_required @mydefs.only_admins def log_page(request): @@ -438,6 +444,21 @@ def log_page(request): }) +@login_required +@mydefs.only_admins +def debtors(request): + #peoples_list = models.Abon.objects.filter(invoiceforpayment__status=True) + #peoples_list = mydefs.pag_mn(request, peoples_list) + + invs = models.InvoiceForPayment.objects.filter(status=True) + invs = mydefs.pag_mn(request, invs) + + return render(request, 'abonapp/debtors.html', { + #'peoples': peoples_list + 'invoices': invs + }) + + # API's def abons(request): diff --git a/accounts_app/views.py b/accounts_app/views.py index f9bc279..9a2edb7 100644 --- a/accounts_app/views.py +++ b/accounts_app/views.py @@ -20,6 +20,7 @@ def home(request): def to_signin(request): nextl = request.GET.get('next') + nextl = '' if nextl == 'None' or nextl is None or nextl.isspace() else nextl try: if request.POST: @@ -27,7 +28,7 @@ def to_signin(request): if auser: login(request, auser) if nextl == 'None' or nextl is None or nextl == '': - if request.user.is_admin: + if request.user.is_staff: return redirect('profile') return redirect('client_home') @@ -39,7 +40,6 @@ def to_signin(request): 'errmsg': u'Неправильный логин или пароль, попробуйте ещё раз' }) return render(request, 'accounts/login.html', { - 'csrf_token': csrf(request)['csrf_token'], 'next': nextl }) except NoReverseMatch: diff --git a/agent/main.py b/agent/main.py index 10ba01d..eb3cb4e 100644 --- a/agent/main.py +++ b/agent/main.py @@ -30,7 +30,8 @@ def create_abon(tariffs, users, event, frw): trf ) users.append(abon) - frw.open_inet_door(abon) + if abon.is_access(): + frw.open_inet_door(abon) def main(debug=False): @@ -44,9 +45,8 @@ def main(debug=False): # Открываем доступ в инет тем кто активен и у кого подключён тариф for usr in filter(lambda usr: usr.is_active, users): - # Доступ в интернет происходит по наличию подключённого тарифа - # если тарифа нет, то и инета нет - if usr.tariff: + # даём услуги если можно + if usr.is_access(): # Открываем доступ в инет frw.open_inet_door(usr) if debug: print "Разрешён доступ в инет для:", usr.ip_str() @@ -55,8 +55,7 @@ def main(debug=False): ts = TransmitServer('127.0.0.1', 2134) ts.start() - if debug: - print("Загружено %d абонентов" % len(users)) + if debug: print("Загружено %d абонентов" % len(users)) while True: # Загружаем события для абонентов из сети (список объектов EventNAS из models) @@ -77,20 +76,15 @@ def main(debug=False): elif toa == 2: print('SIGNAL: Change abon') usr = filter_user_by_id(users, event.id) + # если есть то меняем инфу о клиенте if usr: usr.deserialize(event.dt, tariffs) - ############################## - # НАДО УБЕДИТЬСЯ ЧТО ИЗМЕНЕНИЯ ЗАТРОНУТ ЭЛЕМЕНТ usr В ГЛОБАЛЬНОМ СПИСКЕ - ############################## - # если абонент активен, и куплен и активирован тариф то можно и в инет - if usr.is_active and usr.tariff is not None: - frw.close_inet_door(usr) + # в любом случае сначала очистить всю инфу о клиенте из таблицы фаера + frw.close_inet_door(usr) + # если у абонента есть доступ то можно и в инет + if usr.is_access(): frw.open_inet_door(usr) - - # DEBUG убеждаемся в изменениях - usr_dbg = filter_user_by_id(users, event.id) - assert usr.uid == usr_dbg.uid - assert usr.ip == usr_dbg.ip + # Иначе создаём клиента else: create_abon(tariffs, users, event, frw) diff --git a/agent/models.py b/agent/models.py index a5c3ac4..eec07c4 100644 --- a/agent/models.py +++ b/agent/models.py @@ -80,13 +80,14 @@ class Abonent(Serializer): # Включён-ли абонент is_active = True - def __init__(self, uid=None, ip=None, tariff=None): + def __init__(self, uid=None, ip=None, tariff=None, is_active=True): # none потому что может инициализироваться пустым, чтоб быть распакованным через deserialize() if tariff: assert isinstance(tariff, Tariff) self.ip = ip self.uid = uid self.tariff = tariff + self.is_active = is_active def ip_str(self): return socket.inet_ntoa(struct.pack("!I", self.ip)) @@ -94,7 +95,7 @@ class Abonent(Serializer): def _serializable_obj(self): return { 'id': self.uid, - 'is_active': self.is_active, + 'is_active': bool(self.is_active), 'ip': self.ip, 'tarif_id': self.tariff.tid if self.tariff else 0 } @@ -117,6 +118,14 @@ class Abonent(Serializer): self.tariff = None return self + def is_access(self): + # Доступ в интернет происходит по наличию подключённого тарифа + # если тарифа нет, то и инета нет + if self.is_active and self.tariff is not None: + return True + else: + return False + class EventNAS(Serializer): diff --git a/agent/sslTransmitter.py b/agent/sslTransmitter.py index 1ffb302..084d5b4 100644 --- a/agent/sslTransmitter.py +++ b/agent/sslTransmitter.py @@ -77,7 +77,8 @@ def agent_abon_typer(fn): abn = Abonent( abon.id, abon.ip_address.int_ip() if abon.ip_address else 0, - agent_tariff + agent_tariff, + abon.is_active ) fn(self, abn) return wrapped @@ -187,7 +188,7 @@ class PlainTransmitterClient(SSLTransmitterClient): port or settings.SELF_PORT )) except socket.error: - raise NetExcept('Ошибка подключения к NAS агенту на %s:%d' % ( + raise NetExcept(u'Ошибка подключения к NAS агенту на %s:%d' % ( ip or settings.SELF_IP, port or settings.SELF_PORT )) diff --git a/clientsideapp/views.py b/clientsideapp/views.py index d6a613a..8122b05 100644 --- a/clientsideapp/views.py +++ b/clientsideapp/views.py @@ -1,5 +1,8 @@ from django.contrib.auth.decorators import login_required -from django.shortcuts import render +from django.shortcuts import render, get_object_or_404 +from abonapp.models import AbonLog, AbonTariff +from tariff_app.models import Tariff +from mydefs import pag_mn @login_required @@ -9,9 +12,24 @@ def home(request): @login_required def pays(request): - return render(request, 'clientsideapp/pays.html') + pay_history = AbonLog.objects.filter(abon=request.user).order_by('-id') + pay_history = pag_mn(request, pay_history) + return render(request, 'clientsideapp/pays.html', { + 'pay_history': pay_history + }) @login_required def buy_service(request): - return render(request, 'clientsideapp/buy.html') + all_tarifs = Tariff.objects.all() + + own_abon_tariffs = AbonTariff.objects.filter(abon_id=request.user.id) + + current_service = own_abon_tariffs.exclude(time_start=None) + current_service = current_service[0] if current_service.count() > 0 else None + + return render(request, 'clientsideapp/buy.html', { + 'tarifs': all_tarifs, + 'own_abon_tariffs': own_abon_tariffs, + 'current_service': current_service + }) diff --git a/djing/settings_example.py b/djing/settings_example.py index 3155f4b..9bf2cec 100644 --- a/djing/settings_example.py +++ b/djing/settings_example.py @@ -9,7 +9,7 @@ from django.core.urlresolvers import reverse_lazy # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '$xvppe_5&iu4fgnt2h@eie6+w*n&m=60e7k_6hb5r4rgnfndz1' +SECRET_KEY = '!!!!!!!!!!!!!!!!!!!!!!!!YOUR SECRET KEY!!!!!!!!!!!!!!!!!!!!!!!!' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -64,8 +64,9 @@ TEMPLATES = [ 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', - 'mydefs.context_processor_client_ipaddress', - 'taskapp.context_proc.get_active_tasks_count' + 'global_context_processors.context_processor_client_ipaddress', + 'taskapp.context_proc.get_active_tasks_count', + 'global_context_processors.context_processor_additional_profile' ], }, }, @@ -108,6 +109,9 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +SESSION_ENGINE = 'django.contrib.sessions.backends.file' + +SESSION_COOKIE_HTTPONLY = True # Internationalization # https://docs.djangoproject.com/en/1.9/topics/i18n/ diff --git a/djing/views.py b/djing/views.py index 776ac0f..c5c7389 100644 --- a/djing/views.py +++ b/djing/views.py @@ -4,7 +4,7 @@ from django.shortcuts import redirect @login_required def home(request): - if request.user.is_admin: + if request.user.is_staff: return redirect('profile') else: return redirect('client_home') diff --git a/global_context_processors.py b/global_context_processors.py new file mode 100644 index 0000000..50577ce --- /dev/null +++ b/global_context_processors.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from abonapp.models import Abon +from django.shortcuts import get_object_or_404 + + +def context_processor_client_ipaddress(request): + ip = request.META.get('REMOTE_ADDR', '') or request.META.get('HTTP_X_FORWARDED_FOR', '') + return { + 'client_ipaddress': ip + } + + +# От сюда можно получать на клиентской стороне профиль абонента +def context_processor_additional_profile(request): + if request.user.is_staff or request.user.is_anonymous(): + return {'subscriber': request.user} + else: + return {'subscriber': get_object_or_404(Abon, id=request.user.id)} diff --git a/mydefs.py b/mydefs.py index ab49176..5c586e9 100644 --- a/mydefs.py +++ b/mydefs.py @@ -55,14 +55,6 @@ def pag_mn(request, objs, count_per_page=10): return objs -def context_processor_client_ipaddress(request): - ip = request.META.get('REMOTE_ADDR', '') or request.META.get('HTTP_X_FORWARDED_FOR', '') - return { - 'client_ipaddress': ip - } - #logmodels.debug('%s %s %s'%(request.user, request.path, ip)) - - class MyGenericIPAddressField(models.GenericIPAddressField): description = "Int32 notation ip address" diff --git a/privatemessage/models.py b/privatemessage/models.py index d90b378..54959c7 100644 --- a/privatemessage/models.py +++ b/privatemessage/models.py @@ -1,5 +1,5 @@ from django.db import models -from djing import settings +from django.conf import settings class MessagesManager(models.Manager): diff --git a/tariff_app/forms.py b/tariff_app/forms.py index 5ff8235..f49afd5 100644 --- a/tariff_app/forms.py +++ b/tariff_app/forms.py @@ -8,6 +8,7 @@ class TariffForm(forms.ModelForm): fields = '__all__' widgets = { 'title': forms.TextInput(attrs={'class': 'form-control'}), + 'descr': forms.TextInput(attrs={'class': 'form-control'}), 'speedIn': forms.NumberInput(attrs={'class': 'form-control'}), 'speedOut': forms.NumberInput(attrs={'class': 'form-control'}), 'amount': forms.NumberInput(attrs={'class': 'form-control'}), diff --git a/tariff_app/models.py b/tariff_app/models.py index f48fecb..b059049 100644 --- a/tariff_app/models.py +++ b/tariff_app/models.py @@ -16,6 +16,7 @@ class _TariffChoicesAdapter(MyChoicesAdapter): class Tariff(models.Model): title = models.CharField(max_length=32) + descr = models.CharField(max_length=256) speedIn = models.FloatField(default=0.0) speedOut = models.FloatField(default=0.0) amount = models.FloatField(default=0.0) diff --git a/tariff_app/views.py b/tariff_app/views.py index ddf9bc8..b4d6ba9 100644 --- a/tariff_app/views.py +++ b/tariff_app/views.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from django.contrib.auth.decorators import login_required from django.shortcuts import render, get_object_or_404, redirect -from django.template.context_processors import csrf from models import Tariff import mydefs import forms @@ -48,7 +47,6 @@ def edit_tarif(request, tarif_id=0): return render(request, 'tariff_app/editTarif.html', { 'warntext': warntext, - 'csrf_token': csrf(request)['csrf_token'], 'form': frm, 'tarif_id': tarif_id }) diff --git a/taskapp/models.py b/taskapp/models.py index 0faa9b2..3d79bd4 100644 --- a/taskapp/models.py +++ b/taskapp/models.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.db import models -from djing import settings +from django.conf import settings from devapp.models import Device from datetime import datetime, timedelta diff --git a/taskapp/urls.py b/taskapp/urls.py index e3c8a71..5f1a4fd 100644 --- a/taskapp/urls.py +++ b/taskapp/urls.py @@ -10,5 +10,6 @@ urlpatterns = [ url(r'^add$', views.task_add_edit, name='task_add'), url(r'^active$', views.active_tasks, name='active_tasks'), url(r'^finished$', views.finished_tasks, name='finished_tasks'), + url(r'^own$', views.own_tasks, name='own_tasks'), url(r'^all$', views.all_tasks, name='all_tasks') ] diff --git a/taskapp/views.py b/taskapp/views.py index b7a475f..c8cda85 100644 --- a/taskapp/views.py +++ b/taskapp/views.py @@ -44,6 +44,16 @@ def finished_tasks(request): }) +@login_required +@only_admins +def own_tasks(request): + tasks = Task.objects.filter(author=request.user).exclude(state='F') # Назначенные мной и не законченная + tasks = pag_mn(request, tasks) + return render(request, 'taskapp/tasklist_own.html', { + 'tasks': tasks + }) + + @login_required @only_admins def all_tasks(request): diff --git a/templates/abonapp/activate_service.html b/templates/abonapp/activate_service.html new file mode 100644 index 0000000..44a0c5c --- /dev/null +++ b/templates/abonapp/activate_service.html @@ -0,0 +1,36 @@ +{% extends request.is_ajax|yesno:'bajax.html,base.html' %} +{% block main %} + + + + + +
+
+

Активировать услугу

+
+
+ {% if warntext %} +
{{ warntext }}
+ {% endif %} +
{% csrf_token %} + + +

Вы уверены что хотите активировать абоненту эту услугу?
+ Обратите внимание что с его счёта снимутся деньги и откроется доступ к ресурсам оплаченной услуги.
+ Стоимость услуги: {{ amount }}руб. На счету {{ abon.ballance }} руб, останется {{ diff }} руб.

+ + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/templates/abonapp/buy_tariff.html b/templates/abonapp/buy_tariff.html index 645c3fa..08b1043 100644 --- a/templates/abonapp/buy_tariff.html +++ b/templates/abonapp/buy_tariff.html @@ -20,7 +20,7 @@ {% if warntext %}
- Внимание! {{ warntext }} + Внимание! {{ warntext|safe }}
{% endif %}
{% csrf_token %} diff --git a/templates/abonapp/complete_service.html b/templates/abonapp/complete_service.html index c7f2448..b53beae 100644 --- a/templates/abonapp/complete_service.html +++ b/templates/abonapp/complete_service.html @@ -23,23 +23,13 @@ {% csrf_token %} -

Досрочное завершение текущей услуги приведёт к тому что на счёт вернуться деньги за неиспользованные - ресурсы согласно тарифного плана, и подключится следующий по списку заказанный тарифный план, если он есть. Если больше услуг нет то доступ - в сеть будет закрыт.
- Это значит, что если тариф стоит 300 и модуль расчёта по тарифу сказал что использовано ресурсов было на 200, то на счёт вернётся 100. - Или если модуль вернёт 300 то на счёт ничего не вернётся. Вы так же можете создавать свою логику расчёта по тарифу, читайте документацию

+

Досрочное завершение текущей услуги приведёт к тому что пользователю будет запрещён доступ к ресурсам услуги (закроется инет)
+ Для продолжения пользования ресурсами надо подключить нужную услугу

Подробнее:
Вы завершаете тариф {{ abtar.tariff.title }}.
- {% if next_tariff %} - Следующим будет подключен - {{ next_tariff.tariff.title }}.
- {% else %} - Больше заказанных тарифов нет, а значит доступ в интернет для абонента будет закрыт. - {% endif %}
- - Время начала: {{ abtar.time_start|date:'d F Y, H:i:s' }}
+ Услуга была подключена: {{ abtar.time_start|date:'d F Y, H:i:s' }}
Сегодня: {% now "d F Y, H:i:s" %}
Время использования: {% if time_use.days %}{{ time_use.days }} дней.{% endif %} {{ time_use.hours }} часов и {{ time_use.minutes }} минут.
diff --git a/templates/abonapp/debtors.html b/templates/abonapp/debtors.html new file mode 100644 index 0000000..1392ce3 --- /dev/null +++ b/templates/abonapp/debtors.html @@ -0,0 +1,48 @@ +{% extends 'base.html' %} +{% block main %} + + +

+ + +

Народ, у которого есть неоплаченные услуги

+
+ + + + + + + + + + + + + {% for invoice in invoices %} + + + + + + + + + {% empty %} + + + + {% endfor %} + +
#АбонентЦенаКомментарийДата созданияАвтор
{{ invoice.id }}{{ invoice.abon.username }}{{ invoice.amount }}{{ invoice.comment}}{{ invoice.date_create|date:'d b H:i' }}{{ invoice.author.username }}
+ Нет должников +
+
+ + {% include 'toolbar_page.html' with pag=peoples %} + +{% endblock %} \ No newline at end of file diff --git a/templates/abonapp/ext.htm b/templates/abonapp/ext.htm index 0168511..bc7f8b2 100644 --- a/templates/abonapp/ext.htm +++ b/templates/abonapp/ext.htm @@ -16,7 +16,8 @@ {% endif %} - Ваш балланс 126 руб. + Ваш балланс {{ subscriber.ballance }} руб. @@ -72,12 +72,21 @@
+ + {% if request.user.is_staff %} +
+ Кстати. + Вы администратор, и не должны производить действия из кабинета пользователя, производите их из админки. + Кабинет клиента для вас только для ознакомления. +
+ {% endif %} + {% block client_main %}{% endblock %}
diff --git a/templates/clientsideapp/pays.html b/templates/clientsideapp/pays.html index 468ba68..161df61 100644 --- a/templates/clientsideapp/pays.html +++ b/templates/clientsideapp/pays.html @@ -9,17 +9,19 @@ Сумма транзакции (руб) Дата транзакции - Автор платежа Комментарий + {% for pay in pay_history %} - 100 - 08 Сентябрь 2016, 02:30:40 - bashmak - Покупка тарифного плана через админку, тариф "New2" + {{ pay.amount }} + {{ pay.date|date:'d b H:i' }} + {{ pay.comment }} + {% empty %} + У вас нет проведённых платежей + {% endfor %} diff --git a/templates/tariff_app/editTarif.html b/templates/tariff_app/editTarif.html index 1ae8505..1ffc6f6 100644 --- a/templates/tariff_app/editTarif.html +++ b/templates/tariff_app/editTarif.html @@ -33,6 +33,14 @@ +
+ +
+ + {{ form.descr }}{{ form.descr.errors }} +
+
+
diff --git a/templates/taskapp/ext.htm b/templates/taskapp/ext.htm index a0997f8..b4da38a 100644 --- a/templates/taskapp/ext.htm +++ b/templates/taskapp/ext.htm @@ -35,9 +35,14 @@ Выполненные задачи +
  • + + Назначенные мной задачи + +
  • - Все задачи + Все мои задачи
  • diff --git a/templates/taskapp/tasklist_own.html b/templates/taskapp/tasklist_own.html new file mode 100644 index 0000000..716aabe --- /dev/null +++ b/templates/taskapp/tasklist_own.html @@ -0,0 +1,63 @@ +{% extends request.is_ajax|yesno:'nullcont.htm,taskapp/ext.htm' %} +{% block content %} + +
    + + + + + + + + + + + + + + {% for task in tasks %} + + {% if task.priority == 'E' %} + {% elif task.priority == 'D' %} + {% elif task.priority == 'C' %} + {% elif task.priority == 'B' %} + {% elif task.priority == 'A' %} + {% else %}{% endif %} + + + + + + + + + + + {% empty %} + + + + {% endfor %} + + + + + + +
    #Пару слов..Кому назначенаСостояниеПриоритетВремя выполненияДата созданияДействия
    {{ task.id }}{{ task.descr }}{{ task.recipient.username }}{{ task.get_state_display }}{{ task.get_priority_display }}{{ task.out_date|date:'d N yг' }}{{ task.time_of_create|date:'d N yг H:i:s' }} + + + + + + +
    Все ваши задачи выполнены
    + + + +
    +
    + + {% include 'toolbar_page.html' with pag=tasks %} + +{% endblock %}