Browse Source

всё пишу..

devel
Dmitry 9 years ago
parent
commit
2ea3751aae
  1. 119
      abonapp/models.py
  2. 2
      abonapp/urls.py
  3. 5
      abonapp/urls_abon.py
  4. 95
      abonapp/views.py
  5. 4
      accounts_app/views.py
  6. 24
      agent/main.py
  7. 13
      agent/models.py
  8. 5
      agent/sslTransmitter.py
  9. 24
      clientsideapp/views.py
  10. 10
      djing/settings_example.py
  11. 2
      djing/views.py
  12. 18
      global_context_processors.py
  13. 8
      mydefs.py
  14. 2
      privatemessage/models.py
  15. 1
      tariff_app/forms.py
  16. 1
      tariff_app/models.py
  17. 2
      tariff_app/views.py
  18. 2
      taskapp/models.py
  19. 1
      taskapp/urls.py
  20. 10
      taskapp/views.py
  21. 36
      templates/abonapp/activate_service.html
  22. 2
      templates/abonapp/buy_tariff.html
  23. 16
      templates/abonapp/complete_service.html
  24. 48
      templates/abonapp/debtors.html
  25. 3
      templates/abonapp/ext.htm
  26. 3
      templates/abonapp/group_list.html
  27. 27
      templates/abonapp/services.html
  28. 2
      templates/accounts/index.html
  29. 8
      templates/base.html
  30. 79
      templates/clientsideapp/buy.html
  31. 15
      templates/clientsideapp/ext.html
  32. 12
      templates/clientsideapp/pays.html
  33. 8
      templates/tariff_app/editTarif.html
  34. 7
      templates/taskapp/ext.htm
  35. 63
      templates/taskapp/tasklist_own.html

119
abonapp/models.py

