Browse Source

всё пишу..

devel
Dmitry 9 years ago
parent
commit
2ea3751aae
  1. 169
      abonapp/models.py
  2. 2
      abonapp/urls.py
  3. 5
      abonapp/urls_abon.py
  4. 99
      abonapp/views.py
  5. 4
      accounts_app/views.py
  6. 28
      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. 85
      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

169
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)

2
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)

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+)/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+)/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')
]

99
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' <a href="%s">Вернуться</a>' % 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('<h1>uid not equal uid from service</h1>')
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('<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
@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):

4
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:

28
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)

13
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):

5
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
))

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

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/
# 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/

2
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')

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
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"

2
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):

1
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'}),

1
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)

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

2
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

1
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')
]

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
@only_admins
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 %}
<div class="alert alert-danger alert-dismissable">
<button class="close" type="button" aria-hidden="true" data-dismiss="alert">&times;</button>
<strong>Внимание!</strong> {{ warntext }}
<strong>Внимание!</strong> {{ warntext|safe }}
</div>
{% endif %}
<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 %}
<input name="finish_confirm" value="yes" type="hidden">
<p>Досрочное завершение текущей услуги приведёт к тому что на счёт вернуться деньги за неиспользованные
ресурсы согласно тарифного плана, и подключится следующий по списку заказанный тарифный план, если он есть. Если больше услуг нет то доступ
в сеть будет закрыт.<br/>
Это значит, что если тариф стоит 300 и модуль расчёта по тарифу сказал что использовано ресурсов было на 200, то на счёт вернётся 100.
Или если модуль вернёт 300 то на счёт ничего не вернётся. <b>Вы так же можете создавать свою логику расчёта по тарифу</b>, читайте документацию</p>
<p>Досрочное завершение текущей услуги приведёт к тому что пользователю будет запрещён доступ к ресурсам услуги (закроется инет)<br/>
Для продолжения пользования ресурсами надо подключить нужную услугу</p>
<p>Подробнее:<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/>
Время использования: {% if time_use.days %}{{ time_use.days }} дней.{% endif %}
{{ 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 %}
<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>
<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">
<span class="glyphicon glyphicon-record"></span> Действия абонентов
</a>
<a href="{% url 'abonapp_debtors' %}" class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-exclamation-sign"></span> Список должников
</a>
</td>
</tr>
</tfoot>

27
templates/abonapp/services.html

@ -11,7 +11,7 @@
<th>Входящая скорость</th>
<th>Исходящая скорость</th>
<th>Время действия</th>
<th colspan="2">Ред.</th>
<th>Ред.</th>
</tr>
</thead>
@ -25,19 +25,24 @@
<td>{{ trf.tariff.speedOut }}</td>
<td>{{ trf.tariff.time_of_action }}</td>
{% 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 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="#" class="btn btn-blue" title="Отменить услугу">
<i class="icon-trash"></i>
<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 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>
</td>
{% 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">
<i class="glyphicon glyphicon-remove"></i> Завершить
</a>
@ -45,12 +50,12 @@
{% endif %}
</tr>
{% 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 %}
</tbody>
<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">
<span class="glyphicon glyphicon-plus"></span> Купить услугу
</a>

2
templates/accounts/index.html

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

8
templates/base.html

@ -50,8 +50,8 @@
<ul class="nav navbar-nav">
<li class="active"><a href="/">Главная</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">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Другое <b class="caret"></b></a>
<ul class="dropdown-menu">
@ -152,12 +152,8 @@
{% if tasks_count > 0 %}<span class="badge">{{ tasks_count }}</span>{% endif %}
</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">Nav item</a></li>
</ul>
</div>
<!-- END Left menu -->

85
templates/clientsideapp/buy.html

@ -3,75 +3,60 @@
<div class="page-header">
<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 class="container">
<div class="row">
<div class="col-lg-4">
<h4>Ваши услуги</h4>
<h4>Ваши заказанные услуги</h4>
<ul class="list-group">
{% for abon_tariff in own_abon_tariffs %}
<li class="list-group-item">
<a href="#del" class="btn btn-xs btn-link" title="Удалить услугу из списка">
<span class="glyphicon glyphicon-remove"></span>
</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="Удалить услугу из списка">
<span class="glyphicon glyphicon-remove"></span>
</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 class="btn-group">
<a href="#sdf" class="btn btn-xs btn-success" title="Активировать">
<span class="glyphicon glyphicon-fire"></span>
</a>
<a href="#del" class="btn btn-xs btn-danger" title="Удалить услугу из списка">
<span class="glyphicon glyphicon-remove"></span>
</a>
</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>
<span class="badge">500</span>
<a href="#dsg">Премиум</a>
</li>
{% empty %}
<li class="list-group-item">У вас нет заказанных услуг</li>
{% endfor %}
</ul>
</div>
<div class="col-lg-8">
<h4>Выберите ещё услугу</h4>
<div class="container-fluid">
<div class="row">
{% for tarif in tarifs %}
<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>
</div>
{% empty %}
<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 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>
{% endfor %}
</div>
</div>
</div>

15
templates/clientsideapp/ext.html

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

12
templates/clientsideapp/pays.html

@ -9,17 +9,19 @@
<tr>
<th>Сумма транзакции (руб)</th>
<th>Дата транзакции</th>
<th>Автор платежа</th>
<th>Комментарий</th>
</tr>
</thead>
<tbody>
{% for pay in pay_history %}
<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>
{% empty %}
<tr><td colspan="3">У вас нет проведённых платежей</td></tr>
{% endfor %}
</tbody>
</table>

8
templates/tariff_app/editTarif.html

@ -33,6 +33,14 @@
</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">
<label for="id_speedIn">Входящая скорость</label>
<div class="input-group">

7
templates/taskapp/ext.htm

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