diff --git a/abonapp/admin.py b/abonapp/admin.py
index c3e76ef..082d3d8 100644
--- a/abonapp/admin.py
+++ b/abonapp/admin.py
@@ -14,3 +14,4 @@ admin.site.register(models.AbonRawPassword)
admin.site.register(models.ExtraFieldsModel)
admin.site.register(models.AllPayLog)
admin.site.register(models.PassportInfo)
+admin.site.register(models.AdditionalTelephone)
diff --git a/abonapp/forms.py b/abonapp/forms.py
index b9e11d4..36fa6b5 100644
--- a/abonapp/forms.py
+++ b/abonapp/forms.py
@@ -6,6 +6,10 @@ from django.contrib.auth.hashers import make_password
from random import choice
from string import digits, ascii_lowercase
from . import models
+from django.conf import settings
+
+
+TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^\+[7,8,9,3]\d{10,11}$')
def generate_random_username(length=6, chars=digits, split=2, delimiter=''):
@@ -57,7 +61,7 @@ class AbonForm(forms.ModelForm):
}),
'telephone': forms.TextInput(attrs={
'placeholder': _('telephone placeholder'),
- 'pattern': r'^\+[7,8,9,3]\d{10,11}$',
+ 'pattern': TELEPHONE_REGEXP,
'required': '',
'class': 'form-control'
}),
@@ -131,3 +135,18 @@ class AbonStreetForm(forms.ModelForm):
'name': forms.TextInput(attrs={'class': 'form-control', 'required':'', 'autofocus':''}),
'group': forms.Select(attrs={'class': 'form-control'})
}
+
+
+class AdditionalTelephoneForm(forms.ModelForm):
+ class Meta:
+ model = models.AdditionalTelephone
+ exclude = ['abon']
+ widgets = {
+ 'telephone': forms.TextInput(attrs={
+ 'placeholder': _('telephone placeholder'),
+ 'pattern': TELEPHONE_REGEXP,
+ 'required': '',
+ 'class': 'form-control'
+ }),
+ 'owner_name': forms.TextInput(attrs={'class': 'form-control', 'required':''})
+ }
diff --git a/abonapp/locale/ru/LC_MESSAGES/django.po b/abonapp/locale/ru/LC_MESSAGES/django.po
index 7e81d54..1e734a0 100644
--- a/abonapp/locale/ru/LC_MESSAGES/django.po
+++ b/abonapp/locale/ru/LC_MESSAGES/django.po
@@ -339,7 +339,7 @@ msgstr "куда"
#: abonapp/templates/abonapp/dial_log.html:12
msgid "duration"
-msgstr "продолжительность"
+msgstr "прод."
#: abonapp/templates/abonapp/dial_log.html:13
msgid "start"
@@ -389,10 +389,6 @@ msgstr "Дом"
msgid "Is active"
msgstr "Активен"
-#: abonapp/templates/abonapp/editAbon.html:106
-msgid "Send account info to user"
-msgstr "Отправить данные абоненту"
-
#: abonapp/templates/abonapp/editAbon.html:109
#: abonapp/templates/abonapp/editAbon.html:110
#, fuzzy
@@ -473,7 +469,7 @@ msgstr "Принадлежность услуг к группам"
#: abonapp/templates/abonapp/invoiceForPayment.html:10
#: abonapp/templates/abonapp/payHistory.html:39
msgid "Debts"
-msgstr "Долги"
+msgstr "Квитанции (долги)"
#: abonapp/templates/abonapp/invoiceForPayment.html:15
msgid "Debtor"
@@ -606,10 +602,6 @@ msgstr "Балланс"
msgid "Subscribers not found"
msgstr "Абоненты не найдены"
-#: abonapp/templates/abonapp/peoples.html:130
-msgid "Refresh subscribers on NAS"
-msgstr "Обновить абонентов в NAS"
-
#: abonapp/templates/abonapp/peoples.html:133
msgid "Tariffs in groups"
msgstr "Тарифы в группах"
@@ -736,10 +728,6 @@ msgstr "Адрес"
msgid "delete abon success msg"
msgstr "Абонент успешно удалён"
-#: abonapp/views.py:180
-msgid "I not know what to delete"
-msgstr "Не понятно что удалять"
-
#: abonapp/views.py:184
#, python-format
msgid "NAS says: '%s'"
@@ -951,3 +939,69 @@ msgstr "Пользователь, который не является перс
msgid "Ip not passed"
msgstr "Ip адрес не передан"
+
+msgid "Additional telephone"
+msgstr "Дополнительный телефон"
+
+msgid "Additional telephones"
+msgstr "Дополнительные телефоны"
+
+msgid "Abon group"
+msgstr "Группа абонентов"
+
+msgid "Abon groups"
+msgstr "Группы абонентов"
+
+msgid "Abon service"
+msgstr "Услуга абонента"
+
+msgid "Abon services"
+msgstr "Услуги абонентов"
+
+msgid "Abon"
+msgstr "Абонент"
+
+msgid "Abons"
+msgstr "Абоненты"
+
+msgid "New telephone has been saved"
+msgstr "Новый телефон сохранен"
+
+msgid "Add telephone"
+msgstr "Добавить номер телефона"
+
+msgid "Telephone owner"
+msgstr "Владелец телефона"
+
+msgid "Additional telephones not found"
+msgstr "Дополнительные телефоны не найдены"
+
+msgid "Additional telephone successfully deleted"
+msgstr "Номер телефона успешно удалён"
+
+msgid "Telephone not found"
+msgstr "Телефон не найден"
+
+msgid "Can view subscriber group"
+msgstr "Может просматривать группу абонентов"
+
+msgid "Permission denied"
+msgstr "Доступ запрещён"
+
+msgid "Can view subscriber logs"
+msgstr "Может видеть логи абонента"
+
+msgid "Can view invoice for payment"
+msgstr "Может видеть назначенные платежи"
+
+msgid "Debt"
+msgstr "Квитанция (долг)"
+
+msgid "Passport Info"
+msgstr "Паспортные данные"
+
+msgid "Can ping"
+msgstr "Может пинговать"
+
+msgid "Can view additional telephones"
+msgstr "Может видеть дополнительные телефоны"
diff --git a/abonapp/migrations/0001_initial.py b/abonapp/migrations/0001_initial.py
deleted file mode 100644
index 7b1368f..0000000
--- a/abonapp/migrations/0001_initial.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2016-06-28 23:51
-
-from django.conf import settings
-import django.core.validators
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
- initial = True
-
- dependencies = [
- ('accounts_app', '0001_initial'),
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('tariff_app', '0001_initial'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Abon',
- fields=[
- ('userprofile_ptr',
- models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True,
- primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
- ('ballance', models.FloatField(default=0.0, validators=[django.core.validators.DecimalValidator])),
- ('address', models.CharField(max_length=256)),
- ],
- options={
- 'db_table': 'abonent',
- },
- bases=('accounts_app.userprofile',),
- ),
- migrations.CreateModel(
- name='AbonGroup',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('title', models.CharField(max_length=127)),
- ('address', models.CharField(blank=True, max_length=256, null=True)),
- ],
- options={
- 'db_table': 'abonent_groups',
- },
- ),
- migrations.CreateModel(
- name='AbonLog',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('amount', models.FloatField(default=0.0)),
- ('comment', models.CharField(max_length=128)),
- ('date', models.DateTimeField(auto_now_add=True)),
- ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')),
- ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+',
- to=settings.AUTH_USER_MODEL)),
- ],
- options={
- 'db_table': 'abonent_log',
- },
- ),
- migrations.CreateModel(
- name='AbonTariff',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('tariff_priority', models.PositiveSmallIntegerField(default=0)),
- ('time_start', models.DateTimeField(blank=True, default=None, null=True)),
- ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')),
- ('tariff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='linkto_tariff',
- to='tariff_app.Tariff')),
- ],
- options={
- 'ordering': ('tariff_priority',),
- 'db_table': 'abonent_tariff',
- },
- ),
- migrations.CreateModel(
- name='InvoiceForPayment',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('status', models.BooleanField(default=False)),
- ('amount', models.FloatField(default=0.0)),
- ('comment', models.CharField(max_length=128)),
- ('date_create', models.DateTimeField(auto_now_add=True)),
- ('date_pay', models.DateTimeField(blank=True, null=True)),
- ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')),
- ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+',
- to=settings.AUTH_USER_MODEL)),
- ],
- options={
- 'ordering': ('date_create',),
- 'db_table': 'abonent_inv_pay',
- },
- ),
- migrations.AddField(
- model_name='abon',
- name='current_tariffs',
- field=models.ManyToManyField(through='abonapp.AbonTariff', to='tariff_app.Tariff'),
- ),
- migrations.AddField(
- model_name='abon',
- name='group',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
- to='abonapp.AbonGroup'),
- ),
- migrations.AlterUniqueTogether(
- name='abontariff',
- unique_together={('abon', 'tariff', 'tariff_priority')},
- ),
- ]
diff --git a/abonapp/migrations/0001_squashed_0022_auto_20170816_1109.py b/abonapp/migrations/0001_squashed_0022_auto_20170816_1109.py
new file mode 100644
index 0000000..89e222c
--- /dev/null
+++ b/abonapp/migrations/0001_squashed_0022_auto_20170816_1109.py
@@ -0,0 +1,318 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2017-09-04 16:15
+from __future__ import unicode_literals
+
+from django.conf import settings
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import mydefs
+import re
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('devapp', '0001_squashed_0007_auto_20170816_1109'),
+ ('tariff_app', '0002_tariff_descr'),
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('accounts_app', '0001_initial'),
+ ('tariff_app', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Abon',
+ fields=[
+ ('userprofile_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
+ ('ballance', models.FloatField(default=0.0, validators=[django.core.validators.DecimalValidator])),
+ ('address', models.CharField(max_length=256)),
+ ],
+ options={
+ 'db_table': 'abonent',
+ },
+ bases=('accounts_app.userprofile',),
+ ),
+ migrations.CreateModel(
+ name='AbonGroup',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=127, unique=True)),
+ ],
+ options={
+ 'db_table': 'abonent_groups',
+ },
+ ),
+ migrations.CreateModel(
+ name='AbonLog',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('amount', models.FloatField(default=0.0)),
+ ('comment', models.CharField(max_length=128)),
+ ('date', models.DateTimeField(auto_now_add=True)),
+ ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')),
+ ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)),
+ ],
+ options={
+ 'db_table': 'abonent_log',
+ },
+ ),
+ migrations.CreateModel(
+ name='AbonTariff',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('tariff_priority', models.PositiveSmallIntegerField(default=0)),
+ ('time_start', models.DateTimeField(blank=True, default=None, null=True)),
+ ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')),
+ ('tariff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='linkto_tariff', to='tariff_app.Tariff')),
+ ],
+ options={
+ 'ordering': ('tariff_priority',),
+ 'db_table': 'abonent_tariff',
+ },
+ ),
+ migrations.CreateModel(
+ name='InvoiceForPayment',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('status', models.BooleanField(default=False)),
+ ('amount', models.FloatField(default=0.0)),
+ ('comment', models.CharField(max_length=128)),
+ ('date_create', models.DateTimeField(auto_now_add=True)),
+ ('date_pay', models.DateTimeField(blank=True, null=True)),
+ ('abon', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')),
+ ('author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
+ ],
+ options={
+ 'ordering': ('date_create',),
+ 'db_table': 'abonent_inv_pay',
+ },
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='current_tariffs',
+ field=models.ManyToManyField(through='abonapp.AbonTariff', to='tariff_app.Tariff'),
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='group',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonGroup'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='abontariff',
+ unique_together=set([('abon', 'tariff', 'tariff_priority')]),
+ ),
+ migrations.AddField(
+ model_name='abongroup',
+ name='profiles',
+ field=models.ManyToManyField(blank=True, related_name='abon_groups', to=settings.AUTH_USER_MODEL),
+ ),
+ migrations.AlterModelOptions(
+ name='abon',
+ options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'),)},
+ ),
+ migrations.AlterModelOptions(
+ name='abongroup',
+ options={'permissions': (('can_add_ballance', 'Пополнение счёта'),)},
+ ),
+ migrations.AlterModelOptions(
+ name='abontariff',
+ options={'ordering': ('tariff_priority',), 'permissions': (('can_complete_service', 'Досрочное завершение услуги абонента'), ('can_activate_service', 'Активация услуги абонента'))},
+ ),
+ migrations.CreateModel(
+ name='AbonStreet',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=64)),
+ ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.AbonGroup')),
+ ],
+ ),
+ migrations.RemoveField(
+ model_name='abon',
+ name='address',
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='description',
+ field=models.TextField(blank=True, null=True),
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='house',
+ field=models.CharField(blank=True, max_length=12, null=True),
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='street',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonStreet'),
+ ),
+ migrations.CreateModel(
+ name='AllPayLog',
+ fields=[
+ ('pay_id', models.CharField(max_length=64, primary_key=True, serialize=False)),
+ ('date_action', models.DateTimeField(auto_now_add=True)),
+ ('summ', models.FloatField(default=0.0)),
+ ('pay_system_name', models.CharField(max_length=16)),
+ ],
+ options={
+ 'db_table': 'all_pay_log',
+ 'ordering': ('date_action',),
+ },
+ ),
+ migrations.CreateModel(
+ name='AllTimePayLog',
+ fields=[
+ ('pay_id', models.CharField(max_length=36, primary_key=True, serialize=False, unique=True)),
+ ('date_add', models.DateTimeField(auto_now_add=True)),
+ ('summ', models.FloatField(default=0.0)),
+ ],
+ options={
+ 'db_table': 'all_time_pay_log',
+ 'ordering': ('date_add',),
+ },
+ ),
+ migrations.CreateModel(
+ name='AbonRawPassword',
+ fields=[
+ ('account', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='abonapp.Abon')),
+ ('passw_text', models.CharField(max_length=64)),
+ ],
+ options={
+ 'db_table': 'abon_raw_password',
+ },
+ ),
+ migrations.AlterModelTable(
+ name='abonstreet',
+ table='abon_street',
+ ),
+ migrations.AddField(
+ model_name='abontariff',
+ name='deadline',
+ field=models.DateTimeField(blank=True, default=None, null=True),
+ ),
+ migrations.CreateModel(
+ name='ExtraFieldsModel',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('field_type', models.CharField(choices=[('int', 'Цифровое поле'), ('str', 'Текстовое поле'), ('dbl', 'Дробное с плавающей точкой'), ('ipa', 'IP Адрес')], default='str', max_length=3)),
+ ('data', models.CharField(blank=True, max_length=64, null=True)),
+ ('title', models.CharField(default='no title', max_length=16)),
+ ],
+ options={
+ 'db_table': 'abon_extra_fields',
+ },
+ ),
+ migrations.AlterModelOptions(
+ name='abon',
+ options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Can view passport'))},
+ ),
+ migrations.AlterModelOptions(
+ name='abontariff',
+ options={'ordering': ('tariff_priority',), 'permissions': (('can_complete_service', 'Снятие со счёта средств'), ('can_activate_service', 'Активация услуги абонента'))},
+ ),
+ migrations.AlterField(
+ model_name='abon',
+ name='ballance',
+ field=models.FloatField(default=0.0),
+ ),
+ migrations.AlterModelOptions(
+ name='abon',
+ options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Может просматривать паспортные данные'))},
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='extra_fields',
+ field=models.ManyToManyField(blank=True, to='abonapp.ExtraFieldsModel'),
+ ),
+ migrations.AddField(
+ model_name='abongroup',
+ name='tariffs',
+ field=models.ManyToManyField(blank=True, related_name='tariff_groups', to='tariff_app.Tariff'),
+ ),
+ migrations.CreateModel(
+ name='PassportInfo',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('series', models.CharField(max_length=4, validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z', 32), code='invalid', message='Enter a valid integer.')])),
+ ('number', models.CharField(max_length=6, validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z', 32), code='invalid', message='Enter a valid integer.')])),
+ ('distributor', models.CharField(max_length=64)),
+ ('date_of_acceptance', models.DateField()),
+ ('abon', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.Abon')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='AbonDevice',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('abon', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')),
+ ('device', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device')),
+ ],
+ options={
+ 'db_table': 'abon_device',
+ },
+ ),
+ migrations.AlterUniqueTogether(
+ name='abondevice',
+ unique_together=set([('abon', 'device')]),
+ ),
+ migrations.AlterField(
+ model_name='abondevice',
+ name='abon',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon'),
+ ),
+ migrations.AlterField(
+ model_name='abondevice',
+ name='device',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device'),
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='ip_address',
+ field=mydefs.MyGenericIPAddressField(blank=True, max_length=8, null=True, protocol='ipv4'),
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='dev_port',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Port'),
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='device',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Device'),
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='is_dynamic_ip',
+ field=models.BooleanField(default=False),
+ ),
+ migrations.DeleteModel(
+ name='AbonDevice',
+ ),
+ migrations.AlterModelOptions(
+ name='abontariff',
+ options={'permissions': (('can_complete_service', 'Снятие со счёта средств'),)},
+ ),
+ migrations.RemoveField(
+ model_name='abon',
+ name='current_tariffs',
+ ),
+ migrations.AddField(
+ model_name='abon',
+ name='current_tariff',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonTariff'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='abontariff',
+ unique_together=set([]),
+ ),
+ migrations.RemoveField(
+ model_name='abontariff',
+ name='abon',
+ ),
+ migrations.RemoveField(
+ model_name='abontariff',
+ name='tariff_priority',
+ ),
+ ]
diff --git a/abonapp/migrations/0002_auto_20161206_2135.py b/abonapp/migrations/0002_auto_20161206_2135.py
deleted file mode 100644
index a865928..0000000
--- a/abonapp/migrations/0002_auto_20161206_2135.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2016-12-06 18:35
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0001_initial'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='abongroup',
- name='address',
- ),
- migrations.AlterField(
- model_name='abongroup',
- name='title',
- field=models.CharField(max_length=127, unique=True),
- ),
- ]
diff --git a/abonapp/migrations/0002_auto_20170905_1248.py b/abonapp/migrations/0002_auto_20170905_1248.py
new file mode 100644
index 0000000..75bbac0
--- /dev/null
+++ b/abonapp/migrations/0002_auto_20170905_1248.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2017-09-05 12:48
+from __future__ import unicode_literals
+
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('abonapp', '0001_squashed_0022_auto_20170816_1109'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='AdditionalTelephone',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('telephone', models.CharField(max_length=16, validators=[django.core.validators.RegexValidator('^\\+[7,8,9,3]\\d{10,11}$')], verbose_name='Телефон')),
+ ('owner_name', models.CharField(max_length=127)),
+ ],
+ options={
+ 'verbose_name': 'Дополнительный телефон',
+ 'verbose_name_plural': 'Дополнительные телефоны',
+ 'db_table': 'additional_telephones',
+ 'ordering': ('owner_name',),
+ },
+ ),
+ migrations.AlterModelOptions(
+ name='abon',
+ options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Может просматривать паспортные данные')), 'verbose_name': 'Абонент', 'verbose_name_plural': 'Абоненты'},
+ ),
+ migrations.AlterModelOptions(
+ name='abongroup',
+ options={'permissions': (('can_add_ballance', 'Пополнение счёта'),), 'verbose_name': 'Группа абонентов', 'verbose_name_plural': 'Группы абонентов'},
+ ),
+ migrations.AlterModelOptions(
+ name='abonstreet',
+ options={'verbose_name': 'Улица', 'verbose_name_plural': 'Улицы'},
+ ),
+ migrations.AlterModelOptions(
+ name='abontariff',
+ options={'permissions': (('can_complete_service', 'Снятие со счёта средств'),), 'verbose_name': 'Услуга абонента', 'verbose_name_plural': 'Услуги абонентов'},
+ ),
+ migrations.AddField(
+ model_name='additionaltelephone',
+ name='abon',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='additional_telephones', to='abonapp.Abon'),
+ ),
+ ]
diff --git a/abonapp/migrations/0003_abongroup_profiles.py b/abonapp/migrations/0003_abongroup_profiles.py
deleted file mode 100644
index f3b2d91..0000000
--- a/abonapp/migrations/0003_abongroup_profiles.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2016-12-16 19:14
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('abonapp', '0002_auto_20161206_2135'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='abongroup',
- name='profiles',
- field=models.ManyToManyField(related_name='abon_groups', to=settings.AUTH_USER_MODEL),
- ),
- ]
diff --git a/abonapp/migrations/0003_auto_20170927_1838.py b/abonapp/migrations/0003_auto_20170927_1838.py
new file mode 100644
index 0000000..f15a614
--- /dev/null
+++ b/abonapp/migrations/0003_auto_20170927_1838.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2017-09-27 18:38
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('abonapp', '0002_auto_20170905_1248'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='abon',
+ options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Может просматривать паспортные данные'), ('can_add_ballance', 'Пополнение счёта'), ('can_ping', 'Может пинговать')), 'verbose_name': 'Абонент', 'verbose_name_plural': 'Абоненты'},
+ ),
+ migrations.AlterModelOptions(
+ name='abongroup',
+ options={'permissions': (('can_view_abongroup', 'Может просматривать группу абонентов'),), 'verbose_name': 'Группа абонентов', 'verbose_name_plural': 'Группы абонентов'},
+ ),
+ migrations.AlterModelOptions(
+ name='abonlog',
+ options={'permissions': (('can_view_abonlog', 'Может видеть логи абонента'),)},
+ ),
+ migrations.AlterModelOptions(
+ name='additionaltelephone',
+ options={'ordering': ('owner_name',), 'permissions': (('can_view_additionaltelephones', 'Может видеть дополнительные телефоны'),), 'verbose_name': 'Дополнительный телефон', 'verbose_name_plural': 'Дополнительные телефоны'},
+ ),
+ migrations.AlterModelOptions(
+ name='invoiceforpayment',
+ options={'ordering': ('date_create',), 'permissions': (('can_view_invoiceforpayment', 'Может видеть назначенные платежи'),), 'verbose_name': 'Квитанция (долг)', 'verbose_name_plural': 'Квитанции (долги)'},
+ ),
+ migrations.AlterModelOptions(
+ name='passportinfo',
+ options={'verbose_name': 'Паспортные данные', 'verbose_name_plural': 'Паспортные данные'},
+ ),
+ migrations.AlterModelTable(
+ name='passportinfo',
+ table='passport_info',
+ ),
+ ]
diff --git a/abonapp/migrations/0004_auto_20161220_0102.py b/abonapp/migrations/0004_auto_20161220_0102.py
deleted file mode 100644
index b19ca18..0000000
--- a/abonapp/migrations/0004_auto_20161220_0102.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2016-12-19 22:02
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0003_abongroup_profiles'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='abongroup',
- name='profiles',
- field=models.ManyToManyField(blank=True, related_name='abon_groups', to=settings.AUTH_USER_MODEL),
- ),
- ]
diff --git a/abonapp/migrations/0005_auto_20161226_0054.py b/abonapp/migrations/0005_auto_20161226_0054.py
deleted file mode 100644
index 3b206ae..0000000
--- a/abonapp/migrations/0005_auto_20161226_0054.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2016-12-25 21:54
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0004_auto_20161220_0102'),
- ]
-
- operations = [
- migrations.AlterModelOptions(
- name='abon',
- options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'),)},
- ),
- migrations.AlterModelOptions(
- name='abongroup',
- options={'permissions': (('can_add_ballance', 'Пополнение счёта'),)},
- ),
- migrations.AlterModelOptions(
- name='abontariff',
- options={'ordering': ('tariff_priority',), 'permissions': (('can_complete_service', 'Досрочное завершение услуги абонента'), ('can_activate_service', 'Активация услуги абонента'))},
- ),
- ]
diff --git a/abonapp/migrations/0006_auto_20170128_1626.py b/abonapp/migrations/0006_auto_20170128_1626.py
deleted file mode 100644
index 6274a5d..0000000
--- a/abonapp/migrations/0006_auto_20170128_1626.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-01-28 13:26
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0005_auto_20161226_0054'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='AbonStreets',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=64)),
- ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.AbonGroup')),
- ],
- ),
- migrations.RemoveField(
- model_name='abon',
- name='address',
- ),
- migrations.AddField(
- model_name='abon',
- name='description',
- field=models.TextField(blank=True, null=True),
- ),
- migrations.AddField(
- model_name='abon',
- name='house',
- field=models.CharField(blank=True, max_length=12, null=True),
- ),
- migrations.AddField(
- model_name='abon',
- name='street',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonStreets'),
- ),
- ]
diff --git a/abonapp/migrations/0007_auto_20170131_1650.py b/abonapp/migrations/0007_auto_20170131_1650.py
deleted file mode 100644
index c1f4ae5..0000000
--- a/abonapp/migrations/0007_auto_20170131_1650.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-01-31 13:50
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0006_auto_20170128_1626'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='AllPayLog',
- fields=[
- ('pay_id', models.CharField(max_length=64, primary_key=True, serialize=False)),
- ('date_action', models.DateTimeField(auto_now_add=True)),
- ('summ', models.FloatField(default=0.0)),
- ('pay_system_name', models.CharField(max_length=16)),
- ],
- options={
- 'db_table': 'all_pay_log',
- 'ordering': ('date_action',),
- },
- ),
- migrations.CreateModel(
- name='AllTimePayLog',
- fields=[
- ('pay_id', models.CharField(max_length=36, primary_key=True, serialize=False, unique=True)),
- ('date_add', models.DateTimeField(auto_now_add=True)),
- ('summ', models.FloatField(default=0.0)),
- ],
- options={
- 'db_table': 'all_time_pay_log',
- 'ordering': ('date_add',),
- },
- ),
- migrations.RenameModel(
- old_name='AbonStreets',
- new_name='AbonStreet',
- ),
- ]
diff --git a/abonapp/migrations/0008_auto_20170209_0002.py b/abonapp/migrations/0008_auto_20170209_0002.py
deleted file mode 100644
index 8d24b5d..0000000
--- a/abonapp/migrations/0008_auto_20170209_0002.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-02-08 21:02
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0007_auto_20170131_1650'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='AbonRawPassword',
- fields=[
- ('account', models.OneToOneField(primary_key=True, serialize=False, to='abonapp.Abon')),
- ('passw_text', models.CharField(max_length=64)),
- ],
- options={
- 'db_table': 'abon_raw_password',
- },
- ),
- migrations.AlterModelTable(
- name='abonstreet',
- table='abon_street',
- ),
- ]
diff --git a/abonapp/migrations/0009_abontariff_death_line.py b/abonapp/migrations/0009_abontariff_death_line.py
deleted file mode 100644
index 1152d33..0000000
--- a/abonapp/migrations/0009_abontariff_death_line.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-02-16 12:22
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0008_auto_20170209_0002'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='abontariff',
- name='deadline',
- field=models.DateTimeField(blank=True, default=None, null=True),
- ),
- ]
diff --git a/abonapp/migrations/0010_auto_20170220_1630.py b/abonapp/migrations/0010_auto_20170220_1630.py
deleted file mode 100644
index 69718b8..0000000
--- a/abonapp/migrations/0010_auto_20170220_1630.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-02-20 13:30
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0009_abontariff_death_line'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='ExtraFieldsModel',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('field_type', models.CharField(choices=[('int', 'Digital field'), ('str', 'Text field'), ('dbl', 'Floating field')], max_length=3)),
- ('data', models.CharField(blank=True, max_length=64, null=True)),
- ],
- options={
- 'db_table': 'abon_extra_fields',
- },
- ),
- migrations.AlterModelOptions(
- name='abon',
- options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Can view passport'))},
- ),
- migrations.AlterModelOptions(
- name='abontariff',
- options={'ordering': ('tariff_priority',), 'permissions': (('can_complete_service', 'Снятие со счёта средств'), ('can_activate_service', 'Активация услуги абонента'))},
- ),
- migrations.AlterField(
- model_name='abon',
- name='ballance',
- field=models.FloatField(default=0.0),
- ),
- migrations.AddField(
- model_name='extrafieldsmodel',
- name='account',
- field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='abonapp.Abon'),
- ),
- ]
diff --git a/abonapp/migrations/0011_auto_20170222_2224.py b/abonapp/migrations/0011_auto_20170222_2224.py
deleted file mode 100644
index d197189..0000000
--- a/abonapp/migrations/0011_auto_20170222_2224.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-02-22 19:24
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0010_auto_20170220_1630'),
- ]
-
- operations = [
- migrations.AlterModelOptions(
- name='abon',
- options={'permissions': (('can_buy_tariff', 'Покупка тарифа абоненту'), ('can_view_passport', 'Может просматривать паспортные данные'))},
- ),
- migrations.AlterField(
- model_name='extrafieldsmodel',
- name='field_type',
- field=models.CharField(choices=[('int', 'Цифровое поле'), ('str', 'Текстовое поле'), ('dbl', 'Дробное с плавающей точкой')], max_length=3),
- ),
- ]
diff --git a/abonapp/migrations/0012_auto_20170227_1718.py b/abonapp/migrations/0012_auto_20170227_1718.py
deleted file mode 100644
index 63a66de..0000000
--- a/abonapp/migrations/0012_auto_20170227_1718.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-03-02 18:41
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0011_auto_20170222_2224'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='extrafieldsmodel',
- name='account',
- ),
- migrations.AddField(
- model_name='abon',
- name='extra_fields',
- field=models.ManyToManyField(to='abonapp.ExtraFieldsModel'),
- ),
- ]
diff --git a/abonapp/migrations/0013_abongroup_tariffs.py b/abonapp/migrations/0013_abongroup_tariffs.py
deleted file mode 100644
index b67ffbd..0000000
--- a/abonapp/migrations/0013_abongroup_tariffs.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-03-21 11:30
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('tariff_app', '0002_tariff_descr'),
- ('abonapp', '0012_auto_20170227_1718'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='abongroup',
- name='tariffs',
- field=models.ManyToManyField(blank=True, related_name='tariff_groups', to='tariff_app.Tariff'),
- ),
- ]
diff --git a/abonapp/migrations/0014_auto_20170330_1452.py b/abonapp/migrations/0014_auto_20170330_1452.py
deleted file mode 100644
index c0985ab..0000000
--- a/abonapp/migrations/0014_auto_20170330_1452.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-03-30 11:52
-from __future__ import unicode_literals
-
-import django.db.models.deletion
-import djing.fields
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0013_abongroup_tariffs'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Opt82',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('mac', djing.fields.MACAddressField(integer=True)),
- ('port', models.PositiveSmallIntegerField(default=0)),
- ],
- options={
- 'db_table': 'opt_82',
- },
- ),
- migrations.AlterField(
- model_name='abon',
- name='extra_fields',
- field=models.ManyToManyField(blank=True, to='abonapp.ExtraFieldsModel'),
- ),
- migrations.AlterUniqueTogether(
- name='opt82',
- unique_together=set([('mac', 'port')]),
- ),
- migrations.AddField(
- model_name='abon',
- name='opt82',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='abonapp.Opt82'),
- ),
- ]
diff --git a/abonapp/migrations/0015_passportinfo.py b/abonapp/migrations/0015_passportinfo.py
deleted file mode 100644
index 5207173..0000000
--- a/abonapp/migrations/0015_passportinfo.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-04-11 10:43
-from __future__ import unicode_literals
-
-import django.core.validators
-from django.db import migrations, models
-import django.db.models.deletion
-import re
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0014_auto_20170330_1452'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='PassportInfo',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('series', models.CharField(max_length=4, validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z', 32), code='invalid', message='Enter a valid integer.')])),
- ('number', models.CharField(max_length=6, validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z', 32), code='invalid', message='Enter a valid integer.')])),
- ('distributor', models.CharField(max_length=64)),
- ('date_of_acceptance', models.DateField()),
- ('abon', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.Abon')),
- ],
- ),
- migrations.AlterField(
- model_name='abon',
- name='opt82',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
- to='abonapp.Opt82'),
- )
- ]
diff --git a/abonapp/migrations/0016_auto_20170415_1311.py b/abonapp/migrations/0016_auto_20170415_1311.py
deleted file mode 100644
index 4070341..0000000
--- a/abonapp/migrations/0016_auto_20170415_1311.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-04-15 10:11
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('devapp', '0004_device_user_group'),
- ('abonapp', '0015_passportinfo'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='AbonDevice',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('abon', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon')),
- ('device', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device')),
- ],
- options={
- 'db_table': 'abon_device',
- },
- ),
- migrations.AlterUniqueTogether(
- name='abondevice',
- unique_together=set([('abon', 'device')]),
- ),
- ]
diff --git a/abonapp/migrations/0017_auto_20170416_1029.py b/abonapp/migrations/0017_auto_20170416_1029.py
deleted file mode 100644
index fb70627..0000000
--- a/abonapp/migrations/0017_auto_20170416_1029.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-04-16 07:29
-from __future__ import unicode_literals
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0016_auto_20170415_1311'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='invoiceforpayment',
- name='author',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
- ),
- ]
diff --git a/abonapp/migrations/0018_auto_20170418_1236.py b/abonapp/migrations/0018_auto_20170418_1236.py
deleted file mode 100644
index 175a62b..0000000
--- a/abonapp/migrations/0018_auto_20170418_1236.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-04-18 09:36
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0017_auto_20170416_1029'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='abondevice',
- name='abon',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='abonapp.Abon'),
- ),
- migrations.AlterField(
- model_name='abondevice',
- name='device',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='devapp.Device'),
- ),
- ]
diff --git a/abonapp/migrations/0019_abon_ip_address.py b/abonapp/migrations/0019_abon_ip_address.py
deleted file mode 100644
index 96c2613..0000000
--- a/abonapp/migrations/0019_abon_ip_address.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-05-10 23:17
-from __future__ import unicode_literals
-
-from django.db import migrations
-import mydefs
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0018_auto_20170418_1236'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='abon',
- name='ip_address',
- field=mydefs.MyGenericIPAddressField(blank=True, max_length=8, null=True, protocol='ipv4'),
- ),
- ]
diff --git a/abonapp/migrations/0020_auto_20170517_1655.py b/abonapp/migrations/0020_auto_20170517_1655.py
deleted file mode 100644
index edcf585..0000000
--- a/abonapp/migrations/0020_auto_20170517_1655.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-05-17 13:55
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0019_abon_ip_address'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='extrafieldsmodel',
- name='title',
- field=models.CharField(default='no title', max_length=16),
- ),
- migrations.AlterField(
- model_name='extrafieldsmodel',
- name='field_type',
- field=models.CharField(choices=[('int', 'Цифровое поле'), ('str', 'Текстовое поле'), ('dbl', 'Дробное с плавающей точкой'), ('ipa', 'IP Адрес')], default='str', max_length=3),
- ),
- ]
diff --git a/abonapp/migrations/0021_auto_20170705_1403.py b/abonapp/migrations/0021_auto_20170705_1403.py
deleted file mode 100644
index 16a2a15..0000000
--- a/abonapp/migrations/0021_auto_20170705_1403.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-07-05 14:03
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('devapp', '0006_auto_20170705_1403'),
- ('abonapp', '0020_auto_20170517_1655'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='abon',
- name='opt82',
- ),
- migrations.DeleteModel(
- name='Opt82',
- ),
- migrations.AddField(
- model_name='abon',
- name='dev_port',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Port'),
- ),
- migrations.AddField(
- model_name='abon',
- name='device',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='devapp.Device'),
- ),
- migrations.AddField(
- model_name='abon',
- name='is_dynamic_ip',
- field=models.BooleanField(default=False),
- ),
- migrations.DeleteModel(
- name='AbonDevice',
- ),
- ]
diff --git a/abonapp/migrations/0022_auto_20170816_1109.py b/abonapp/migrations/0022_auto_20170816_1109.py
deleted file mode 100644
index d514365..0000000
--- a/abonapp/migrations/0022_auto_20170816_1109.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2017-08-16 11:09
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('abonapp', '0021_auto_20170705_1403'),
- ]
-
- operations = [
- migrations.AlterModelOptions(
- name='abontariff',
- options={'permissions': (('can_complete_service', 'Снятие со счёта средств'),)},
- ),
- migrations.RemoveField(
- model_name='abon',
- name='current_tariffs',
- ),
- migrations.AddField(
- model_name='abon',
- name='current_tariff',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abonapp.AbonTariff'),
- ),
- migrations.AlterUniqueTogether(
- name='abontariff',
- unique_together=set([]),
- ),
- migrations.RemoveField(
- model_name='abontariff',
- name='abon',
- ),
- migrations.RemoveField(
- model_name='abontariff',
- name='tariff_priority',
- ),
- ]
diff --git a/abonapp/models.py b/abonapp/models.py
index ce737ea..212ae5c 100644
--- a/abonapp/models.py
+++ b/abonapp/models.py
@@ -1,14 +1,20 @@
# -*- coding: utf-8 -*-
from django.core.exceptions import ValidationError
+from django.core.validators import RegexValidator
+from django.db.models.signals import post_save, post_delete, pre_delete, post_init
+from django.dispatch import receiver
from django.utils import timezone
from django.db import models
from django.core import validators
from django.utils.translation import ugettext as _
from agent import Transmitter, AbonStruct, TariffStruct, NasFailedResult, NasNetworkError
from tariff_app.models import Tariff
-from accounts_app.models import UserProfile
+from accounts_app.models import UserProfile, MyUserManager
from mydefs import MyGenericIPAddressField, ip2int, LogicError, ip_addr_regex
-from djing import settings
+from django.conf import settings
+
+
+TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^\+[7,8,9,3]\d{10,11}$')
class AbonGroup(models.Model):
@@ -19,8 +25,10 @@ class AbonGroup(models.Model):
class Meta:
db_table = 'abonent_groups'
permissions = (
- ('can_add_ballance', _('fill account')),
+ ('can_view_abongroup', _('Can view subscriber group')),
)
+ verbose_name = _('Abon group')
+ verbose_name_plural = _('Abon groups')
def __str__(self):
return self.title
@@ -35,6 +43,9 @@ class AbonLog(models.Model):
class Meta:
db_table = 'abonent_log'
+ permissions = (
+ ('can_view_abonlog', _('Can view subscriber logs')),
+ )
def __str__(self):
return self.comment
@@ -68,6 +79,8 @@ class AbonTariff(models.Model):
permissions = (
('can_complete_service', _('finish service perm')),
)
+ verbose_name = _('Abon service')
+ verbose_name_plural = _('Abon services')
class AbonStreet(models.Model):
@@ -79,6 +92,8 @@ class AbonStreet(models.Model):
class Meta:
db_table = 'abon_street'
+ verbose_name = _('Street')
+ verbose_name_plural = _('Streets')
class ExtraFieldsModel(models.Model):
@@ -123,6 +138,13 @@ class ExtraFieldsModel(models.Model):
db_table = 'abon_extra_fields'
+
+class AbonManager(MyUserManager):
+
+ def get_queryset(self):
+ return super(MyUserManager, self).get_queryset().filter(is_admin=False)
+
+
class Abon(UserProfile):
current_tariff = models.ForeignKey(AbonTariff, null=True, blank=True, on_delete=models.SET_NULL)
group = models.ForeignKey(AbonGroup, models.SET_NULL, blank=True, null=True)
@@ -140,12 +162,18 @@ class Abon(UserProfile):
def active_tariff(self):
return self.current_tariff
+ objects = AbonManager()
+
class Meta:
db_table = 'abonent'
permissions = (
('can_buy_tariff', _('Buy service perm')),
- ('can_view_passport', _('Can view passport'))
+ ('can_view_passport', _('Can view passport')),
+ ('can_add_ballance', _('fill account')),
+ ('can_ping', _('Can ping'))
)
+ verbose_name = _('Abon')
+ verbose_name_plural = _('Abons')
# Платим за что-то
def make_pay(self, curuser, how_match_to_pay=0.0):
@@ -203,6 +231,8 @@ class Abon(UserProfile):
# Производим расчёт услуги абонента, т.е. завершаем если пришло время
def bill_service(self, author):
abon_tariff = self.active_tariff()
+ if abon_tariff is None:
+ return
nw = timezone.now()
# если услуга просрочена
if nw > abon_tariff.deadline:
@@ -226,7 +256,7 @@ class Abon(UserProfile):
return
abon_tariff = self.active_tariff()
if abon_tariff is None:
- agent_trf = TariffStruct()
+ agent_trf = None
else:
trf = abon_tariff.tariff
agent_trf = TariffStruct(trf.id, trf.speedIn, trf.speedOut)
@@ -247,7 +277,12 @@ class PassportInfo(models.Model):
date_of_acceptance = models.DateField()
abon = models.OneToOneField(Abon, on_delete=models.SET_NULL, blank=True, null=True)
- def __unicode__(self):
+ class Meta:
+ db_table = 'passport_info'
+ verbose_name = _('Passport Info')
+ verbose_name_plural = _('Passport Info')
+
+ def __str__(self):
return "%s %s" % (self.series, self.number)
@@ -273,6 +308,11 @@ class InvoiceForPayment(models.Model):
class Meta:
ordering = ('date_create',)
db_table = 'abonent_inv_pay'
+ permissions = (
+ ('can_view_invoiceforpayment', _('Can view invoice for payment')),
+ )
+ verbose_name = _('Debt')
+ verbose_name_plural = _('Debts')
# Log for pay system "AllTime"
@@ -315,7 +355,32 @@ class AbonRawPassword(models.Model):
db_table = 'abon_raw_password'
-def abon_post_save(sender, instance, **kwargs):
+class AdditionalTelephone(models.Model):
+ abon = models.ForeignKey(Abon, related_name='additional_telephones')
+ telephone = models.CharField(
+ max_length=16,
+ verbose_name=_('Telephone'),
+ # unique=True,
+ validators=[RegexValidator(TELEPHONE_REGEXP)]
+ )
+ owner_name = models.CharField(max_length=127)
+
+ def __str__(self):
+ return "%s - (%s)" % (self.owner_name, self.telephone)
+
+ class Meta:
+ db_table = 'additional_telephones'
+ ordering = ('owner_name',)
+ permissions = (
+ ('can_view_additionaltelephones', _('Can view additional telephones')),
+ )
+ verbose_name = _('Additional telephone')
+ verbose_name_plural = _('Additional telephones')
+
+
+@receiver(post_save, sender=Abon)
+def abon_post_save(sender, **kwargs):
+ instance, created = kwargs["instance"], kwargs["created"]
timeout = None
if hasattr(instance, 'is_dhcp') and instance.is_dhcp:
timeout = getattr(settings, 'DHCP_TIMEOUT', 14400)
@@ -324,21 +389,23 @@ def abon_post_save(sender, instance, **kwargs):
return True
try:
tm = Transmitter()
- if kwargs['created']:
+ if created:
# создаём абонента
tm.add_user(agent_abon, ip_timeout=timeout)
else:
# обновляем абонента на NAS
tm.update_user(agent_abon, ip_timeout=timeout)
- except (NasFailedResult, NasNetworkError) as e:
+ except (NasFailedResult, NasNetworkError, ConnectionResetError) as e:
print('ERROR:', e)
return True
-def abon_del_signal(sender, instance, **kwargs):
+@receiver(post_delete, sender=Abon)
+def abon_del_signal(sender, **kwargs):
+ abon = kwargs["instance"]
try:
- ab = instance.build_agent_struct()
+ ab = abon.build_agent_struct()
if ab is None:
return True
# подключаемся к NAS'у
@@ -349,14 +416,28 @@ def abon_del_signal(sender, instance, **kwargs):
return True
-def abon_tariff_post_init(sender, instance, **kwargs):
- if getattr(instance, 'time_start') is None:
- instance.time_start = timezone.now()
- calc_obj = instance.tariff.get_calc_type()(instance)
- if getattr(instance, 'deadline') is None:
- instance.deadline = calc_obj.calc_deadline()
+@receiver(post_init, sender=AbonTariff)
+def abon_tariff_post_init(sender, **kwargs):
+ abon_tariff = kwargs["instance"]
+ if getattr(abon_tariff, 'time_start') is None:
+ abon_tariff.time_start = timezone.now()
+ calc_obj = abon_tariff.tariff.get_calc_type()(abon_tariff)
+ if getattr(abon_tariff, 'deadline') is None:
+ abon_tariff.deadline = calc_obj.calc_deadline()
-models.signals.post_save.connect(abon_post_save, sender=Abon)
-models.signals.post_delete.connect(abon_del_signal, sender=Abon)
-models.signals.post_init.connect(abon_tariff_post_init, sender=AbonTariff)
+@receiver(pre_delete, sender=AbonTariff)
+def abontariff_pre_delete(sender, **kwargs):
+ abon_tariff = kwargs["instance"]
+ try:
+ abon = Abon.objects.get(current_tariff=abon_tariff)
+ ab = abon.build_agent_struct()
+ if ab is None:
+ return True
+ tm = Transmitter()
+ tm.remove_user(ab)
+ except Abon.DoesNotExist:
+ print('ERROR: Abon.DoesNotExist')
+ except (NasFailedResult, NasNetworkError, ConnectionResetError) as e:
+ print('NetErr:', e)
+ return True
diff --git a/abonapp/pay_systems.py b/abonapp/pay_systems.py
index c159507..cd7bccb 100644
--- a/abonapp/pay_systems.py
+++ b/abonapp/pay_systems.py
@@ -6,8 +6,8 @@ from django.db import DatabaseError
from django.conf import settings
-SECRET = getattr(settings, 'pay_SECRET')
-SERV_ID = getattr(settings, 'pay_SERV_ID')
+SECRET = getattr(settings, 'PAY_SECRET')
+SERV_ID = getattr(settings, 'PAY_SERV_ID')
#?ACT=1&PAY_ACCOUNT=960849&SERVICE_ID=y832r92y8f9e&PAY_ID=3561234&TRADE_POINT=377&SIGN=32e533a72389fe4e93746509f9d672f8
diff --git a/abonapp/templates/abonapp/complete_service.html b/abonapp/templates/abonapp/complete_service.html
deleted file mode 100644
index d0939a2..0000000
--- a/abonapp/templates/abonapp/complete_service.html
+++ /dev/null
@@ -1,58 +0,0 @@
-{% extends request.is_ajax|yesno:'bajax.html,base.html' %}
-{% load i18n %}
-{% block main %}
-
-
-
- - {% trans 'User groups' %}
- - {{ abon_group.title }}
- - {{ abon.fio }}
- - {% trans 'Finish service' %}
-
-
- {% include 'message_block.html' %}
-
-
-
-
{% trans 'Finish service' %}
-
-
-
-
-{% endblock %}
\ No newline at end of file
diff --git a/abonapp/templates/abonapp/editAbon.html b/abonapp/templates/abonapp/editAbon.html
index e5883ae..5e93ebd 100644
--- a/abonapp/templates/abonapp/editAbon.html
+++ b/abonapp/templates/abonapp/editAbon.html
@@ -1,5 +1,6 @@
{% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %}
{% load i18n %}
+{% load guardian_tags %}
{% block content %}
@@ -102,9 +109,6 @@
-
{% if perms.taskapp.add_task %}
{% trans 'Add new task' %}
@@ -113,7 +117,7 @@
- {% if ip %}
+ {% if ip and perms.abonapp.can_ping %}
+ {% if perms.abonapp.change_abon %}
{% trans 'Select the device' %}
@@ -140,7 +145,7 @@
+ {% endif %}
+ {% if perms.abonapp.add_extrafieldsmodel %}
{% trans 'Extra fields' %}
@@ -236,6 +243,7 @@
+ {% endif %}
diff --git a/abonapp/templates/abonapp/group_list.html b/abonapp/templates/abonapp/group_list.html
index 59fb7ed..00362e7 100644
--- a/abonapp/templates/abonapp/group_list.html
+++ b/abonapp/templates/abonapp/group_list.html
@@ -38,7 +38,7 @@
{% if perms.abonapp.delete_abongroup %}
{% if gr.usercount == 0 %}
-
+
{% endif %}
@@ -63,12 +63,16 @@
{% trans 'Add group' %}
{% endif %}
+ {% if perms.abonapp.can_view_abonlog %}
{% trans 'Subscribers actions' %}
+ {% endif %}
+ {% if perms.abonapp.can_view_invoiceforpayment %}
{% trans 'List of debtors' %}
+ {% endif %}
|
@@ -77,4 +81,4 @@
{% include 'toolbar_page.html' with pag=groups %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/abonapp/templates/abonapp/modal_add_phone.html b/abonapp/templates/abonapp/modal_add_phone.html
new file mode 100644
index 0000000..1ca2916
--- /dev/null
+++ b/abonapp/templates/abonapp/modal_add_phone.html
@@ -0,0 +1,35 @@
+{% load i18n %}
+
diff --git a/abonapp/templates/abonapp/modal_additional_telephones.html b/abonapp/templates/abonapp/modal_additional_telephones.html
new file mode 100644
index 0000000..5782e6b
--- /dev/null
+++ b/abonapp/templates/abonapp/modal_additional_telephones.html
@@ -0,0 +1,37 @@
+{% load i18n %}
+
+
+
+
+
+
+
+
+ | {% trans 'Telephone owner' %} |
+ {% trans 'Telephone' %} |
+ |
+
+
+
+ {% for t in telephones %}
+
+ | {{ t.owner_name }} |
+ {{ t.telephone }} |
+
+
+
+
+ |
+
+ {% empty %}
+
+ | {% trans 'Additional telephones not found' %} |
+
+ {% endfor %}
+
+
+
+
diff --git a/abonapp/templates/abonapp/payHistory.html b/abonapp/templates/abonapp/payHistory.html
index f81a128..fc55b95 100644
--- a/abonapp/templates/abonapp/payHistory.html
+++ b/abonapp/templates/abonapp/payHistory.html
@@ -1,5 +1,6 @@
{% extends request.is_ajax|yesno:'nullcont.htm,abonapp/ext.htm' %}
{% load i18n %}
+{% load guardian_tags %}
{% block content %}
{% include 'toolbar_page.html' with pag=pay_history %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/abonapp/templates/abonapp/peoples.html b/abonapp/templates/abonapp/peoples.html
index 905ea2e..eeadaae 100644
--- a/abonapp/templates/abonapp/peoples.html
+++ b/abonapp/templates/abonapp/peoples.html
@@ -1,5 +1,6 @@
{% extends 'base.html' %}
{% load i18n %}
+{% load dpagination %}
{% block main %}
@@ -20,32 +21,32 @@
| # |
-
+
{% trans 'Sub' %}
{% if order_by == 'username' %}{% endif %}
|
{% trans 'Last traffic' %} |
-
+
{% trans 'Ip address' %}
{% if order_by == 'ip_address' %}{% endif %}
|
-
+
{% trans 'fio' %}
{% if order_by == 'fio' %}{% endif %}
|
-
+
{% trans 'Street' %}
{% if order_by == 'street' %}{% endif %}
|
-
+
{% trans 'Apartment' %}
{% if order_by == 'house' %}{% endif %}
@@ -53,7 +54,7 @@
| {% trans 'Telephone' %} |
{% trans 'Service' %} |
-
+
{% trans 'Ballance' %}
{% if order_by == 'ballance' %}{% endif %}
@@ -104,7 +105,7 @@
| {{ human.ballance }} |
{% if can_del_trf %}
-
+
{% endif %}
@@ -126,14 +127,11 @@
|
|
{% if perms.abonapp.add_abon %}
-
+
{% trans 'Add abon' %}
{% endif %}
-
- {% trans 'Refresh subscribers on NAS' %}
-
-
+
{% trans 'Tariffs in groups' %}
|
@@ -147,7 +145,7 @@
{% trans 'Streets' %}
+ {% if perms.abonapp.can_view_passport %}
+ {% endif %}
{% endblock %}
\ No newline at end of file
diff --git a/abonapp/templatetags/dpagination.py b/abonapp/templatetags/dpagination.py
index 582009b..e8232c7 100644
--- a/abonapp/templatetags/dpagination.py
+++ b/abonapp/templatetags/dpagination.py
@@ -8,3 +8,11 @@ def url_page_replace(request, field, value):
dict_ = request.GET.copy()
dict_[field] = value
return dict_.urlencode()
+
+
+@register.simple_tag
+def url_replace(request, *args, **kwargs):
+ dict_ = request.GET.copy()
+ for k, v in kwargs.items():
+ dict_[k] = v
+ return dict_.urlencode()
diff --git a/abonapp/urls.py b/abonapp/urls.py
index 3aa6686..048f525 100644
--- a/abonapp/urls.py
+++ b/abonapp/urls.py
@@ -13,7 +13,7 @@ urlpatterns = [
url(r'^log$', views.log_page, name='log'),
- url(r'^del$', views.delentity, name='del_abon'),
+ url(r'^del$', views.del_abon, name='del_abon'),
url(r'^pay$', views.terminal_pay, name='terminal_pay'),
@@ -21,8 +21,6 @@ urlpatterns = [
url(r'^ping$', views.abon_ping, name='ping'),
- url(r'^refresh_group_nas(?P\d+)$', views.update_nas, name='update_nas'),
-
# Api's
url(r'^api/abons$', views.abons),
url(r'^api/abon_filter$', views.search_abon)
diff --git a/abonapp/urls_abon.py b/abonapp/urls_abon.py
index 2922a6b..d37a86c 100644
--- a/abonapp/urls_abon.py
+++ b/abonapp/urls_abon.py
@@ -19,7 +19,6 @@ urlpatterns = [
url(r'^(?P\d+)/addinvoice$', views.add_invoice, name='add_invoice'),
url(r'^(?P\d+)/pick$', views.pick_tariff, name='pick_tariff'),
url(r'^(?P\d+)/passport_view$', views.passport_view, name='passport_view'),
- url(r'^(?P\d+)/complete_service(?P\d+)$', views.complete_service, name='compl_srv'),
url(r'^(?P\d+)/chart$', views.charts, name='charts'),
url(r'^(?P\d+)/dials$', views.dials, name='dials'),
url(r'^(?P\d+)/extra_field$', views.make_extra_field, name='extra_field'),
@@ -33,5 +32,9 @@ urlpatterns = [
url(r'^(?P\d+)/clear_dev/$', views.clear_dev, name='clear_dev'),
url(r'^(?P\d+)/task_log$', views.task_log, name='task_log'),
- url(r'^(?P\d+)/user_dev$', views.save_user_dev_port, name='save_user_dev_port')
+ url(r'^(?P\d+)/user_dev$', views.save_user_dev_port, name='save_user_dev_port'),
+
+ url(r'^(?P\d+)/tel$', views.tels, name='telephones'),
+ url(r'^(?P\d+)/tel/add$', views.tel_add, name='telephone_new'),
+ url(r'^(?P\d+)/tel/del$', views.tel_del, name='telephone_del')
]
diff --git a/abonapp/views.py b/abonapp/views.py
index b47f23d..e8846ac 100644
--- a/abonapp/views.py
+++ b/abonapp/views.py
@@ -6,8 +6,7 @@ from django.db import IntegrityError, ProgrammingError
from django.db.models import Count, Q
from django.db.transaction import atomic
from django.shortcuts import render, redirect, get_object_or_404, resolve_url
-from django.contrib.auth.decorators import login_required, permission_required
-from django.utils import timezone
+from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
@@ -23,17 +22,22 @@ from datetime import datetime, date
from taskapp.models import Task
from dialing_app.models import AsteriskCDR
from statistics.models import getModel, get_dates
+from guardian.shortcuts import get_objects_for_user, assign_perm
+from guardian.decorators import permission_required_or_403 as permission_required
@login_required
@mydefs.only_admins
def peoples(request, gid):
+ abon_group = get_object_or_404(models.AbonGroup, pk=gid)
+ if not request.user.has_perm('abonapp.can_view_abongroup', abon_group):
+ raise PermissionDenied
street_id = mydefs.safe_int(request.GET.get('street'))
peoples_list = models.Abon.objects.select_related('group', 'street')
if street_id > 0:
- peoples_list = peoples_list.filter(group=gid, street=street_id)
+ peoples_list = peoples_list.filter(group=abon_group, street=street_id)
else:
- peoples_list = peoples_list.filter(group=gid)
+ peoples_list = peoples_list.filter(group=abon_group)
# фильтр
dr, field = mydefs.order_helper(request)
@@ -72,7 +76,10 @@ def addgroup(request):
if request.method == 'POST':
frm = forms.AbonGroupForm(request.POST)
if frm.is_valid():
- frm.save()
+ grp = frm.save()
+ assign_perm('abonapp.can_view_abongroup', request.user, grp)
+ assign_perm('abonapp.delete_abongroup', request.user, grp)
+ assign_perm('abonapp.change_abongroup', request.user, grp)
messages.success(request, _('create group success msg'))
return redirect('abonapp:group_list')
else:
@@ -91,6 +98,7 @@ def addgroup(request):
@mydefs.only_admins
def grouplist(request):
groups = models.AbonGroup.objects.annotate(usercount=Count('abon')).order_by('title')
+ groups = get_objects_for_user(request.user, 'abonapp.can_view_abongroup', klass=groups, accept_global_perms=False)
# фильтр
directory, field = mydefs.order_helper(request)
@@ -107,11 +115,13 @@ def grouplist(request):
@login_required
-@permission_required('abonapp.delete_abongroup')
def delgroup(request):
try:
agd = mydefs.safe_int(request.GET.get('id'))
- get_object_or_404(models.AbonGroup, pk=agd).delete()
+ abon_group = models.AbonGroup.objects.get(pk=agd)
+ if not request.user.has_perm('abonapp.delete_abongroup', abon_group):
+ raise PermissionDenied
+ abon_group.delete()
messages.success(request, _('delete group success msg'))
return mydefs.res_success(request, 'abonapp:group_list')
except (NasFailedResult, NasNetworkError) as e:
@@ -119,6 +129,8 @@ def delgroup(request):
except mydefs.MultipleException as errs:
for err in errs.err_list:
messages.add_message(request, messages.constants.ERROR, err)
+ except models.AbonGroup.DoesNotExist:
+ return mydefs.res_error(request, 'Group with id=%d does not exist' % agd)
return mydefs.res_error(request, 'abonapp:group_list')
@@ -129,10 +141,17 @@ def addabon(request, gid):
group = None
try:
group = get_object_or_404(models.AbonGroup, pk=gid)
+ if not request.user.has_perm('abonapp.can_view_abongroup', group):
+ raise PermissionDenied
if request.method == 'POST':
frm = forms.AbonForm(request.POST, initial={'group': group})
if frm.is_valid():
abon = frm.save()
+ assign_perm("abonapp.change_abon", request.user, abon)
+ assign_perm("abonapp.delete_abon", request.user, abon)
+ assign_perm("abonapp.can_buy_tariff", request.user, abon)
+ assign_perm("abonapp.can_view_passport", request.user, abon)
+ assign_perm('abonapp.can_add_ballance', request.user, abon)
messages.success(request, _('create abon success msg'))
return redirect('abonapp:abon_home', group.id, abon.pk)
else:
@@ -159,26 +178,18 @@ def addabon(request, gid):
@login_required
@mydefs.only_admins
-def delentity(request):
- typ = request.GET.get('t')
+def del_abon(request):
uid = request.GET.get('id')
try:
- if typ == 'a':
- if not request.user.has_perm('abonapp.delete_abon'):
- raise PermissionDenied
- abon = get_object_or_404(models.Abon, pk=uid)
- gid = abon.group.id
- abon.delete()
- messages.success(request, _('delete abon success msg'))
- return mydefs.res_success(request, resolve_url('abonapp:people_list', gid=gid))
- elif typ == 'g':
- if not request.user.has_perm('abonapp.delete_abongroup'):
- raise PermissionDenied
- get_object_or_404(models.AbonGroup, pk=uid).delete()
- messages.success(request, _('delete group success msg'))
- return mydefs.res_success(request, 'abonapp:group_list')
- else:
- messages.warning(request, _('I not know what to delete'))
+ abon = get_object_or_404(models.Abon, pk=uid)
+ if not request.user.has_perm('abonapp.delete_abon') or not request.user.has_perm(
+ 'abonapp.can_view_abongroup', abon.group):
+ raise PermissionDenied
+ gid = abon.group.id
+ abon.delete()
+ messages.success(request, _('delete abon success msg'))
+ return mydefs.res_success(request, resolve_url('abonapp:people_list', gid=gid))
+
except NasNetworkError as e:
messages.error(request, e)
except NasFailedResult as e:
@@ -218,6 +229,7 @@ def abonamount(request, gid, uid):
@login_required
@mydefs.only_admins
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
def invoice_for_payment(request, gid, uid):
abon = get_object_or_404(models.Abon, pk=uid)
invoices = models.InvoiceForPayment.objects.filter(abon=abon)
@@ -231,6 +243,7 @@ def invoice_for_payment(request, gid, uid):
@login_required
@mydefs.only_admins
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
def pay_history(request, gid, uid):
abon = get_object_or_404(models.Abon, pk=uid)
pay_history = models.AbonLog.objects.filter(abon=abon).order_by('-id')
@@ -246,6 +259,8 @@ def pay_history(request, gid, uid):
@mydefs.only_admins
def abon_services(request, gid, uid):
grp = get_object_or_404(models.AbonGroup, pk=gid)
+ if not request.user.has_perm('abonapp.can_view_abongroup', grp):
+ raise PermissionDenied
abon = get_object_or_404(models.Abon, pk=uid)
return render(request, 'abonapp/service.html', {
@@ -261,6 +276,8 @@ def abon_services(request, gid, uid):
def abonhome(request, gid, uid):
abon = get_object_or_404(models.Abon, pk=uid)
abon_group = get_object_or_404(models.AbonGroup, pk=gid)
+ if not request.user.has_perm('abonapp.can_view_abongroup', abon_group):
+ raise PermissionDenied
frm = None
passw = None
try:
@@ -394,71 +411,13 @@ def pick_tariff(request, gid, uid):
})
-@login_required
-@permission_required('abonapp.can_complete_service')
-@atomic
-def complete_service(request, gid, uid, srvid):
- abtar = get_object_or_404(models.AbonTariff, pk=srvid)
- abon = abtar.abon
- # считаем не использованные ресурсы
- calc_obj = abtar.tariff.get_calc_type()(abtar)
- # получаем сколько использовано
- res_amount = calc_obj.calc_amount()
- cashback = abtar.tariff.amount - res_amount
-
- if abtar.abon.group is None:
- abon.group = get_object_or_404(models.AbonGroup, pk=gid)
- abon.save(update_fields=['group'])
- if int(abtar.abon.pk) != int(uid) or int(abtar.abon.group.pk) != int(gid):
- # если что-то написали в урле вручную, то вернём на путь истинный
- return redirect('abonapp:compl_srv', gid=abtar.abon.group.pk, uid=abtar.abon.pk, srvid=srvid)
- time_use = None
- try:
- if request.method == 'POST':
- # досрочно завершаем услугу
- if request.POST.get('finish_confirm') == 'yes':
- if cashback > 0.5:
- # возвращаем деньги, которые абонент не использовал
- abon.add_ballance(
- request.user,
- cashback,
- _('Refunds for unused resources')
- )
- abon.save(update_fields=['ballance'])
-
- # удаляем запись о текущей услуге.
- abtar.delete()
- messages.success(request, _('Service has been finished successfully'))
- return redirect('abonapp:abon_services', gid, uid)
- else:
- raise mydefs.LogicError(_('Not confirmed'))
-
- time_use = mydefs.RuTimedelta(timezone.now() - abtar.time_start)
-
- except (mydefs.LogicError, NasFailedResult) as e:
- messages.error(request, e)
- except NasNetworkError as e:
- messages.warning(request, e)
- return redirect('abonapp:abon_home', gid, uid)
- except mydefs.MultipleException as errs:
- for err in errs.err_list:
- messages.add_message(request, messages.constants.ERROR, err)
-
- return render(request, 'abonapp/complete_service.html', {
- 'abtar': abtar,
- 'abon': abon,
- 'time_use': time_use,
- 'abon_group': get_object_or_404(models.AbonGroup, pk=gid),
- 'tcost': round(res_amount, 4),
- 'cashback': round(cashback, 4)
- })
-
-
@login_required
@permission_required('abonapp.delete_abontariff')
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
def unsubscribe_service(request, gid, uid, abon_tariff_id):
try:
- get_object_or_404(models.AbonTariff, pk=int(abon_tariff_id)).delete()
+ abon_tariff = get_object_or_404(models.AbonTariff, pk=int(abon_tariff_id))
+ abon_tariff.delete()
messages.success(request, _('User has been detached from service'))
except NasFailedResult as e:
messages.error(request, e)
@@ -471,7 +430,7 @@ def unsubscribe_service(request, gid, uid, abon_tariff_id):
@login_required
-@mydefs.only_admins
+@permission_required('abonapp.can_view_abonlog')
def log_page(request):
logs = models.AbonLog.objects.all()
logs = mydefs.pag_mn(request, logs)
@@ -481,42 +440,17 @@ def log_page(request):
@login_required
-@mydefs.only_admins
+@permission_required('abonapp.can_view_invoiceforpayment')
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
})
@login_required
-@mydefs.only_admins
-def update_nas(request, group_id):
- users = models.Abon.objects.filter(group=group_id)
- try:
- tm = Transmitter()
- for usr in users:
- if not usr.ip_address:
- continue
- agent_abon = usr.build_agent_struct()
- if agent_abon is not None:
- tm.update_user(agent_abon)
- except NasFailedResult as e:
- messages.error(request, e)
- except NasNetworkError as e:
- messages.warning(request, e)
- except mydefs.MultipleException as errs:
- for err in errs.err_list:
- messages.add_message(request, messages.constants.ERROR, err)
- return redirect('abonapp:people_list', gid=group_id)
-
-
-@login_required
-@mydefs.only_admins
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
def task_log(request, gid, uid):
abon = get_object_or_404(models.Abon, pk=uid)
tasks = Task.objects.filter(abon=abon)
@@ -528,7 +462,7 @@ def task_log(request, gid, uid):
@login_required
-@mydefs.only_admins
+@permission_required('abonapp.can_view_passport')
def passport_view(request, gid, uid):
try:
abon = models.Abon.objects.get(pk=uid)
@@ -566,6 +500,8 @@ def passport_view(request, gid, uid):
@mydefs.only_admins
def chgroup_tariff(request, gid):
grp = get_object_or_404(models.AbonGroup, pk=gid)
+ if not request.user.has_perm('abonapp.change_abongroup', grp):
+ raise PermissionDenied
if request.method == 'POST':
tr = request.POST.getlist('tr')
grp.tariffs.clear()
@@ -579,7 +515,7 @@ def chgroup_tariff(request, gid):
@login_required
-@mydefs.only_admins
+@permission_required('abonapp.change_abon')
def dev(request, gid, uid):
abon_dev = None
try:
@@ -605,7 +541,8 @@ def dev(request, gid, uid):
@login_required
-@mydefs.only_admins
+@permission_required('abonapp.change_abon')
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
def clear_dev(request, gid, uid):
try:
abon = models.Abon.objects.get(pk=uid)
@@ -619,7 +556,7 @@ def clear_dev(request, gid, uid):
@login_required
-@mydefs.only_admins
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
def charts(request, gid, uid):
high = 100
@@ -673,7 +610,7 @@ def charts(request, gid, uid):
@login_required
-@permission_required('abonapp.add_extra_fields_model')
+@permission_required('abonapp.add_extrafieldsmodel')
def make_extra_field(request, gid, uid):
abon = get_object_or_404(models.Abon, pk=uid)
try:
@@ -733,6 +670,7 @@ def extra_field_delete(request, gid, uid, fid):
@login_required
+@permission_required('abonapp.can_ping')
def abon_ping(request):
ip = request.GET.get('cmd_param')
status = False
@@ -753,7 +691,8 @@ def abon_ping(request):
text = ' %s' % _('ok ping, %d/%d loses') % ping_result
status = True
else:
- text = ' %s' % _('no ping, %d/%d loses') % ping_result
+ text = ' %s' % _(
+ 'no ping, %d/%d loses') % ping_result
else:
text = ' %s' % _('ping ok') + ' ' + str(ping_result)
status = True
@@ -773,6 +712,8 @@ def abon_ping(request):
@mydefs.only_admins
def dials(request, gid, uid):
abon = get_object_or_404(models.Abon, pk=uid)
+ if not request.user.has_perm('abonapp.can_view_abongroup', abon.group):
+ raise PermissionDenied
if hasattr(abon.group, 'pk') and abon.group.pk != int(gid):
return redirect('abonapp:dials', abon.group.pk, abon.pk)
if abon.telephone is not None and abon.telephone != '':
@@ -791,7 +732,7 @@ def dials(request, gid, uid):
@login_required
-@mydefs.only_admins
+@permission_required('abonapp.change_abon')
def save_user_dev_port(request, gid, uid):
if request.method != 'POST':
messages.error(request, _('Method is not POST'))
@@ -820,6 +761,7 @@ def save_user_dev_port(request, gid, uid):
@login_required
@permission_required('abonapp.add_abonstreet')
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
def street_add(request, gid):
if request.method == 'POST':
frm = forms.AbonStreetForm(request.POST)
@@ -839,10 +781,12 @@ def street_add(request, gid):
@login_required
@permission_required('abonapp.change_abonstreet')
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
def street_edit(request, gid):
try:
if request.method == 'POST':
- streets_pairs = [(int(sid), sname) for sid, sname in zip(request.POST.getlist('sid'), request.POST.getlist('sname'))]
+ streets_pairs = [(int(sid), sname) for sid, sname in
+ zip(request.POST.getlist('sid'), request.POST.getlist('sname'))]
for sid, sname in streets_pairs:
street = models.AbonStreet.objects.get(pk=sid)
street.name = sname
@@ -862,6 +806,7 @@ def street_edit(request, gid):
@login_required
@permission_required('abonapp.delete_abonstreet')
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
def street_del(request, gid, sid):
try:
models.AbonStreet.objects.get(pk=sid, group=gid).delete()
@@ -871,22 +816,70 @@ def street_del(request, gid, sid):
return redirect('abonapp:people_list', gid)
+@login_required
+@permission_required('abonapp.can_view_additionaltelephones')
+@permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid'))
+def tels(request, gid, uid):
+ abon = get_object_or_404(models.Abon, pk=uid)
+ telephones = abon.additional_telephones.all()
+ return render_to_text('abonapp/modal_additional_telephones.html', {
+ 'telephones': telephones,
+ 'gid': gid,
+ 'uid': uid
+ }, request=request)
+
+
+@login_required
+@permission_required('abnapp.add_additionaltelephone')
+def tel_add(request, gid, uid):
+ if request.method == 'POST':
+ frm = forms.AdditionalTelephoneForm(request.POST)
+ if frm.is_valid():
+ new_tel = frm.save(commit=False)
+ abon = get_object_or_404(models.Abon, pk=uid)
+ new_tel.abon = abon
+ new_tel.save()
+ messages.success(request, _('New telephone has been saved'))
+ return redirect('abonapp:abon_home', gid, uid)
+ else:
+ messages.error(request, _('fix form errors'))
+ else:
+ frm = forms.AdditionalTelephoneForm()
+ return render_to_text('abonapp/modal_add_phone.html', {
+ 'form': frm,
+ 'gid': gid,
+ 'uid': uid
+ }, request=request)
+
+
+@login_required
+@permission_required('abnapp.delete_additionaltelephone')
+def tel_del(request, gid, uid):
+ try:
+ tid = mydefs.safe_int(request.GET.get('tid'))
+ tel = models.AdditionalTelephone.objects.get(pk=tid)
+ tel.delete()
+ messages.success(request, _('Additional telephone successfully deleted'))
+ except models.AdditionalTelephone.DoesNotExist:
+ messages.error(request, _('Telephone not found'))
+ return redirect('abonapp:abon_home', gid, uid)
+
# API's
def abons(request):
ablist = [{
- 'id': abn.pk,
- 'tarif_id': abn.active_tariff().tariff.pk if abn.active_tariff() is not None else 0,
- 'ip': abn.ip_address.int_ip(),
- 'is_active': abn.is_active
- } for abn in models.Abon.objects.all()]
+ 'id': abn.pk,
+ 'tarif_id': abn.active_tariff().tariff.pk if abn.active_tariff() is not None else 0,
+ 'ip': abn.ip_address.int_ip(),
+ 'is_active': abn.is_active
+ } for abn in models.Abon.objects.all()]
tarlist = [{
- 'id': trf.pk,
- 'speedIn': trf.speedIn,
- 'speedOut': trf.speedOut
- } for trf in Tariff.objects.all()]
+ 'id': trf.pk,
+ 'speedIn': trf.speedIn,
+ 'speedOut': trf.speedOut
+ } for trf in Tariff.objects.all()]
data = {
'subscribers': ablist,
diff --git a/accounts_app/forms.py b/accounts_app/forms.py
index fbedf6f..4288081 100644
--- a/accounts_app/forms.py
+++ b/accounts_app/forms.py
@@ -1,12 +1,24 @@
# -*- coding: utf-8 -*-
-from django import forms
-from .models import UserProfile
+from guardian.forms import UserObjectPermissionsForm
+from guardian.shortcuts import assign_perm, remove_perm
-class SetupPerms(forms.ModelForm):
- class Meta:
- model = UserProfile
- fields = ['user_permissions']
- widgets = {
- 'user_permissions': forms.CheckboxSelectMultiple()
- }
+class MyUserObjectPermissionsForm(UserObjectPermissionsForm):
+
+ def save_obj_perms(self):
+ """
+ Saves selected object permissions by creating new ones and removing
+ those which were not selected but already exists.
+
+ Should be called *after* form is validated.
+ """
+ perms = set(self.cleaned_data[self.get_obj_perms_field_name()])
+ model_perms = set([c[0] for c in self.get_obj_perms_field_choices()])
+ init_perms = set(self.get_obj_perms_field_initial())
+
+ to_remove = (model_perms - perms) & init_perms
+ for perm in to_remove:
+ remove_perm(perm, self.user, self.obj)
+
+ for perm in perms - init_perms:
+ assign_perm(perm, self.user, self.obj)
diff --git a/accounts_app/locale/ru/LC_MESSAGES/django.po b/accounts_app/locale/ru/LC_MESSAGES/django.po
index d3c7a5c..1de16c6 100644
--- a/accounts_app/locale/ru/LC_MESSAGES/django.po
+++ b/accounts_app/locale/ru/LC_MESSAGES/django.po
@@ -33,18 +33,6 @@ msgstr "Администраторы"
msgid "Groups"
msgstr "Группы"
-#: accounts_app/templates/accounts/group.html:16
-msgid "The current distribution of rights for groups"
-msgstr "Действующее распределение прав для группы"
-
-#: accounts_app/templates/accounts/group.html:22
-msgid "Available rights"
-msgstr "Доступные права"
-
-#: accounts_app/templates/accounts/group.html:36
-msgid "Rights for the group"
-msgstr "Права группы"
-
#: accounts_app/templates/accounts/group.html:44
#: accounts_app/templates/accounts/profile_chgroup.html:20
#: accounts_app/templates/accounts/settings/ch_info.html:66
@@ -58,22 +46,6 @@ msgstr "Сохранить"
msgid "Reset"
msgstr "Сбросить"
-#: accounts_app/templates/accounts/group_list.html:11
-msgid "Admin groups list"
-msgstr "Список групп администраторов"
-
-#: accounts_app/templates/accounts/group_list.html:20
-msgid "Group"
-msgstr "Группа"
-
-#: accounts_app/templates/accounts/group_list.html:40
-msgid "Groups does not found"
-msgstr "Нет групп"
-
-#: accounts_app/templates/accounts/group_list.html:47
-msgid "Add group"
-msgstr "Добавить группу"
-
#: accounts_app/templates/accounts/index.html:8
#: accounts_app/templates/accounts/settings/ch_info.html:37
msgid "Telephone"
@@ -186,11 +158,47 @@ msgstr "Настройка прав"
msgid "Edit"
msgstr "Редактировать"
-msgid "Set a task"
-msgstr "Дать задачу"
-
msgid "Please select an image"
msgstr "Пожалуйста выберите изображение"
msgid "Avatar successfully changed"
msgstr "Аватар успешно изменён"
+
+msgid "Access to groups"
+msgstr "Доступ к группам"
+
+msgid "The list of user groups to which the account has access"
+msgstr "Список групп абонентов, к которым учётка имеет доступ"
+
+msgid "The responsibility of the staff of the group of subscribers"
+msgstr "Ответственность работника за группы абонентов"
+
+msgid "Not set"
+msgstr "Не найдено"
+
+msgid "Change permission for that object"
+msgstr "Изменение прав доступа для выбранного объекта"
+
+msgid "Permissions has successfully updated"
+msgstr "Права успешно обновлены"
+
+msgid "Profile is superuser, permissions to change it makes no sense"
+msgstr "Учётная запись является суперпользователем, разрешения менять нет смысла"
+
+msgid "Staff account profile"
+msgstr "Учётная запись работника"
+
+msgid "Staff account profiles"
+msgstr "Учётные записи работников"
+
+msgid "Can view staff profile"
+msgstr "Может просматривать учётку сотрудника"
+
+msgid "Pick object for edit permissions"
+msgstr "Выберите объект для редактирования прав доступа"
+
+msgid "Pick the type of object"
+msgstr "Выберите тип объекта"
+
+msgid "Profile has been deleted"
+msgstr "Учётная запись удалена"
diff --git a/accounts_app/migrations/0008_auto_20170927_1838.py b/accounts_app/migrations/0008_auto_20170927_1838.py
new file mode 100644
index 0000000..fb3c6fe
--- /dev/null
+++ b/accounts_app/migrations/0008_auto_20170927_1838.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2017-09-27 18:38
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('accounts_app', '0007_auto_20170816_1109'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='userprofile',
+ options={'permissions': (('can_view_userprofile', 'Может просматривать учётку сотрудника'),), 'verbose_name': 'Учётная запись работника', 'verbose_name_plural': 'Учётные записи работников'},
+ ),
+ ]
diff --git a/accounts_app/models.py b/accounts_app/models.py
index a5f5238..731b432 100644
--- a/accounts_app/models.py
+++ b/accounts_app/models.py
@@ -1,4 +1,5 @@
# -*- coding:utf-8 -*-
+import os
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin
from django.core.validators import RegexValidator
@@ -7,7 +8,7 @@ from django.conf import settings
from photo_app.models import Photo
-DEFAULT_PICTURE = getattr(settings, 'DEFAULT_PICTURE', '/static/images/default-avatar.png')
+DEFAULT_PICTURE = getattr(settings, 'DEFAULT_PICTURE', '/static/img/user_ava.gif')
TELEPHONE_REGEXP = getattr(settings, 'TELEPHONE_REGEXP', r'^\+[7,8,9,3]\d{10,11}$')
@@ -79,15 +80,31 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
def get_big_ava(self):
if self.avatar:
- return self.avatar.big()
+ path = self.avatar.big()
+ if os.path.exists(path):
+ return path
+ else:
+ return DEFAULT_PICTURE
else:
return DEFAULT_PICTURE
def get_min_ava(self):
if self.avatar:
- return self.avatar.min()
+ url_path = self.avatar.min()
+ real_path = url_path[1:]
+ if os.path.exists(real_path):
+ return url_path
+ else:
+ return DEFAULT_PICTURE
else:
return DEFAULT_PICTURE
def __str__(self):
return self.get_full_name()
+
+ class Meta:
+ permissions = (
+ ('can_view_userprofile', _('Can view staff profile')),
+ )
+ verbose_name = _('Staff account profile')
+ verbose_name_plural = _('Staff account profiles')
diff --git a/accounts_app/templates/accounts/acc_list.html b/accounts_app/templates/accounts/acc_list.html
index 09e2880..ed5e52e 100644
--- a/accounts_app/templates/accounts/acc_list.html
+++ b/accounts_app/templates/accounts/acc_list.html
@@ -25,7 +25,7 @@
{% for usr in users %}
-
|
{{ usr.username }} |
@@ -39,7 +39,7 @@
title="Дать задание">
-
diff --git a/accounts_app/templates/accounts/ext.htm b/accounts_app/templates/accounts/ext.htm
index cc08e5c..19cf4e1 100644
--- a/accounts_app/templates/accounts/ext.htm
+++ b/accounts_app/templates/accounts/ext.htm
@@ -14,19 +14,32 @@
{% if userprofile.avatar %}
-
-
+
+
{% else %}