@ -4,11 +4,11 @@ from django.http import Http404
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils import timezone from django.utils import timezone
from django.utils.datetime_safe import datetime 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 ip_pool.models import IpPoolItem
from tariff_app.models import Tariff from tariff_app.models import Tariff
from django.db import models from django.db import models
from djing import settings
from django.conf import settings
from django.core.validators import DecimalValidator from django.core.validators import DecimalValidator
from accounts_app.models import UserProfile from accounts_app.models import UserProfile
@ -63,7 +63,7 @@ class AbonTariffManager(models.Manager):
for at in abon_tariff_list: for at in abon_tariff_list:
at.tariff_priority = at_pr at.tariff_priority = at_pr
at_pr += 1 at_pr += 1
at.save()
at.save(update_fields=['tariff_priority'])
class AbonTariff(models.Model): class AbonTariff(models.Model):
@ -103,9 +103,9 @@ class AbonTariff(models.Model):
# Swap приоритетов у текущего и найденного с меньшим tariff_priority (большим приоритетом) # Swap приоритетов у текущего и найденного с меньшим tariff_priority (большим приоритетом)
tmp_prior = target_abtar.tariff_priority tmp_prior = target_abtar.tariff_priority
target_abtar.tariff_priority = self.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.tariff_priority = tmp_prior
self.save()
self.save(update_fields=['tariff_priority'])
def priority_down(self): def priority_down(self):
# ищем услугу с меньшим приоритетом # ищем услугу с меньшим приоритетом
@ -123,8 +123,8 @@ class AbonTariff(models.Model):
tmp_pr = self.tariff_priority tmp_pr = self.tariff_priority
self.tariff_priority = target_abtar.tariff_priority self.tariff_priority = target_abtar.tariff_priority
target_abtar.tariff_priority = tmp_pr 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): def calc_amount_service(self):
@ -133,33 +133,21 @@ class AbonTariff(models.Model):
amount = calc_obj.calc_amount(self) amount = calc_obj.calc_amount(self)
return round(amount, 2) 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()
# Активируем тариф
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()
#теперь к текущему баллансу добавляем сумму не потраченных ресурсов, т.к. полная сумма тарифа списывается при покупке тарифа
ret_amount = self.tariff.amount - used_services
self.abon.ballance += ret_amount
self.abon.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): def __unicode__(self):
return "%d: '%s' - '%s'" % ( return "%d: '%s' - '%s'" % (
@ -184,11 +172,11 @@ class Abon(UserProfile):
_act_tar_cache = None _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 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: if ats.count() > 0:
self._act_tar_cache = ats[0].tariff self._act_tar_cache = ats[0].tariff
@ -217,6 +205,7 @@ class Abon(UserProfile):
class Meta: class Meta:
db_table = 'abonent' db_table = 'abonent'
# Платим за что-то
def make_pay(self, curuser, how_match_to_pay=0.0): def make_pay(self, curuser, how_match_to_pay=0.0):
AbonLog.objects.create( AbonLog.objects.create(
abon = self, abon = self,
@ -226,6 +215,7 @@ class Abon(UserProfile):
) )
self.ballance -= how_match_to_pay self.ballance -= how_match_to_pay
# Пополняем счёт
def add_ballance(self, current_user, amount): def add_ballance(self, current_user, amount):
AbonLog.objects.create( AbonLog.objects.create(
abon = self, abon = self,
@ -235,13 +225,9 @@ class Abon(UserProfile):
) )
self.ballance += amount self.ballance += amount
# покупаем тариф
def buy_tariff(self, tariff, author): def buy_tariff(self, tariff, author):
if self.ballance >= tariff.amount:
# денег достаточно, можно покупать
self.ballance -= tariff.amount
# Пытаемся подключиться к NAS агенту
tc = get_TransmitterClientKlass()()
assert isinstance(tariff, Tariff)
# выбераем связь ТарифАбонент с самым низким приоритетом # выбераем связь ТарифАбонент с самым низким приоритетом
abtrf = AbonTariff.objects.filter(abon=self).order_by('-tariff_priority')[:1] abtrf = AbonTariff.objects.filter(abon=self).order_by('-tariff_priority')[:1]
@ -261,29 +247,12 @@ class Abon(UserProfile):
new_abtar.save() 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( AbonLog.objects.create(
abon = self, amount = -tariff.amount, abon = self, amount = -tariff.amount,
author = author, author = author,
comment = u'Покупка тарифного плана через админку, тариф "%s"' % tariff.title comment = u'Покупка тарифного плана через админку, тариф "%s"' % tariff.title
) )
else:
raise LogicError(u'Недостаточно денег на счету абонента')
# Пробует подключить новую услугу если пришло время # Пробует подключить новую услугу если пришло время
def activate_next_tariff(self, author): def activate_next_tariff(self, author):
@ -292,8 +261,8 @@ class Abon(UserProfile):
nw = datetime.now(tz=timezone.get_current_timezone()) nw = datetime.now(tz=timezone.get_current_timezone())
for at in ats: for at in ats:
# Если времени активации нет, то это ещё не активированный тариф
if not at.time_start:
# Если активированный тариф
if not at.is_started():
return return
# время к началу месяца # время к началу месяца
@ -363,15 +332,15 @@ class InvoiceForPayment(models.Model):
def abon_post_save(sender, instance, **kwargs): def abon_post_save(sender, instance, **kwargs):
if kwargs['created']: if kwargs['created']:
print 'abon_pre_save CREATED'
print 'abon_post_save CREATED'
else: else:
print 'abon_pre_save CHANGED'
# подключение к NAS'у в начале для того чтоб если исключение то ничего не сохранялось и сразу показать ошибку
print 'abon_post_save CHANGED'
tc = get_TransmitterClientKlass()() tc = get_TransmitterClientKlass()()
# обновляем абонента на NAS # обновляем абонента на NAS
tc.signal_abon_refresh(instance) tc.signal_abon_refresh(instance)
def abon_del_signal(sender, instance, **kwargs): def abon_del_signal(sender, instance, **kwargs):
print 'abon_del_signal' print 'abon_del_signal'
# подключаемся к NAS'у # подключаемся к NAS'у
@ -388,14 +357,24 @@ def abon_del_signal(sender, instance, **kwargs):
#tc = get_TransmitterClientKlass()()''' #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_save.connect(abon_post_save, sender=Abon)
models.signals.post_delete.connect(abon_del_signal, 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)

2
abonapp/urls.py

@ -15,6 +15,8 @@ urlpatterns = [
url(r'^pay$', views.terminal_pay, name='abonapp_terminalpay_link'), url(r'^pay$', views.terminal_pay, name='abonapp_terminalpay_link'),
url(r'^debtors$', views.debtors, name='abonapp_debtors'),
# Api's # Api's
url(r'^api/abons$', views.abons) url(r'^api/abons$', views.abons)

5
abonapp/urls_abon.py

@ -15,5 +15,8 @@ urlpatterns = [
url(r'^(?P<uid>\d+)/addinvoice$', views.add_invoice, name='abonapp_addinvoice_link'), url(r'^(?P<uid>\d+)/addinvoice$', views.add_invoice, name='abonapp_addinvoice_link'),
url(r'^(?P<uid>\d+)/buy$', views.buy_tariff, name='abonapp_buy_tariff'), url(r'^(?P<uid>\d+)/buy$', views.buy_tariff, name='abonapp_buy_tariff'),
url(r'^(?P<uid>\d+)/chpriority$', views.chpriority, name='abonapp_chpriority_tariff'), url(r'^(?P<uid>\d+)/chpriority$', views.chpriority, name='abonapp_chpriority_tariff'),
url(r'^(?P<uid>\d+)/complete_service_(?P<srvid>\d+)$', views.complete_service, name='abonapp_compl_srv'),
url(r'^(?P<uid>\d+)/complete_service(?P<srvid>\d+)$', views.complete_service, name='abonapp_compl_srv'),
url(r'^(?P<uid>\d+)/activate_service(?P<srvid>\d+)$', views.activate_service, name='abonapp_activate_service'),
url(r'^(?P<uid>\d+)/unsubscribe_service(?P<srvid>\d+)$', views.unsubscribe_service, name='abonapp_unsubscribe_service')
] ]

95
abonapp/views.py

@ -152,7 +152,7 @@ def abonamount(request, gid, uid):
if abonid == int(uid): if abonid == int(uid):
amnt = mydefs.safe_float(request.POST.get('amount')) amnt = mydefs.safe_float(request.POST.get('amount'))
abon.add_ballance(request.user, amnt) abon.add_ballance(request.user, amnt)
abon.save()
abon.save(update_fields=['ballance'])
return redirect('abonhome_link', gid=gid, uid=uid) return redirect('abonhome_link', gid=gid, uid=uid)
else: else:
warning_text = u'Не правильно выбран абонент как цель для пополнения' warning_text = u'Не правильно выбран абонент как цель для пополнения'
@ -193,18 +193,14 @@ def pay_history(request, gid, uid):
@mydefs.only_admins @mydefs.only_admins
def abon_services(request, gid, uid): def abon_services(request, gid, uid):
abon = get_object_or_404(models.Abon, id=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', { return render(request, 'abonapp/services.html', {
'warntext': warntext,
'abon': abon, 'abon': abon,
'abon_tarifs': abon_tarifs, '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 'abon_group': abon.group
}) })
@ -275,7 +271,7 @@ def terminal_pay(request):
abon.add_ballance(kernel_user, amount) abon.add_ballance(kernel_user, amount)
abon.save()
abon.save(update_fields=['ballance'])
return HttpResponse('ok') return HttpResponse('ok')
@ -334,7 +330,8 @@ def buy_tariff(request, gid, uid):
warntext = e.value warntext = e.value
except NetExcept as e: except NetExcept as e:
warntext = e.value
warntext = e.value+u', но услуга уже подключена, она будет применена когда будет восстановлен доступ к NAS серверу.'\
u' <a href="%s">Вернуться</a>' % resolve_url('abonhome_link', gid=gid, uid=abon.id)
return render(request, 'abonapp/buy_tariff.html', { return render(request, 'abonapp/buy_tariff.html', {
'warntext': warntext, 'warntext': warntext,
@ -364,39 +361,20 @@ def chpriority(request, gid, uid):
@mydefs.only_admins @mydefs.only_admins
def complete_service(request, gid, uid, srvid): def complete_service(request, gid, uid, srvid):
abtar = get_object_or_404(models.AbonTariff, id=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): if abtar.abon.id != int(uid):
return HttpResponse('<h1>uid not equal uid from service</h1>') return HttpResponse('<h1>uid not equal uid from service</h1>')
try: try:
if request.method == 'POST': if request.method == 'POST':
abon = abtar.abon
# досрочно завершаем услугу # досрочно завершаем услугу
try:
# пробуем активировать следующую услугу
abtar.finish_and_activate_next_tariff(request.user)
except models.LogicError:
# Значит у абонента нет следующих услуг. Игнорим, далее в tariff.manage_access() всё разрулится
pass
# завершаем текущую услугу.
finish_confirm = request.POST.get('finish_confirm')
if finish_confirm == 'yes':
# удаляем запись о текущей услуге.
abtar.delete() abtar.delete()
# Переупорядочиваем приоритеты
models.AbonTariff.objects.update_priorities(abon)
return redirect('abonhome_link', gid, uid) 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()
else:
raise models.LogicError('Действие не подтверждено')
time_use = timezone.now() - abtar.time_start time_use = timezone.now() - abtar.time_start
time_use = { time_use = {
@ -407,9 +385,8 @@ def complete_service(request, gid, uid, srvid):
return render(request, 'abonapp/complete_service.html', { return render(request, 'abonapp/complete_service.html', {
'abtar': abtar, 'abtar': abtar,
'abon': abtar.abon, 'abon': abtar.abon,
'next_tariff': next_tariff[0] if next_tariff.count() > 0 else None,
'time_use': time_use, 'time_use': time_use,
'abon_group': abon_group
'abon_group': get_object_or_404(models.AbonGroup, id=gid)
}) })
except models.LogicError as e: except models.LogicError as e:
@ -422,10 +399,39 @@ def complete_service(request, gid, uid, srvid):
'abtar': abtar, 'abtar': abtar,
'abon': abtar.abon, 'abon': abtar.abon,
'warntext': warntext, '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('<h1>Request not confirmed</h1>')
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 @login_required
@mydefs.only_admins @mydefs.only_admins
def log_page(request): 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 # API's
def abons(request): def abons(request):

4
accounts_app/views.py

@ -20,6 +20,7 @@ def home(request):
def to_signin(request): def to_signin(request):
nextl = request.GET.get('next') nextl = request.GET.get('next')
nextl = '' if nextl == 'None' or nextl is None or nextl.isspace() else nextl
try: try:
if request.POST: if request.POST:
@ -27,7 +28,7 @@ def to_signin(request):
if auser: if auser:
login(request, auser) login(request, auser)
if nextl == 'None' or nextl is None or nextl == '': if nextl == 'None' or nextl is None or nextl == '':
if request.user.is_admin:
if request.user.is_staff:
return redirect('profile') return redirect('profile')
return redirect('client_home') return redirect('client_home')
@ -39,7 +40,6 @@ def to_signin(request):
'errmsg': u'Неправильный логин или пароль, попробуйте ещё раз' 'errmsg': u'Неправильный логин или пароль, попробуйте ещё раз'
}) })
return render(request, 'accounts/login.html', { return render(request, 'accounts/login.html', {
'csrf_token': csrf(request)['csrf_token'],
'next': nextl 'next': nextl
}) })
except NoReverseMatch: except NoReverseMatch:

24
agent/main.py

@ -30,6 +30,7 @@ def create_abon(tariffs, users, event, frw):
trf trf
) )
users.append(abon) users.append(abon)
if abon.is_access():
frw.open_inet_door(abon) frw.open_inet_door(abon)
@ -44,9 +45,8 @@ def main(debug=False):
# Открываем доступ в инет тем кто активен и у кого подключён тариф # Открываем доступ в инет тем кто активен и у кого подключён тариф
for usr in filter(lambda usr: usr.is_active, users): for usr in filter(lambda usr: usr.is_active, users):
# Доступ в интернет происходит по наличию подключённого тарифа
# если тарифа нет, то и инета нет
if usr.tariff:
# даём услуги если можно
if usr.is_access():
# Открываем доступ в инет # Открываем доступ в инет
frw.open_inet_door(usr) frw.open_inet_door(usr)
if debug: print "Разрешён доступ в инет для:", usr.ip_str() if debug: print "Разрешён доступ в инет для:", usr.ip_str()
@ -55,8 +55,7 @@ def main(debug=False):
ts = TransmitServer('127.0.0.1', 2134) ts = TransmitServer('127.0.0.1', 2134)
ts.start() ts.start()
if debug:
print("Загружено %d абонентов" % len(users))
if debug: print("Загружено %d абонентов" % len(users))
while True: while True:
# Загружаем события для абонентов из сети (список объектов EventNAS из models) # Загружаем события для абонентов из сети (список объектов EventNAS из models)
@ -77,20 +76,15 @@ def main(debug=False):
elif toa == 2: elif toa == 2:
print('SIGNAL: Change abon') print('SIGNAL: Change abon')
usr = filter_user_by_id(users, event.id) usr = filter_user_by_id(users, event.id)
# если есть то меняем инфу о клиенте
if usr: if usr:
usr.deserialize(event.dt, tariffs) 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) 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: else:
create_abon(tariffs, users, event, frw) create_abon(tariffs, users, event, frw)

