Browse Source

продолжаю...

devel
Dmitry 9 years ago
parent
commit
dc77ed368e
  1. 1
      abonapp/admin.py
  2. 87
      abonapp/forms.py
  3. 29
      abonapp/models.py
  4. 4
      abonapp/urls_abon.py
  5. 58
      abonapp/views.py
  6. 2
      accounts_app/models.py
  7. 2
      agent/netflow/to_mysql.py
  8. 2
      djing/utils/load_dot_from_nodeny.py
  9. 2
      djing/utils/load_from_nodeny.py
  10. 2
      djing/utils/save_dot_from_nodeny.py
  11. 2
      djing/utils/save_from_nodeny.py
  12. 22
      static/css/custom.css
  13. 8
      static/js/bootstrap-datetimepicker.min.js
  14. 91
      static/js/gmap.js
  15. 3386
      static/js/moment-with-locales.min.js
  16. 29
      templates/abonapp/addAbon.html
  17. 2
      templates/abonapp/buy_tariff.html
  18. 72
      templates/abonapp/editAbon.html
  19. 44
      templates/abonapp/ext.htm
  20. 26
      templates/abonapp/peoples.html
  21. 2
      templates/accounts/ext.htm
  22. 2
      templates/accounts/settings/ext.htm
  23. 2
      templates/devapp/ext.htm
  24. 8
      templates/taskapp/add_edit_task.html
  25. 2
      templates/taskapp/ext.htm

1
abonapp/admin.py

@ -8,3 +8,4 @@ admin.site.register(models.Abon)
admin.site.register(models.InvoiceForPayment) admin.site.register(models.InvoiceForPayment)
admin.site.register(models.AbonLog) admin.site.register(models.AbonLog)
admin.site.register(models.AbonTariff) admin.site.register(models.AbonTariff)
admin.site.register(models.AbonStreets)

87
abonapp/forms.py

@ -1,55 +1,51 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django import forms from django import forms
from django.core.validators import RegexValidator
from random import choice
from string import digits
from . import models from . import models
from mydefs import ip_addr_regex
class AbonForm(forms.Form):
username = forms.CharField(max_length=127, required=False, widget=forms.TextInput(attrs={
def generate_random_username(length=6, chars=digits, split=2, delimiter=''):
username = ''.join([choice(chars) for i in range(length)])
if split:
username = delimiter.join([username[start:start+split] for start in range(0, len(username), split)])
try:
models.Abon.objects.get(username=username)
return generate_random_username(length=length, chars=chars, split=split, delimiter=delimiter)
except models.Abon.DoesNotExist:
return username
class AbonForm(forms.ModelForm):
username = forms.CharField(max_length=127, required=False, initial=generate_random_username, widget=forms.TextInput(attrs={
'placeholder': 'Логин', 'placeholder': 'Логин',
'class': "form-control", 'class': "form-control",
'id': "login"
}))
fio = forms.CharField(max_length=256, widget=forms.TextInput(attrs={
'placeholder': 'ФИО',
'class': "form-control",
'id': "fio"
}), required=False)
ip_address = forms.GenericIPAddressField(protocol='ipv4', required=False, widget=forms.TextInput(attrs={
'pattern': ip_addr_regex,
'placeholder': '127.0.0.1',
'class': "form-control",
'id': "ip"
'required':''
})) }))
telephone = forms.CharField(
max_length=16,
validators=[RegexValidator(r'^\+[7,8,9,3]\d{10,11}$')],
widget=forms.TextInput(attrs={
'placeholder': '+[7,8,9,3] и 10,11 цифр',
'pattern': r'^\+[7,8,9,3]\d{10,11}$',
'required': '',
'class': 'form-control',
'id': 'telephone'
})
)
is_active = forms.BooleanField(
required=False,
widget=forms.NullBooleanSelect(attrs={'class': 'form-control', 'id': 'isactive'})
)
group = forms.ModelChoiceField(
queryset=models.AbonGroup.objects.all(),
required=False,
widget=forms.Select(attrs={'class': 'form-control', 'id': 'grp'})
)
address = forms.CharField(
max_length=256,
required=False,
widget=forms.TextInput(attrs={'class': 'form-control', 'id': 'address'})
)
class Meta:
model = models.Abon
fields = ['username', 'telephone', 'fio', 'group', 'description', 'street', 'house', 'is_active']
widgets = {
'fio': forms.TextInput(attrs={
'placeholder': 'ФИО',
'class': "form-control",
'required': ''
}),
'telephone': forms.TextInput(attrs={
'placeholder': '+[7,8,9,3] и 10,11 цифр',
'pattern': r'^\+[7,8,9,3]\d{10,11}$',
'required': '',
'class': 'form-control'
}),
'group': forms.Select(attrs={'class': 'form-control'}),
'description': forms.Textarea(attrs={'class': 'form-control', 'rows':'3', 'cols':'65'}),
'street': forms.Select(attrs={'class': 'form-control'}),
'house': forms.TextInput(attrs={'class': 'form-control'}),
'is_active': forms.NullBooleanSelect(attrs={'class': 'form-control'})
}
class AbonGroupForm(forms.ModelForm): class AbonGroupForm(forms.ModelForm):
@ -57,7 +53,8 @@ class AbonGroupForm(forms.ModelForm):
model = models.AbonGroup model = models.AbonGroup
fields = '__all__' fields = '__all__'
widgets = { widgets = {
'class': 'form-control'
'title': forms.TextInput(attrs={'class': 'form-control'}),
'profiles': forms.TextInput(attrs={'class': 'form-control'})
} }
@ -65,5 +62,5 @@ class BuyTariff(forms.Form):
tariff = forms.ModelChoiceField( tariff = forms.ModelChoiceField(
queryset=models.Tariff.objects.all(), queryset=models.Tariff.objects.all(),
required=True, required=True,
widget=forms.Select(attrs={'class': 'form-control', 'id': 'tariff'})
widget=forms.Select(attrs={'class': 'form-control'})
) )