{% endif %}
@@ -46,6 +59,15 @@
{% trans 'Groups' %}
+ {% if request.user.is_superuser %}
+ {% url 'acc_app:set_abon_groups_permission' uid as set_ag_perm %}
+
+
+
+ {% trans 'Access to groups' %}
+
+
+ {% endif %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/accounts_app/templates/accounts/group.html b/accounts_app/templates/accounts/group.html
deleted file mode 100644
index 96e0120..0000000
--- a/accounts_app/templates/accounts/group.html
+++ /dev/null
@@ -1,50 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block main %}
-
-
-
- - {% trans 'Administrators' %}
- - {% trans 'Groups' %}
- - {{ group.name }}
-
-
- {% include 'message_block.html' %}
-
-
-
-
{% trans 'The current distribution of rights for groups' %} {{ group.name }}
-
-
-
-
-{% endblock %}
\ No newline at end of file
diff --git a/accounts_app/templates/accounts/group_list.html b/accounts_app/templates/accounts/group_list.html
deleted file mode 100644
index fd90afd..0000000
--- a/accounts_app/templates/accounts/group_list.html
+++ /dev/null
@@ -1,58 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block main %}
-
-
-
- - {% trans 'Administrators' %}
- - {% trans 'Groups' %}
-
-
- {% trans 'Admin groups list' %}
-
- {% include 'message_block.html' %}
-
-
-
- {% include 'toolbar_page.html' with pag=groups %}
-
-{% endblock %}
\ No newline at end of file
diff --git a/accounts_app/templates/accounts/perms/objects_of_type.html b/accounts_app/templates/accounts/perms/objects_of_type.html
new file mode 100644
index 0000000..e5adbcf
--- /dev/null
+++ b/accounts_app/templates/accounts/perms/objects_of_type.html
@@ -0,0 +1,34 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block main %}
+
+
+
+ - {% trans 'Administrators' %}
+ - {{ userprofile.username }}
+ - {% trans 'Permission options' %}
+ - <{{ klass }}> {{ klass_name }}
+
+
+ {% trans 'Pick object for edit permissions' %}
+
+ {% include 'message_block.html' %}
+
+
+
+
+
+ | obj |
+
+
+
+ {% for obj in objects %}|
+ {{ obj }}
+ |
{% endfor %}
+
+
+
+
+ {% include 'toolbar_page.html' with pag=objects %}
+
+{% endblock %}
diff --git a/accounts_app/templates/accounts/perms/objects_types.html b/accounts_app/templates/accounts/perms/objects_types.html
new file mode 100644
index 0000000..a831c76
--- /dev/null
+++ b/accounts_app/templates/accounts/perms/objects_types.html
@@ -0,0 +1,36 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% load acc_tags %}
+{% block main %}
+
+
+
+ - {% trans 'Administrators' %}
+ - {{ userprofile.username }}
+ - {% trans 'Permission options' %}
+
+
+ {% trans 'Pick the type of object' %}
+
+ {% include 'message_block.html' %}
+
+
+
+{% endblock %}
diff --git a/accounts_app/templates/accounts/perms/perms_edit.html b/accounts_app/templates/accounts/perms/perms_edit.html
new file mode 100644
index 0000000..1e0cf96
--- /dev/null
+++ b/accounts_app/templates/accounts/perms/perms_edit.html
@@ -0,0 +1,71 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% load guardian_tags %}
+{% block main %}
+
+
+
+ - {% trans 'Administrators' %}
+ - {{ userprofile.username }}
+ - {% trans 'Permission options' %}
+ - <{{ klass }}> {{ klass_name }}
+
+ - {{ obj }}
+
+
+ {% trans 'Pick object for edit permissions' %}
+
+ {% include 'message_block.html' %}
+
+ {% if userprofile.is_superuser %}
+
+
+
+ {% trans 'Profile is superuser, permissions to change it makes no sense' %}
+
+ {% endif %}
+
+
+
+
{% trans 'Change permission for that object' %}
+
+
+
+
+{% endblock %}
diff --git a/accounts_app/templates/accounts/profile_chgroup.html b/accounts_app/templates/accounts/profile_chgroup.html
index 22156fa..c5ac443 100644
--- a/accounts_app/templates/accounts/profile_chgroup.html
+++ b/accounts_app/templates/accounts/profile_chgroup.html
@@ -2,15 +2,15 @@
{% load i18n %}
{% block content %}
-
+
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/accounts_app/templates/accounts/set_abon_groups_permission.html b/accounts_app/templates/accounts/set_abon_groups_permission.html
new file mode 100644
index 0000000..b431f98
--- /dev/null
+++ b/accounts_app/templates/accounts/set_abon_groups_permission.html
@@ -0,0 +1,25 @@
+{% extends request.is_ajax|yesno:'nullcont.htm,accounts/ext.htm' %}
+{% load i18n %}
+{% block content %}
+
+
+
+
+{% endblock %}
diff --git a/accounts_app/templates/accounts/settings/ext.htm b/accounts_app/templates/accounts/settings/ext.htm
index 92c5b3c..572c19d 100644
--- a/accounts_app/templates/accounts/settings/ext.htm
+++ b/accounts_app/templates/accounts/settings/ext.htm
@@ -16,9 +16,7 @@