13
agent/models.py

@ -80,13 +80,14 @@ class Abonent(Serializer):
# Включён-ли абонент # Включён-ли абонент
is_active = True 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() # none потому что может инициализироваться пустым, чтоб быть распакованным через deserialize()
if tariff: if tariff:
assert isinstance(tariff, Tariff) assert isinstance(tariff, Tariff)
self.ip = ip self.ip = ip
self.uid = uid self.uid = uid
self.tariff = tariff self.tariff = tariff
self.is_active = is_active
def ip_str(self): def ip_str(self):
return socket.inet_ntoa(struct.pack("!I", self.ip)) return socket.inet_ntoa(struct.pack("!I", self.ip))
@ -94,7 +95,7 @@ class Abonent(Serializer):
def _serializable_obj(self): def _serializable_obj(self):
return { return {
'id': self.uid, 'id': self.uid,
'is_active': self.is_active,
'is_active': bool(self.is_active),
'ip': self.ip, 'ip': self.ip,
'tarif_id': self.tariff.tid if self.tariff else 0 'tarif_id': self.tariff.tid if self.tariff else 0
} }
@ -117,6 +118,14 @@ class Abonent(Serializer):
self.tariff = None self.tariff = None
return self return self
def is_access(self):
# Доступ в интернет происходит по наличию подключённого тарифа
# если тарифа нет, то и инета нет
if self.is_active and self.tariff is not None:
return True
else:
return False
class EventNAS(Serializer): class EventNAS(Serializer):