29
abonapp/models.py

@ -150,12 +150,20 @@ class AbonTariff(models.Model):
) )
class AbonStreets(models.Model):
name = models.CharField(max_length=64)
group = models.ForeignKey(AbonGroup)
class Abon(UserProfile): class Abon(UserProfile):
current_tariffs = models.ManyToManyField(Tariff, through=AbonTariff) current_tariffs = models.ManyToManyField(Tariff, through=AbonTariff)
group = models.ForeignKey(AbonGroup, models.SET_NULL, blank=True, null=True) group = models.ForeignKey(AbonGroup, models.SET_NULL, blank=True, null=True)
ballance = models.FloatField(default=0.0, validators=[DecimalValidator]) ballance = models.FloatField(default=0.0, validators=[DecimalValidator])
ip_address = models.OneToOneField(IpPoolItem, on_delete=models.SET_NULL, null=True, blank=True) ip_address = models.OneToOneField(IpPoolItem, on_delete=models.SET_NULL, null=True, blank=True)
address = models.CharField(max_length=256)
#TODO: надо ж пароль для абонента создавать
description = models.TextField(null=True, blank=True)
street = models.ForeignKey(AbonStreets, on_delete=models.SET_NULL, null=True, blank=True)
house = models.CharField(max_length=12, null=True, blank=True)
_act_tar_cache = None _act_tar_cache = None
@ -173,23 +181,6 @@ class Abon(UserProfile):
self._act_tar_cache = None self._act_tar_cache = None
return return
def save_form(self, abonform_instance):
try:
cd = abonform_instance.cleaned_data
tel = cd['telephone']
self.username = cd['username'] or tel[1:]
self.fio = cd['fio']
self.telephone = tel
self.is_admin = False
self.ip_address = get_object_or_404(IpPoolItem, ip=cd['ip_address'])
self.is_active = True
self.group = cd['group']
self.address = cd['address']
except Http404:
raise LogicError('Введённый IP адрес не добавлен в ip pool')
except MultipleObjectsReturned:
raise LogicError('Введённый IP адрес не определён')
class Meta: class Meta:
db_table = 'abonent' db_table = 'abonent'
permissions = ( permissions = (
@ -360,6 +351,8 @@ def abontariff_post_save(sender, instance, **kwargs):
if not kwargs['created']: if not kwargs['created']:
# если изменение приоритета то не говорим об этом NAS'у # если изменение приоритета то не говорим об этом NAS'у
return return
if instance.abon.ip_address is None:
return
agent_trf = TariffStruct(instance.tariff.id, instance.tariff.speedIn, instance.tariff.speedOut) agent_trf = TariffStruct(instance.tariff.id, instance.tariff.speedIn, instance.tariff.speedOut)
agent_abon = AbonStruct(instance.abon.id, instance.abon.ip_address.int_ip(), agent_trf) agent_abon = AbonStruct(instance.abon.id, instance.abon.ip_address.int_ip(), agent_trf)
tm = Transmitter() tm = Transmitter()

4
abonapp/urls_abon.py

@ -20,5 +20,7 @@ urlpatterns = [
url(r'^(?P<uid>\d+)/activate_service(?P<srvid>\d+)$', views.activate_service, name='activate_service'), url(r'^(?P<uid>\d+)/activate_service(?P<srvid>\d+)$', views.activate_service, name='activate_service'),
url(r'^(?P<uid>\d+)/unsubscribe_service(?P<srvid>\d+)$', views.unsubscribe_service, url(r'^(?P<uid>\d+)/unsubscribe_service(?P<srvid>\d+)$', views.unsubscribe_service,
name='unsubscribe_service')
name='unsubscribe_service'),
url(r'^(?P<uid>\d+)/task_log$', views.task_log, name='task_log')
] ]

58
abonapp/views.py

@ -11,7 +11,6 @@ from django.http import HttpResponse, Http404
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib import messages from django.contrib import messages
from ip_pool.models import IpPoolItem
from tariff_app.models import Tariff from tariff_app.models import Tariff
from agent import NasFailedResult, AbonStruct, Transmitter, TariffStruct, NasNetworkError from agent import NasFailedResult, AbonStruct, Transmitter, TariffStruct, NasNetworkError
from . import forms from . import forms
@ -102,12 +101,9 @@ def addabon(request, gid):
try: try:
group = get_object_or_404(models.AbonGroup, id=gid) group = get_object_or_404(models.AbonGroup, id=gid)
if request.method == 'POST': if request.method == 'POST':
frm = forms.AbonForm(request.POST)
frm = forms.AbonForm(request.POST, initial={'group': group})
if frm.is_valid(): if frm.is_valid():
prf = models.Abon()
prf.group = group
prf.save_form(frm)
prf.save()
frm.save()
return redirect('abonapp:people_list', group.id) return redirect('abonapp:people_list', group.id)
else: else:
messages.error(request, 'Некоторые поля заполнены не правильно, проверте ещё раз') messages.error(request, 'Некоторые поля заполнены не правильно, проверте ещё раз')
@ -123,8 +119,9 @@ def addabon(request, gid):
if not frm: if not frm:
frm = forms.AbonForm(initial={ frm = forms.AbonForm(initial={
'ip_address': IpPoolItem.objects.get_free_ip(),
'group': group
'group': group,
'address': 'Адрес',
'is_active': False
}) })
return render(request, 'abonapp/addAbon.html', { return render(request, 'abonapp/addAbon.html', {
@ -231,44 +228,27 @@ def abon_services(request, gid, uid):
def abonhome(request, gid, uid): def abonhome(request, gid, uid):
abon = get_object_or_404(models.Abon, id=uid) abon = get_object_or_404(models.Abon, id=uid)
abon_group = get_object_or_404(models.AbonGroup, id=gid) abon_group = get_object_or_404(models.AbonGroup, id=gid)
ballance = abon.ballance
frm = None frm = None
init_frm_dat = {
'username': abon.username,
'fio': abon.fio,
'ip_address': abon.ip_address or 'Не назначен',
'telephone': abon.telephone,
'group': abon.group,
'address': abon.address,
'is_active': abon.is_active
}
try: try:
if request.method == 'POST': if request.method == 'POST':
frm = forms.AbonForm(request.POST)
frm = forms.AbonForm(request.POST, instance=abon)
if frm.is_valid(): if frm.is_valid():
cd = frm.cleaned_data
abon.username = cd['username']
abon.fio = cd['fio']
abon.ip_address = get_object_or_404(IpPoolItem, ip=cd['ip_address'])
abon.telephone = cd['telephone']
abon.group = cd['group']
abon.address = cd['address']
abon.is_active = 1 if cd['is_active'] else 0
abon.save() abon.save()
messages.success(request, 'Абонент успешно сохранён')
# return redirect('abonapp:abon_home', gid, uid) # return redirect('abonapp:abon_home', gid, uid)
else: else:
messages.warning(request, 'Не правильные значения, проверте поля и попробуйте ещё') messages.warning(request, 'Не правильные значения, проверте поля и попробуйте ещё')
else: else:
frm = forms.AbonForm(initial=init_frm_dat)
frm = forms.AbonForm(instance=abon)
except IntegrityError as e: except IntegrityError as e:
messages.error(request, 'Проверте введённые вами значения, скорее всего такой ip уже у кого-то есть. А вообще: %s' % e) messages.error(request, 'Проверте введённые вами значения, скорее всего такой ip уже у кого-то есть. А вообще: %s' % e)
frm = forms.AbonForm(initial=init_frm_dat)
frm = forms.AbonForm(instance=abon)
except Http404: except Http404:
messages.error(request, 'Ip адрес не найден в списке IP адресов') messages.error(request, 'Ip адрес не найден в списке IP адресов')
frm = forms.AbonForm(initial=init_frm_dat)
frm = forms.AbonForm(instance=abon)
except NasFailedResult as e: except NasFailedResult as e:
messages.error(request, e) messages.error(request, e)
@ -276,9 +256,8 @@ def abonhome(request, gid, uid):
messages.error(request, e) messages.error(request, e)
return render(request, 'abonapp/editAbon.html', { return render(request, 'abonapp/editAbon.html', {
'form': frm or forms.AbonForm(initial=init_frm_dat),
'form': frm or forms.AbonForm(instance=abon),
'abon': abon, 'abon': abon,
'ballance': ballance,
'abon_group': abon_group 'abon_group': abon_group
}) })
@ -518,6 +497,20 @@ def update_nas(request, group_id):
return redirect('abonapp:people_list', gid=group_id) return redirect('abonapp:people_list', gid=group_id)
@login_required
@mydefs.only_admins
def task_log(request, gid, uid):
from taskapp.models import Task
abon = get_object_or_404(models.Abon, id=uid)
tasks = Task.objects.filter(abon=abon)
return render(request, 'abonapp/task_log.html', {
'tasks': tasks,
'abon_group': get_object_or_404(models.AbonGroup, id=gid),
'abon': abon
})
# API's # API's
def abons(request): def abons(request):
@ -544,6 +537,7 @@ def abons(request):
def search_abon(request): def search_abon(request):
word = request.GET.get('s') word = request.GET.get('s')
#FIXME: всё равно чувствительный к регистру, надо не чувствительный
results = models.Abon.objects.filter(fio__icontains=word)[:8] results = models.Abon.objects.filter(fio__icontains=word)[:8]
results = [{'id':usr.id, 'name':usr.username, 'fio':usr.fio} for usr in results] results = [{'id':usr.id, 'name':usr.username, 'fio':usr.fio} for usr in results]
return HttpResponse(dumps(results, ensure_ascii=False)) return HttpResponse(dumps(results, ensure_ascii=False))

2
accounts_app/models.py

@ -53,7 +53,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
validators=[RegexValidator('^\+[7,8,9,3]\d{10,11}$')] validators=[RegexValidator('^\+[7,8,9,3]\d{10,11}$')]
) )
avatar = models.ForeignKey(Photo, null=True, blank=True) avatar = models.ForeignKey(Photo, null=True, blank=True)
email = models.EmailField()
email = models.EmailField(default='admin@example.ru')
USERNAME_FIELD = 'username' USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['telephone'] REQUIRED_FIELDS = ['telephone']

2
agent/netflow/to_mysql.py

@ -1,4 +1,4 @@
#!/bin/env python2
#!/bin/env python3
import sys import sys
import socket import socket
import struct import struct

2
djing/utils/load_dot_from_nodeny.py

@ -1,4 +1,4 @@
#!/bin/env python2
#!/bin/env python3
# coding=utf-8 # coding=utf-8
import os import os

2
djing/utils/load_from_nodeny.py

@ -1,4 +1,4 @@
#!/bin/env python2
#!/bin/env python3
# coding=utf-8 # coding=utf-8
import os import os

2
djing/utils/save_dot_from_nodeny.py

@ -1,4 +1,4 @@
#!/bin/env python2
#!/bin/env python3
# coding=utf-8 # coding=utf-8
import os import os

2
djing/utils/save_from_nodeny.py

@ -1,4 +1,4 @@
#!/bin/env python2
#!/bin/env python3
# coding=utf-8 # coding=utf-8
import os import os

22
static/css/custom.css

@ -89,10 +89,17 @@ td.btn-group {
vertical-align: middle; vertical-align: middle;
} }
.modal-header.warning {
background-color: #d2322d;
.modal-header{
border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0;
} }
.modal-header.warning {background-color: #d2322d;}
.modal-header.success {background-color: #6ad245;}
.modal-header.primary {background-color: #789cbb;}
.page-header {
margin-top: 19px;
}
.tab-pane { .tab-pane {
border-left: 1px solid #ddd; border-left: 1px solid #ddd;
@ -119,15 +126,6 @@ td.btn-group {
} }
/*---------Switch----------*/ /*---------Switch----------*/
.switch_ports {
border: 2px solid #636363;
border-radius: 7px;
box-shadow: 3px 3px 8px #2B2B2B;
}
.switch_ports h4 {
margin: 10px 0 3px 10px;
}
.port { .port {
display: inline-block; display: inline-block;
@ -187,7 +185,7 @@ a.port-img{
/* /*
* Off Canvas
* Off Canvas. На маленьком экране появляется кнопка чтоб сдвинуть экран
* -------------------------------------------------- * --------------------------------------------------
*/ */
@media screen and (max-width: 767px) { @media screen and (max-width: 767px) {

8
static/js/bootstrap-datetimepicker.min.js
File diff suppressed because it is too large
View File

91
static/js/gmap.js

@ -1,91 +0,0 @@
function toggleCategory(category) {
$.each(gmap_markers, function (key, marker) {
if (marker.category == category) {
if (marker.getVisible() == true) {
marker.setVisible(false)
} else {
marker.setVisible(true)
}
}
})
}
function toggleTag(tag) {
$.each(gmap_markers, function (key, marker) {
$.each(marker.tags, function (key, this_tag) {
if (this_tag == tag) {
if (marker.getVisible() == true) {
marker.setVisible(false)
} else {
marker.setVisible(true)
}
}
})
})
}
$(document).ready(function () {
var myLatlng = new Array();
var open_marker = '';
myLatlng[0] = new google.maps.LatLng(28.5000, -81.4500);
var map = new google.maps.Map(document.getElementById("gmap_canvas"), {
zoom: 1,
center: myLatlng[0],
mapTypeId: google.maps.MapTypeId.ROADMAP
});
$.getJSON('/map/markers.json', function (data) {
var categories = new Array();
var tags = new Array();
var infowindow = new google.maps.InfoWindow({content: ''})
gmap_markers = []
$.each(data, function (key, item) {
var content = '<span class="name">' + item.fields.name + '</span><br/><span class="phone">' + item.fields.phone + '</span><br/><span class="email">' + item.fields.email + '</span><br/><span class="url">' + item.fields.url + '</span><br/>'
var latLng = new google.maps.LatLng(item.fields.latitude, item.fields.longitude)
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: item.fields.name,
category: item.fields.category,
tags: item.fields.sub_categories,
})
google.maps.event.addListener(marker, "click", function () {
infowindow.content = content
infowindow.open(map, marker);
});
gmap_markers.push(marker)
if ($.inArray(item.fields.category, categories) == -1) {
categories.push(item.fields.category)
}
$.each(item.fields.sub_categories, function (key, item) {
if ($.inArray(item, tags) == -1) {
tags.push(item)
}
})
})
$.each(categories, function (key, category) {
var $button = $(' <a href="#category_' + category + '">' + category + '</a> ').bind('click', function () {
toggleCategory(category)
})
$('#gmap_categories').append($button)
})
$.each(tags, function (key, tag) {
var $button = $(' <a href="#tag_' + tag + '">' + tag + '</a> ').bind('click', function () {
toggleTag(tag)
})
$('#gmap_sub_categories').append($button)
})
})
google.maps.event.addListener(map, 'click', function () {
if (open_marker != '') {
open_marker.close();
}
open_marker = '';
});
})

3386
static/js/moment-with-locales.min.js
File diff suppressed because it is too large
View File

29
templates/abonapp/addAbon.html

@ -32,14 +32,6 @@
{{ form.fio }}{{ form.fio.errors }} {{ form.fio }}{{ form.fio.errors }}
</div> </div>
</div> </div>
<div class="form-group">
<label for="ip">IP Адрес</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-ice-lolly"></span></span>
{{ form.ip_address }}{{ form.ip_address.errors }}
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="telephone">Телефон</label> <label for="telephone">Телефон</label>
@ -57,13 +49,28 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="address">Адрес проживания</label>
<label for="id_description">Комментарий</label>
<span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
{{ form.description }}{{ form.description.errors }}
</div>
<div class="form-group">
<label for="id_street">Улица</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-road"></span></span>
{{ form.street }}{{ form.street.errors }}
</div>
</div>
<div class="form-group">
<label for="id_house">Дом/Квартира</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-map-marker"></span></span>
{{ form.address }}
<span class="input-group-addon"><span class="glyphicon glyphicon-home"></span></span>
{{ form.house }}{{ form.house.errors }}
</div> </div>
</div> </div>
<div class="btn-group"> <div class="btn-group">
<button type="submit" class="btn btn-sm btn-primary"> <button type="submit" class="btn btn-sm btn-primary">
<span class="glyphicon glyphicon-save"></span> Сохранить <span class="glyphicon glyphicon-save"></span> Сохранить

2
templates/abonapp/buy_tariff.html

@ -22,7 +22,7 @@
<form role="form" action="{% url 'abonapp:buy_tariff' abon_group.id abon.id %}" <form role="form" action="{% url 'abonapp:buy_tariff' abon_group.id abon.id %}"
method="post">{% csrf_token %} method="post">{% csrf_token %}
<div class="form-group"> <div class="form-group">
<label for="tariff">Выбирите тарифф</label>
<label for="id_tariff">Выбирите тарифф</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-bullhorn"></span></span> <span class="input-group-addon"><span class="glyphicon glyphicon-bullhorn"></span></span>

72
templates/abonapp/editAbon.html

@ -4,46 +4,64 @@
<div class="row"> <div class="row">
<div class="col-sm-4"> <div class="col-sm-4">
<form role="form" action="{% url 'abonapp:abon_home' abon_group.id abon.id %}" method="post"> {% csrf_token %}
<form role="form" class="form-horizontal" action="{% url 'abonapp:abon_home' abon_group.id abon.id %}" method="post"> {% csrf_token %}
<div class="form-group-sm"> <div class="form-group-sm">
<label for="grp">Группа</label>
{{ form.group }}{{ form.group.errors }}
<label for="id_group" class="col-sm-2 control-label">Группа</label>
<div class="col-sm-10">
{{ form.group }}{{ form.group.errors }}
</div>
</div> </div>
<div class="form-group-sm"> <div class="form-group-sm">
<label for="isactive">Активен</label>
{{ form.is_active }}
<label for="id_is_active" class="col-sm-2 control-label">Активен</label>
<div class="col-sm-10">
{{ form.is_active }}
</div>
</div> </div>
<div class="form-group-sm"> <div class="form-group-sm">
<label for="login">Логин абонента</label>
{{ form.username }}{{ form.username.errors }}
<label for="id_username" class="col-sm-2 control-label">Логин</label>
<div class="col-sm-10">
{{ form.username }}{{ form.username.errors }}
</div>
</div> </div>
<div class="form-group-sm"> <div class="form-group-sm">
<label for="fio">ФИО</label>
{{ form.fio }}{{ form.fio.errors }}
<label for="id_fio" class="col-sm-2 control-label">ФИО</label>
<div class="col-sm-10">
{{ form.fio }}{{ form.fio.errors }}
</div>
</div> </div>
<div class="form-group-sm"> <div class="form-group-sm">
<label for="ip">IP Адрес</label>
{{ form.ip_address }}{{ form.ip_address.errors }}
<label for="id_telephone" class="col-sm-2 control-label">Телефон</label>
<div class="col-sm-10">
{{ form.telephone }}{{ form.telephone.errors }}
</div>
</div> </div>
<div class="form-group-sm"> <div class="form-group-sm">
<label for="contract">Договор</label>
<input type="text" class="form-control" id="contract" placeholder="Contract"/>
<label for="id_street" class="col-sm-2 control-label">Улица</label>
<div class="col-sm-10">
{{ form.street }}{{ form.street.errors }}
</div>
</div> </div>
<div class="form-group-sm"> <div class="form-group-sm">
<label for="telephone">Телефон</label>
{{ form.telephone }}{{ form.telephone.errors }}
<label for="id_house" class="col-sm-2 control-label">Дом</label>
<div class="col-sm-10">
{{ form.house }}{{ form.house.errors }}
</div>
</div> </div>
<div class="form-group-sm"> <div class="form-group-sm">
<label for="address">Адрес проживания</label>
{{ form.address }}{{ form.address.errors }}
<label for="id_description">Комментарий</label>
<div class="input-group">
{{ form.description }}{{ form.description.errors }}
</div>
</div> </div>
<br> <br>
@ -54,19 +72,25 @@
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
<form role="form" action="" method="get">
<form role="form" class="form-horizontal" action="" method="get">
<div class="form-group-sm"> <div class="form-group-sm">
<label for="pasp_num">Серия паспорта</label>
<input type="text" name="pasp_num" class="form-control" id="pasp_num"/>
<label for="pasp_num" class="col-sm-4 control-label">Серия пас.</label>
<div class="col-sm-8">
<input type="text" name="pasp_num" class="form-control" id="pasp_num"/>
</div>
</div> </div>
<div class="form-group-sm"> <div class="form-group-sm">
<label for="pasp_sr">Номер паспорта</label>
<input type="text" name="pasp_sr" class="form-control" id="pasp_sr"/>
<label for="pasp_sr" class="col-sm-4 control-label">Номер пас.</label>
<div class="col-sm-8">
<input type="text" name="pasp_sr" class="form-control" id="pasp_sr"/>
</div>
</div> </div>
<div class="form-group-sm"> <div class="form-group-sm">
<label for="wr">Кем выдан</label>
<input type="text" name="wr" class="form-control" id="wr"/>
<label for="wr" class="col-sm-4 control-label">Кем выдан</label>
<div class="col-sm-8">
<input type="text" name="wr" class="form-control" id="wr"/>
</div>
</div> </div>
<br> <br>

44
templates/abonapp/ext.htm

@ -13,26 +13,46 @@
<div class="page-header"> <div class="page-header">
<h2>{{ abon.fio|default:"Имя абонента" }} <h2>{{ abon.fio|default:"Имя абонента" }}
<small>Балланс <i class="glyphicon glyphicon-ruble"></i> <small>Балланс <i class="glyphicon glyphicon-ruble"></i>
<b>{{ ballance }}</b> руб
<b>{{ abon.ballance }}</b> руб
</small> </small>
</h2> </h2>
</div> </div>
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"><a href="#livetab_content" data-tab-remote="{% url 'abonapp:abon_home' abon_group.id abon.id %}"
role="tab" data-toggle="tab">Информация абонента</a></li>
<li><a href="#livetab_content" data-tab-remote="{% url 'abonapp:abon_services' abon_group.id abon.id %}" role="tab"
data-toggle="tab">Услуги</a></li>
<li><a href="#livetab_content" data-tab-remote="{% url 'abonapp:abon_amount' abon_group.id abon.id %}" role="tab"
data-toggle="tab">Пополнить счёт</a></li>
<li><a href="#livetab_content" data-tab-remote="{% url 'abonapp:abon_debts' abon_group.id abon.id %}" role="tab"
data-toggle="tab">Долги</a></li>
<li><a href="#livetab_content" data-tab-remote="{% url 'abonapp:abon_phistory' abon_group.id abon.id %}" role="tab"
data-toggle="tab">История платежей</a></li>
{% url 'abonapp:abon_home' abon_group.id abon.id as abon_home %}
<li{% if abon_home == request.path %} class="active"{% endif %}>
<a href="{{ abon_home }}">Информация абонента</a>
</li>
{% url 'abonapp:abon_services' abon_group.id abon.id as abserv %}
<li{% if abserv == request.path %} class="active"{% endif %}>
<a href="{{ abserv }}">Услуги</a>
</li>
{% url 'abonapp:abon_amount' abon_group.id abon.id as abamount %}
<li{% if abamount == request.path %} class="active"{% endif %}>
<a href="{{ abamount }}">Пополнить счёт</a>
</li>
{% url 'abonapp:abon_debts' abon_group.id abon.id as abondebts %}
<li{% if abondebts == request.path %} class="active"{% endif %}>
<a href="{{ abondebts }}">Долги</a>
</li>
{% url 'abonapp:abon_phistory' abon_group.id abon.id as abphist %}
<li{% if abphist == request.path %} class="active"{% endif %}>
<a href="{{ abphist }}">История платежей</a>
</li>
{% url 'abonapp:task_log' abon_group.id abon.id as abtasklog %}
<li{% if abtasklog == request.path %} class="active"{% endif %}>
<a href="{{ abtasklog }}">История задач</a>
</li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="livetab_content">
<div class="tab-pane active">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
</div> </div>

26
templates/abonapp/peoples.html

@ -15,7 +15,6 @@
<table class="table table-striped table-bordered"> <table class="table table-striped table-bordered">
<thead> <thead>
<tr> <tr>
<th width="15">#</th>
<th> <th>
<a href="{% url 'abonapp:people_list' abon_group.id %}?order_by=username&dir={{ dir|default:"down" }}"> <a href="{% url 'abonapp:people_list' abon_group.id %}?order_by=username&dir={{ dir|default:"down" }}">
Абонент Абонент
@ -34,14 +33,26 @@
</a> </a>
{% if order_by == 'fio' %}<span class="glyphicon glyphicon-filter"></span>{% endif %} {% if order_by == 'fio' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th> </th>
<th>
<a herf="{% url 'abonapp:people_list' abon_group.id %}?order_by=street&dir={{ dir|default:"down" }}">
Улица
</a>
{% if order_by == 'street' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th width="100">
<a herf="{% url 'abonapp:people_list' abon_group.id %}?order_by=house&dir={{ dir|default:"down" }}">
дом/кв
</a>
{% if order_by == 'house' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th width="150">Телефон</th>
<th width="150">Тариф</th>
<th width="50"> <th width="50">
<a href="{% url 'abonapp:people_list' abon_group.id %}?order_by=ballance&dir={{ dir|default:"down" }}"> <a href="{% url 'abonapp:people_list' abon_group.id %}?order_by=ballance&dir={{ dir|default:"down" }}">
Балланс Балланс
</a> </a>
{% if order_by == 'ballance' %}<span class="glyphicon glyphicon-filter"></span>{% endif %} {% if order_by == 'ballance' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th> </th>
<th width="150">Телефон</th>
<th width="150">Тариф</th>
<th width="100">Do</th> <th width="100">Do</th>
</tr> </tr>
</thead> </thead>
@ -52,11 +63,11 @@
{% else %} {% else %}
<tr class="danger"> <tr class="danger">
{% endif %} {% endif %}
<td>{{ human.id }}</td>
<td><a href="{% url 'abonapp:abon_home' human.group.id human.id %}">{{ human.username }}</a></td> <td><a href="{% url 'abonapp:abon_home' human.group.id human.id %}">{{ human.username }}</a></td>
<td>{{ human.ip_address|default:'Не назначен' }}</td> <td>{{ human.ip_address|default:'Не назначен' }}</td>
<td>{{ human.fio }}</td> <td>{{ human.fio }}</td>
<td>{{ human.ballance }}</td>
<td>{{ human.street|default:'Не указан' }}</td>
<td>{{ human.house|default:'Не указан' }}</td>
<td><a href="tel:{{ human.telephone }}">{{ human.telephone }}</a></td> <td><a href="tel:{{ human.telephone }}">{{ human.telephone }}</a></td>
<td> <td>
{% if human.active_tariff %} {% if human.active_tariff %}
@ -64,13 +75,14 @@
{% else %}&mdash;&mdash;&mdash; {% else %}&mdash;&mdash;&mdash;
{% endif %} {% endif %}
</td> </td>
<td>{{ human.ballance }}</td>
<td><a href="{% url 'abonapp:del_abon' %}?t=a&id={{ human.id }}" class="btn btn-danger btn-sm"> <td><a href="{% url 'abonapp:del_abon' %}?t=a&id={{ human.id }}" class="btn btn-danger btn-sm">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</a></td> </a></td>
</tr> </tr>
{% empty %} {% empty %}
<tr> <tr>
<td colspan="8">
<td colspan="9">
Ещё нет абонентов, <a href="{% url 'abonapp:add_abon' abon_group.id %}">добавить</a> Ещё нет абонентов, <a href="{% url 'abonapp:add_abon' abon_group.id %}">добавить</a>
</td> </td>
</tr> </tr>
@ -78,7 +90,7 @@
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="8" class="btn-group">
<td colspan="9" class="btn-group">
{% if perms.abonapp.add_abon %} {% if perms.abonapp.add_abon %}
<a href="{% url 'abonapp:add_abon' abon_group.id %}" class="btn btn-sm btn-default" title="Добавить"> <a href="{% url 'abonapp:add_abon' abon_group.id %}" class="btn btn-sm btn-default" title="Добавить">
<span class="glyphicon glyphicon-plus"></span> Добавить абонента <span class="glyphicon glyphicon-plus"></span> Добавить абонента

2
templates/accounts/ext.htm

@ -47,7 +47,7 @@
</li> </li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="livetab_content">
<div class="tab-pane active">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
</div> </div>

2
templates/accounts/settings/ext.htm

@ -44,7 +44,7 @@
{% endif %} {% endif %}
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="livetab_content">
<div class="tab-pane active">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
</div> </div>

2
templates/devapp/ext.htm

@ -29,7 +29,7 @@
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="livetab_content">
<div class="tab-pane active">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
</div> </div>

8
templates/taskapp/add_edit_task.html

@ -30,14 +30,6 @@
{{ form.descr }}{{ form.descr.errors }} {{ form.descr }}{{ form.descr.errors }}
</div> </div>
</div> </div>
<!--<div class="form-group">
<label for="id_device">С каким устройством связано</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-hdd"></span></span>
{ { form.device }}{ { form.device.errors }}
</div>
</div>-->
<div class="form-group"> <div class="form-group">
<label for="id_mode">Характер поломки</label> <label for="id_mode">Характер поломки</label>

2
templates/taskapp/ext.htm

@ -53,7 +53,7 @@
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="livetab_content">
<div class="tab-pane active">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
</div> </div>

Loading…
Cancel
Save