5
agent/sslTransmitter.py

@ -77,7 +77,8 @@ def agent_abon_typer(fn):
abn = Abonent( abn = Abonent(
abon.id, abon.id,
abon.ip_address.int_ip() if abon.ip_address else 0, abon.ip_address.int_ip() if abon.ip_address else 0,
agent_tariff
agent_tariff,
abon.is_active
) )
fn(self, abn) fn(self, abn)
return wrapped return wrapped
@ -187,7 +188,7 @@ class PlainTransmitterClient(SSLTransmitterClient):
port or settings.SELF_PORT port or settings.SELF_PORT
)) ))
except socket.error: except socket.error:
raise NetExcept('Ошибка подключения к NAS агенту на %s:%d' % (
raise NetExcept(u'Ошибка подключения к NAS агенту на %s:%d' % (
ip or settings.SELF_IP, ip or settings.SELF_IP,
port or settings.SELF_PORT port or settings.SELF_PORT
)) ))

24
clientsideapp/views.py

@ -1,5 +1,8 @@
from django.contrib.auth.decorators import login_required 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 @login_required
@ -9,9 +12,24 @@ def home(request):
@login_required @login_required
def pays(request): 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 @login_required
def buy_service(request): 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
})

10
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/ # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! # 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! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
@ -64,8 +64,9 @@ TEMPLATES = [
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', '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 # Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/ # https://docs.djangoproject.com/en/1.9/topics/i18n/

2
djing/views.py

@ -4,7 +4,7 @@ from django.shortcuts import redirect
@login_required @login_required
def home(request): def home(request):
if request.user.is_admin:
if request.user.is_staff:
return redirect('profile') return redirect('profile')
else: else:
return redirect('client_home') return redirect('client_home')

18
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)}

8
mydefs.py

@ -55,14 +55,6 @@ def pag_mn(request, objs, count_per_page=10):
return objs 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): class MyGenericIPAddressField(models.GenericIPAddressField):
description = "Int32 notation ip address" description = "Int32 notation ip address"

2
privatemessage/models.py

@ -1,5 +1,5 @@
from django.db import models from django.db import models
from djing import settings
from django.conf import settings
class MessagesManager(models.Manager): class MessagesManager(models.Manager):

1
tariff_app/forms.py

@ -8,6 +8,7 @@ class TariffForm(forms.ModelForm):
fields = '__all__' fields = '__all__'
widgets = { widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}), 'title': forms.TextInput(attrs={'class': 'form-control'}),
'descr': forms.TextInput(attrs={'class': 'form-control'}),
'speedIn': forms.NumberInput(attrs={'class': 'form-control'}), 'speedIn': forms.NumberInput(attrs={'class': 'form-control'}),
'speedOut': forms.NumberInput(attrs={'class': 'form-control'}), 'speedOut': forms.NumberInput(attrs={'class': 'form-control'}),
'amount': forms.NumberInput(attrs={'class': 'form-control'}), 'amount': forms.NumberInput(attrs={'class': 'form-control'}),

1
tariff_app/models.py

@ -16,6 +16,7 @@ class _TariffChoicesAdapter(MyChoicesAdapter):
class Tariff(models.Model): class Tariff(models.Model):
title = models.CharField(max_length=32) title = models.CharField(max_length=32)
descr = models.CharField(max_length=256)
speedIn = models.FloatField(default=0.0) speedIn = models.FloatField(default=0.0)
speedOut = models.FloatField(default=0.0) speedOut = models.FloatField(default=0.0)
amount = models.FloatField(default=0.0) amount = models.FloatField(default=0.0)

2
tariff_app/views.py

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import render, get_object_or_404, redirect
from django.template.context_processors import csrf
from models import Tariff from models import Tariff
import mydefs import mydefs
import forms import forms
@ -48,7 +47,6 @@ def edit_tarif(request, tarif_id=0):
return render(request, 'tariff_app/editTarif.html', { return render(request, 'tariff_app/editTarif.html', {
'warntext': warntext, 'warntext': warntext,
'csrf_token': csrf(request)['csrf_token'],
'form': frm, 'form': frm,
'tarif_id': tarif_id 'tarif_id': tarif_id
}) })

2
taskapp/models.py

@ -2,7 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models from django.db import models
from djing import settings
from django.conf import settings
from devapp.models import Device from devapp.models import Device
from datetime import datetime, timedelta from datetime import datetime, timedelta

1
taskapp/urls.py

@ -10,5 +10,6 @@ urlpatterns = [
url(r'^add$', views.task_add_edit, name='task_add'), url(r'^add$', views.task_add_edit, name='task_add'),
url(r'^active$', views.active_tasks, name='active_tasks'), url(r'^active$', views.active_tasks, name='active_tasks'),
url(r'^finished$', views.finished_tasks, name='finished_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') url(r'^all$', views.all_tasks, name='all_tasks')
] ]

10
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 @login_required
@only_admins @only_admins
def all_tasks(request): def all_tasks(request):

36
templates/abonapp/activate_service.html

@ -0,0 +1,36 @@
{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'abongroup_list_link' %}">Группы абонентов</a></li>
<li><a href="{% url 'people_list_link' abon_group.id %}">{{ abon_group.title }}</a></li>
<li><a href="{% url 'abonhome_link' abon_group.id abon.id %}">{{ abon.fio }}</a></li>
<li class="active">Активировать услугу</li>
</ol>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Активировать услугу</h3>
</div>
<div class="panel-body">
{% if warntext %}
<div class="alert-danger">{{ warntext }}</div>
{% endif %}
<form role="form" action="{% url 'abonapp_activate_service' abon_group.id abon.id abtar.id %}" method="post">{% csrf_token %}
<input name="finish_confirm" value="yes" type="hidden">
<p>Вы уверены что хотите активировать абоненту эту услугу?<br>
Обратите внимание что с его счёта <b>снимутся деньги</b> и откроется доступ к ресурсам оплаченной услуги.<br>
Стоимость услуги: {{ amount }}руб. На счету {{ abon.ballance }} руб, останется {{ diff }} руб.</p>
<button type="submit" class="btn btn-sm btn-primary">
<span class="glyphicon glyphicon-save"></span> Подтвердить
</button>
</form>
</div>
</div>
{% endblock %}

2
templates/abonapp/buy_tariff.html

@ -20,7 +20,7 @@
{% if warntext %} {% if warntext %}
<div class="alert alert-danger alert-dismissable"> <div class="alert alert-danger alert-dismissable">
<button class="close" type="button" aria-hidden="true" data-dismiss="alert">&times;</button> <button class="close" type="button" aria-hidden="true" data-dismiss="alert">&times;</button>
<strong>Внимание!</strong> {{ warntext }}
<strong>Внимание!</strong> {{ warntext|safe }}
</div> </div>
{% endif %} {% endif %}
<form role="form" action="{% url 'abonapp_buy_tariff' abon_group.id abon.id %}" method="post">{% csrf_token %} <form role="form" action="{% url 'abonapp_buy_tariff' abon_group.id abon.id %}" method="post">{% csrf_token %}

16
templates/abonapp/complete_service.html

@ -23,23 +23,13 @@
<form role="form" action="{% url 'abonapp_compl_srv' abon_group.id abon.id abtar.id %}" method="post">{% csrf_token %} <form role="form" action="{% url 'abonapp_compl_srv' abon_group.id abon.id abtar.id %}" method="post">{% csrf_token %}
<input name="finish_confirm" value="yes" type="hidden"> <input name="finish_confirm" value="yes" type="hidden">
<p>Досрочное завершение текущей услуги приведёт к тому что на счёт вернуться деньги за неиспользованные
ресурсы согласно тарифного плана, и подключится следующий по списку заказанный тарифный план, если он есть. Если больше услуг нет то доступ
в сеть будет закрыт.<br/>
Это значит, что если тариф стоит 300 и модуль расчёта по тарифу сказал что использовано ресурсов было на 200, то на счёт вернётся 100.
Или если модуль вернёт 300 то на счёт ничего не вернётся. <b>Вы так же можете создавать свою логику расчёта по тарифу</b>, читайте документацию</p>
<p>Досрочное завершение текущей услуги приведёт к тому что пользователю будет запрещён доступ к ресурсам услуги (закроется инет)<br/>
Для продолжения пользования ресурсами надо подключить нужную услугу</p>
<p>Подробнее:<br/> <p>Подробнее:<br/>
Вы завершаете тариф <a href="{% url 'tarifs_edit_link' abtar.tariff.id %}" target="_blank">{{ abtar.tariff.title }}</a>.<br/> Вы завершаете тариф <a href="{% url 'tarifs_edit_link' abtar.tariff.id %}" target="_blank">{{ abtar.tariff.title }}</a>.<br/>
{% if next_tariff %}
Следующим будет подключен
<a href="{% url 'tarifs_edit_link' next_tariff.tariff.id %}" target="_blank">{{ next_tariff.tariff.title }}</a>.<br/>
{% else %}
Больше заказанных тарифов нет, а значит доступ в интернет для абонента будет закрыт.
{% endif %}<br/>
Время начала: {{ abtar.time_start|date:'d F Y, H:i:s' }}<br/>
Услуга была подключена: {{ abtar.time_start|date:'d F Y, H:i:s' }}<br/>
Сегодня: {% now "d F Y, H:i:s" %}<br/> Сегодня: {% now "d F Y, H:i:s" %}<br/>
Время использования: {% if time_use.days %}{{ time_use.days }} дней.{% endif %} Время использования: {% if time_use.days %}{{ time_use.days }} дней.{% endif %}
{{ time_use.hours }} часов и {{ time_use.minutes }} минут.<br/> {{ time_use.hours }} часов и {{ time_use.minutes }} минут.<br/>

48
templates/abonapp/debtors.html

@ -0,0 +1,48 @@
{% extends 'base.html' %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'abongroup_list_link' %}">Группы абонентов</a></li>
<li class="active">Должники</li>
</ol>
<h3>Народ, у которого есть неоплаченные услуги</h3>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th width="15">#</th>
<th>Абонент</th>
<th>Цена</th>
<th>Комментарий</th>
<th>Дата создания</th>
<th>Автор</th>
</tr>
</thead>
<tbody>
{% for invoice in invoices %}
<tr>
<td>{{ invoice.id }}</td>
<td><a href="{% url 'abonhome_link' invoice.abon.group.id invoice.abon.id %}" target="_blank">{{ invoice.abon.username }}</a></td>
<td>{{ invoice.amount }}</td>
<td>{{ invoice.comment}}</td>
<td>{{ invoice.date_create|date:'d b H:i' }}</td>
<td><a href="{% url 'other_profile' invoice.author.id %}" target="_blank">{{ invoice.author.username }}</a></td>
</tr>
{% empty %}
<tr>
<td colspan="7">
Нет должников
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include 'toolbar_page.html' with pag=peoples %}
{% endblock %}

3
templates/abonapp/ext.htm

@ -16,7 +16,8 @@
{% endif %} {% endif %}
<div class="page-header"> <div class="page-header">
<h2>{{ abon.fio|default:"Имя абонента" }} <small>Балланс <b>&#8399;{{ ballance }}</b> руб</small></h2>
<h2>{{ abon.fio|default:"Имя абонента" }} <small>Балланс <i class="glyphicon glyphicon-ruble"></i>
<b>{{ ballance }}</b> руб</small></h2>
</div> </div>
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">

3
templates/abonapp/group_list.html

@ -64,6 +64,9 @@
<a href="{% url 'abonapp_log_link' %}" class="btn btn-default btn-sm"> <a href="{% url 'abonapp_log_link' %}" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-record"></span> Действия абонентов <span class="glyphicon glyphicon-record"></span> Действия абонентов
</a> </a>
<a href="{% url 'abonapp_debtors' %}" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-exclamation-sign"></span> Список должников
</a>
</td> </td>
</tr> </tr>
</tfoot> </tfoot>

27
templates/abonapp/services.html

@ -11,7 +11,7 @@
<th>Входящая скорость</th> <th>Входящая скорость</th>
<th>Исходящая скорость</th> <th>Исходящая скорость</th>
<th>Время действия</th> <th>Время действия</th>
<th colspan="2">Ред.</th>
<th>Ред.</th>
</tr> </tr>
</thead> </thead>
@ -25,19 +25,24 @@
<td>{{ trf.tariff.speedOut }}</td> <td>{{ trf.tariff.speedOut }}</td>
<td>{{ trf.tariff.time_of_action }}</td> <td>{{ trf.tariff.time_of_action }}</td>
{% if trf.id != active_abontariff_id %} {% if trf.id != active_abontariff_id %}
<td colspan="2" class="btn-group">
<a href="{% url 'abonapp_chpriority_tariff' abon_group.id abon.id %}?t={{ trf.id }}&a=up" class="btn btn-blue">
<i class="icon-fing_up"></i>
<td class="btn-group">
{% if not active_abontariff_id %}
<a href="{% url 'abonapp_activate_service' abon_group.id abon.id trf.id %}" class="btn btn-success btn-sm" title="Активировать услугу">
<i class="glyphicon glyphicon-shopping-cart"></i>
</a> </a>
<a href="{% url 'abonapp_chpriority_tariff' abon_group.id abon.id %}?t={{ trf.id }}&a=down" class="btn btn-blue">
<i class="icon-fing_down"></i>
{% endif %}
<a href="{% url 'abonapp_chpriority_tariff' abon_group.id abon.id %}?t={{ trf.id }}&a=up" class="btn btn-default btn-sm" title="Повысить приоритет">
<i class="glyphicon glyphicon-hand-up"></i>
</a>
<a href="{% url 'abonapp_chpriority_tariff' abon_group.id abon.id %}?t={{ trf.id }}&a=down" class="btn btn-default btn-sm" title="Понизить приоритет">
<i class="glyphicon glyphicon-hand-down"></i>
</a> </a>
<a href="#" class="btn btn-blue" title="Отменить услугу">
<i class="icon-trash"></i>
<a href="{% url 'abonapp_unsubscribe_service' abon_group.id abon.id trf.id %}" class="btn btn-danger btn-sm" title="Удалить услугу">
<i class="glyphicon glyphicon-remove"></i>
</a> </a>
</td> </td>
{% else %} {% else %}
<td colspan="2">
<td>
<a href="{% url 'abonapp_compl_srv' abon_group.id abon.id trf.id %}" title="Завершить услугу досрочно" class="btn btn-danger btn-sm"> <a href="{% url 'abonapp_compl_srv' abon_group.id abon.id trf.id %}" title="Завершить услугу досрочно" class="btn btn-danger btn-sm">
<i class="glyphicon glyphicon-remove"></i> Завершить <i class="glyphicon glyphicon-remove"></i> Завершить
</a> </a>
@ -45,12 +50,12 @@
{% endif %} {% endif %}
</tr> </tr>
{% empty %} {% empty %}
<tr><td colspan="8">Нет подключённых абоненту услуг, <a href="{% url 'abonapp_buy_tariff' abon_group.id abon.id %}" class="lgtbx">купить</a></td></tr>
<tr><td colspan="7">Нет подключённых абоненту услуг, <a href="{% url 'abonapp_buy_tariff' abon_group.id abon.id %}" class="lgtbx">купить</a></td></tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
<tfoot> <tfoot>
<tr><th colspan="8">
<tr><th colspan="7">
<a href="{% url 'abonapp_buy_tariff' abon_group.id abon.id %}" class="btn btn-sm btn-success"> <a href="{% url 'abonapp_buy_tariff' abon_group.id abon.id %}" class="btn btn-sm btn-success">
<span class="glyphicon glyphicon-plus"></span> Купить услугу <span class="glyphicon glyphicon-plus"></span> Купить услугу
</a> </a>

2
templates/accounts/index.html

@ -30,7 +30,7 @@
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<tr> <tr>
<td>Административный доступ (все права)</td> <td>Административный доступ (все права)</td>
<td><input type="checkbox"{{ userprofile.is_admin|yesno:' checked,' }}></td>
<td><input type="checkbox"{{ userprofile.is_staff|yesno:' checked,' }}></td>
</tr> </tr>
{% endif %} {% endif %}
</tbody> </tbody>

8
templates/base.html

@ -50,8 +50,8 @@
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li class="active"><a href="/">Главная</a></li> <li class="active"><a href="/">Главная</a></li>
<li><a href="{% url 'maps_home_link' %}" target="_blank">Карта</a></li> <li><a href="{% url 'maps_home_link' %}" target="_blank">Карта</a></li>
<li><a href="{% url 'stat_home' %}">График траффика</a></li>
<li><a href="{% url 'client_home' %}">Кабинет клиента</a></li>
<li><a href="{% url 'stat_home' %}" target="_blank">График траффика</a></li>
<li><a href="{% url 'client_home' %}" target="_blank">Кабинет клиента</a></li>
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Другое <b class="caret"></b></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Другое <b class="caret"></b></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
@ -152,12 +152,8 @@
{% if tasks_count > 0 %}<span class="badge">{{ tasks_count }}</span>{% endif %} {% if tasks_count > 0 %}<span class="badge">{{ tasks_count }}</span>{% endif %}
</a></li> </a></li>
</ul> </ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
</ul>
</div> </div>
<!-- END Left menu --> <!-- END Left menu -->

79
templates/clientsideapp/buy.html

@ -3,75 +3,60 @@
<div class="page-header"> <div class="page-header">
<h3>Заказать услугу</h3> <h3>Заказать услугу</h3>
<p>Ваша текущая услуга <a href="#dv">Стандартный</a> за <b>130</b> руб.</p>
{% if current_service %}
<p>Ваша текущая услуга <a href="#dv">{{ current_service.tariff.title }}</a>
за <b>{{ current_service.tariff.amount }}</b> руб.</p>
{% else %}
<p>У вас нет активной услуги, для использования ресурсов приобретите нужную услугу из представленных ниже.<br>
А если уже заказали то просто активируйте услугу из списка заказанных.</p>
{% endif %}
</div> </div>
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-lg-4"> <div class="col-lg-4">
<h4>Ваши услуги</h4>
<h4>Ваши заказанные услуги</h4>
<ul class="list-group"> <ul class="list-group">
{% for abon_tariff in own_abon_tariffs %}
<li class="list-group-item"> <li class="list-group-item">
<a href="#del" class="btn btn-xs btn-link" title="Удалить услугу из списка">
<span class="glyphicon glyphicon-remove"></span>
<div class="btn-group">
<a href="#sdf" class="btn btn-xs btn-success" title="Активировать">
<span class="glyphicon glyphicon-fire"></span>
</a> </a>
<span class="badge">130</span>
<a href="#sdv"><b>Стандартный</b></a>
</li>
<li class="list-group-item">
<a href="#del" class="btn btn-xs btn-link" title="Удалить услугу из списка">
<a href="#del" class="btn btn-xs btn-danger" title="Удалить услугу из списка">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</a> </a>
<span class="badge">500</span>
<a href="#dsg">Премиум</a>
</li>
<li class="list-group-item">
<a href="#del" class="btn btn-xs btn-link" title="Удалить услугу из списка">
<span class="glyphicon glyphicon-remove"></span>
</div>
<span class="badge">{{ abon_tariff.tariff.amount }}</span>
<a href="#sdv">
{% if abon_tariff.is_started %}<b>{{ abon_tariff.tariff.title }}</b>
{% else %}{{ abon_tariff.tariff.title }}{% endif %}
</a> </a>
<span class="badge">500</span>
<a href="#dsg">Премиум</a>
</li> </li>
{% empty %}
<li class="list-group-item">У вас нет заказанных услуг</li>
{% endfor %}
</ul> </ul>
</div> </div>
<div class="col-lg-8"> <div class="col-lg-8">
<h4>Выберите ещё услугу</h4> <h4>Выберите ещё услугу</h4>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
{% for tarif in tarifs %}
<div class="col-lg-4"> <div class="col-lg-4">
<h3>Название услуги</h3>
<p>Опис</p>
<a href="#" class="btn btn-default">
<span class="glyphicon glyphicon-shopping-cart"></span> Купить
<h3>{{ tarif.title }}</h3>
<p>{{ tarif.descr }}</p>
<p>Входящая скорость: {{ tarif.speedIn }} MBit/s<br>
Исходящая скорость: {{ tarif.speedOut }} MBit/s<br>
Стоимость: {{ tarif.amount }} руб.</p>
<a href="#" class="btn btn-primary">
<span class="glyphicon glyphicon-shopping-cart"></span> Заказать
</a> </a>
</div> </div>
{% empty %}
<div class="col-lg-4"> <div class="col-lg-4">
<h3>Название услуги</h3>
<p>Описание услуги, длинное длинное</p>
<a href="#" class="btn btn-default">
<span class="glyphicon glyphicon-shopping-cart"></span> Купить
</a>
</div>
<div class="col-lg-4">
<h3>Название услуги</h3>
<p>Описание услуги, длинное длинное</p>
<a href="#" class="btn btn-default">
<span class="glyphicon glyphicon-shopping-cart"></span> Купить
</a>
</div>
<div class="col-lg-4">
<h3>Название услуги</h3>
<p>Описание услуги, длинное длинное</p>
<a href="#" class="btn btn-default">
<span class="glyphicon glyphicon-shopping-cart"></span> Купить
</a>
</div>
<div class="col-lg-4">
<h3>Название услуги</h3>
<p>Описание услуги, длинное длинное</p>
<a href="#" class="btn btn-default">
<span class="glyphicon glyphicon-shopping-cart"></span> Купить
</a>
<h3 class="panel-title">Нет доступных услуг для заказа</h3>
</div> </div>
{% endfor %}
</div> </div>
</div> </div>
</div> </div>

15
templates/clientsideapp/ext.html

@ -60,11 +60,11 @@
<li class="divider"></li> <li class="divider"></li>
<li class="dropdown-header">Nav header</li> <li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li> <li><a href="#">Separated link</a></li>
<li><a href="#">Выйти</a></li>
<li><a href="{% url 'logout_link' %}">Выйти</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
<span class="navbar-text">Ваш балланс <b>126</b> руб.</span>
<span class="navbar-text">Ваш балланс <b>{{ subscriber.ballance }}</b> руб.</span>
</div><!--/.nav-collapse --> </div><!--/.nav-collapse -->
</div> </div>
</div> </div>
@ -72,12 +72,21 @@
<!-- Begin page content --> <!-- Begin page content -->
<div class="container"> <div class="container">
{% if request.user.is_staff %}
<div class="alert alert-info">
<strong>Кстати.</strong>
Вы администратор, и не должны производить действия из кабинета пользователя, производите их из админки.
Кабинет клиента для вас только для ознакомления.
</div>
{% endif %}
{% block client_main %}{% endblock %} {% block client_main %}{% endblock %}
</div> </div>
<div id="footer"> <div id="footer">
<div class="container"> <div class="container">
<p class="text-muted">Place sticky footer content here.</p>
<p class="text-muted">DN&copy;</p>
</div> </div>
</div> </div>

12
templates/clientsideapp/pays.html

@ -9,17 +9,19 @@
<tr> <tr>
<th>Сумма транзакции (руб)</th> <th>Сумма транзакции (руб)</th>
<th>Дата транзакции</th> <th>Дата транзакции</th>
<th>Автор платежа</th>
<th>Комментарий</th> <th>Комментарий</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for pay in pay_history %}
<tr> <tr>
<td>100</td>
<td>08 Сентябрь 2016, 02:30:40</td>
<td><a target="_blank" href="/accounts/1">bashmak</a></td>
<td>Покупка тарифного плана через админку, тариф "New2"</td>
<td>{{ pay.amount }}</td>
<td>{{ pay.date|date:'d b H:i' }}</td>
<td>{{ pay.comment }}</td>
</tr> </tr>
{% empty %}
<tr><td colspan="3">У вас нет проведённых платежей</td></tr>
{% endfor %}
</tbody> </tbody>
</table> </table>

8
templates/tariff_app/editTarif.html

@ -33,6 +33,14 @@
</div> </div>
</div> </div>
<div class="form-group">
<label for="id_descr">Описание тарифа</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-text-background"></span></span>
{{ form.descr }}{{ form.descr.errors }}
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="id_speedIn">Входящая скорость</label> <label for="id_speedIn">Входящая скорость</label>
<div class="input-group"> <div class="input-group">

7
templates/taskapp/ext.htm

@ -35,9 +35,14 @@
Выполненные задачи Выполненные задачи
</a> </a>
</li> </li>
<li>
<a href="#livetab_content" data-tab-remote="{% url 'own_tasks' %}" role="tab" data-toggle="tab">
Назначенные мной задачи
</a>
</li>
<li> <li>
<a href="#livetab_content" data-tab-remote="{% url 'all_tasks' %}" role="tab" data-toggle="tab"> <a href="#livetab_content" data-tab-remote="{% url 'all_tasks' %}" role="tab" data-toggle="tab">
Все задачи
Все мои задачи
</a> </a>
</li> </li>
</ul> </ul>

63
templates/taskapp/tasklist_own.html

@ -0,0 +1,63 @@
{% extends request.is_ajax|yesno:'nullcont.htm,taskapp/ext.htm' %}
{% block content %}
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr><th>#</th>
<th class="col-sm-6">Пару слов..</th>
<th class="col-sm-1">Кому назначена</th>
<th class="col-sm-1">Состояние</th>
<th class="col-sm-1">Приоритет</th>
<th class="col-sm-1">Время выполнения</th>
<th class="col-sm-1">Дата создания</th>
<th class="col-sm-1">Действия</th>
</tr>
</thead>
<tbody>
{% for task in tasks %}
{% if task.priority == 'E' %}<tr class="danger">
{% elif task.priority == 'D' %}<tr class="warning">
{% elif task.priority == 'C' %}<tr class="info">
{% elif task.priority == 'B' %}<tr>
{% elif task.priority == 'A' %}<tr class="success">
{% else %}<tr>{% endif %}
<td>{{ task.id }}</td>
<td>{{ task.descr }}</td>
<td><a href="{% url 'other_profile' task.recipient.id %}" title="{{ task.recipient.get_full_name }}">{{ task.recipient.username }}</a></td>
<td>{{ task.get_state_display }}</td>
<td>{{ task.get_priority_display }}</td>
<td>{{ task.out_date|date:'d N yг' }}</td>
<td>{{ task.time_of_create|date:'d N yг H:i:s' }}</td>
<td class="btn-group">
<a href="{% url 'task_edit' task.id %}" class="btn btn-sm btn-default" title="Редактировать">
<span class="glyphicon glyphicon-edit"></span>
</a>
<a href="#" class="btn btn-sm btn-danger disabled" title="Удалить">
<span class="glyphicon glyphicon-remove-circle"></span>
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="8">Все ваши задачи выполнены</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="8">
<a href="{% url 'task_add' %}" class="btn btn-sm btn-success" title="Создать новую задачу">
<span class="glyphicon glyphicon-plus"></span>
</a>
</td>
</tr>
</tfoot>
</table>
</div>
{% include 'toolbar_page.html' with pag=tasks %}
{% endblock %}
Loading…
Cancel
Save