Browse Source

Merge branch 'devel' of https://github.com/nerosketch/djing into devel

devel
Dmitry Novikov 8 years ago
parent
commit
95bcbad04d
  1. 2
      abonapp/templates/abonapp/debtors.html
  2. 2
      abonapp/templates/abonapp/dial_log.html
  3. 2
      abonapp/templates/abonapp/invoiceForPayment.html
  4. 2
      abonapp/templates/abonapp/log.html
  5. 2
      abonapp/templates/abonapp/payHistory.html
  6. 2
      abonapp/templates/abonapp/task_log.html
  7. 4
      abonapp/urls.py
  8. 8
      abonapp/urls_abon.py
  9. 164
      abonapp/views.py
  10. 319
      accounts_app/locale/ru/LC_MESSAGES/django.po
  11. 41
      accounts_app/templates/accounts/acc_list.html
  12. 28
      accounts_app/templates/accounts/create_acc.html
  13. 2
      accounts_app/templates/accounts/login.html
  14. 2
      accounts_app/templates/accounts/perms/objects_of_type.html
  15. 4
      accounts_app/urls.py
  16. 67
      accounts_app/views.py
  17. 3
      clientsideapp/views.py
  18. 8
      devapp/templates/devapp/devices_null_group.html
  19. 2
      devapp/templates/devapp/group_list.html
  20. 4
      devapp/urls.py
  21. 51
      devapp/views.py
  22. 14
      djing/urls.py
  23. 2
      msg_app/templates/msg_app/conversations.html
  24. 2
      msg_app/urls.py
  25. 21
      msg_app/views.py
  26. 56
      mydefs.py
  27. 5
      tariff_app/locale/ru/LC_MESSAGES/django.po
  28. 23
      tariff_app/migrations/0007_auto_20180215_1423.py
  29. 12
      tariff_app/models.py
  30. 2
      tariff_app/templates/tariff_app/periodic_pays/list.html
  31. 12
      tariff_app/templates/tariff_app/tarifs.html
  32. 4
      tariff_app/urls.py
  33. 44
      tariff_app/views.py
  34. 26
      templates/toolbar_page.html

2
abonapp/templates/abonapp/debtors.html

@ -47,6 +47,6 @@
</table>
</div>
{% include 'toolbar_page.html' with pag=peoples %}
{% include 'pagination.html' %}
{% endblock %}

2
abonapp/templates/abonapp/dial_log.html

@ -42,6 +42,6 @@
</table>
{% include 'toolbar_page.html' with pag=logs %}
{% include 'pagination.html' %}
{% endblock %}

2
abonapp/templates/abonapp/invoiceForPayment.html

@ -67,6 +67,6 @@
</table>
</div>
{% include 'toolbar_page.html' with pag=invoices %}
{% include 'pagination.html' %}
{% endblock %}

2
abonapp/templates/abonapp/log.html

@ -51,6 +51,6 @@
</table>
</div>
{% include 'toolbar_page.html' with pag=logs %}
{% include 'pagination.html' %}
{% endblock %}

2
abonapp/templates/abonapp/payHistory.html

@ -53,5 +53,5 @@
</table>
{% include 'toolbar_page.html' with pag=pay_history %}
{% include 'pagination.html' %}
{% endblock %}

2
abonapp/templates/abonapp/task_log.html

@ -44,5 +44,5 @@
</tfoot>
</table>
{% include 'toolbar_page.html' with pag=tasks %}
{% include 'pagination.html' %}
{% endblock %}

4
abonapp/urls.py

@ -15,13 +15,13 @@ urlpatterns = [
url(r'^(?P<gid>\d+)/', include('abonapp.urls_abon')),
url(r'^log$', views.log_page, name='log'),
url(r'^log$', views.LogListView.as_view(), name='log'),
url(r'^del$', views.del_abon, name='del_abon'),
url(r'^pay$', views.terminal_pay, name='terminal_pay'),
url(r'^debtors$', views.debtors, name='debtors'),
url(r'^debtors$', views.DebtorsListView.as_view(), name='debtors'),
url(r'^ping$', views.abon_ping, name='ping'),

8
abonapp/urls_abon.py

@ -15,14 +15,14 @@ urlpatterns = [
url(r'^(?P<uid>\d+)/services$', views.abon_services, name='abon_services'),
url(r'^(?P<uid>\d+)/amount', views.abonamount, name='abon_amount'),
url(r'^(?P<uid>\d+)/debts', views.invoice_for_payment, name='abon_debts'),
url(r'^(?P<uid>\d+)/pay', views.pay_history, name='abon_phistory'),
url(r'^(?P<uid>\d+)/debts', views.DebtsListView.as_view(), name='abon_debts'),
url(r'^(?P<uid>\d+)/pay', views.PayHistoryListView.as_view(), name='abon_phistory'),
url(r'^(?P<uid>\d+)/addinvoice$', views.add_invoice, name='add_invoice'),
url(r'^(?P<uid>\d+)/pick$', views.pick_tariff, name='pick_tariff'),
url(r'^(?P<uid>\d+)/passport_view$', views.passport_view, name='passport_view'),
url(r'^(?P<uid>\d+)/chart$', views.charts, name='charts'),
url(r'^(?P<uid>\d+)/dials$', views.dials, name='dials'),
url(r'^(?P<uid>\d+)/dials$', views.DialsListView.as_view(), name='dials'),
url(r'^(?P<uid>\d+)/reset_ip$', views.reset_ip, name='reset_ip'),
url(r'^(?P<uid>\d+)/extra_field$', views.make_extra_field, name='extra_field'),
url(r'^(?P<uid>\d+)/extra_field/(?P<fid>\d+)/delete$', views.extra_field_delete, name='extra_field_delete'),
@ -34,7 +34,7 @@ urlpatterns = [
url(r'^(?P<uid>\d+)/dev/$', views.dev, name='dev'),
url(r'^(?P<uid>\d+)/clear_dev/$', views.clear_dev, name='clear_dev'),
url(r'^(?P<uid>\d+)/task_log$', views.task_log, name='task_log'),
url(r'^(?P<uid>\d+)/task_log$', views.TaskLogListView.as_view(), name='task_log'),
url(r'^(?P<uid>\d+)/user_dev$', views.save_user_dev_port, name='save_user_dev_port'),
url(r'^(?P<uid>\d+)/tel$', views.tels, name='telephones'),

164
abonapp/views.py

@ -230,32 +230,39 @@ def abonamount(request, gid, uid):
}, request=request)
@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)
invoices = mydefs.pag_mn(request, invoices)
return render(request, 'abonapp/invoiceForPayment.html', {
'invoices': invoices,
'abon_group': abon.group,
'abon': abon
})
@method_decorator(permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')), name='dispatch')
class DebtsListView(BaseAbonListView):
context_object_name = 'invoices'
template_name = 'abonapp/invoiceForPayment.html'
def get_queryset(self):
abon = get_object_or_404(models.Abon, pk=self.kwargs.get('uid'))
self.abon = abon
return models.InvoiceForPayment.objects.filter(abon=abon)
@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')
pay_history = mydefs.pag_mn(request, pay_history)
return render(request, 'abonapp/payHistory.html', {
'pay_history': pay_history,
'abon_group': abon.group,
'abon': abon
})
def get_context_data(self, **kwargs):
context = super(DebtsListView, self).get_context_data(**kwargs)
context['abon_group'] = self.abon.group
context['abon'] = self.abon
return context
@method_decorator(permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')), name='dispatch')
class PayHistoryListView(BaseAbonListView):
context_object_name = 'pay_history'
template_name = 'abonapp/payHistory.html'
def get_queryset(self):
abon = get_object_or_404(models.Abon, pk=self.kwargs.get('uid'))
self.abon = abon
pay_history = models.AbonLog.objects.filter(abon=abon).order_by('-id')
return pay_history
def get_context_data(self, **kwargs):
context = super(PayHistoryListView, self).get_context_data(**kwargs)
context['abon_group'] = self.abon.group
context['abon'] = self.abon
return context
@login_required
@ -447,36 +454,44 @@ def unsubscribe_service(request, gid, uid, abon_tariff_id):
return redirect('abonapp:abon_services', gid=gid, uid=uid)
@login_required
@permission_required('abonapp.can_view_abonlog')
def log_page(request):
logs = models.AbonLog.objects.all()
logs = mydefs.pag_mn(request, logs)
return render(request, 'abonapp/log.html', {
'logs': logs
})
@method_decorator(login_required, name='dispatch')
@method_decorator(permission_required('abonapp.can_view_abonlog'), name='dispatch')
class LogListView(ListView):
paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
context_object_name = 'logs'
template_name = 'abonapp/log.html'
model = models.AbonLog
@login_required
@permission_required('abonapp.can_view_invoiceforpayment')
def debtors(request):
invs = models.InvoiceForPayment.objects.filter(status=True)
invs = mydefs.pag_mn(request, invs)
return render(request, 'abonapp/debtors.html', {
'invoices': invs
})
@method_decorator(login_required, name='dispatch')
@method_decorator(permission_required('abonapp.can_view_invoiceforpayment'), name='dispatch')
class DebtorsListView(ListView):
paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
context_object_name = 'invoices'
template_name = 'abonapp/debtors.html'
queryset = models.InvoiceForPayment.objects.filter(status=True)
@login_required
@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)
return render(request, 'abonapp/task_log.html', {
'tasks': tasks,
'abon_group': get_object_or_404(models.AbonGroup, pk=gid),
'abon': abon
})
@method_decorator(login_required, name='dispatch')
@method_decorator(permission_required('abonapp.can_view_abongroup', (models.AbonGroup, 'pk', 'gid')), name='dispatch')
class TaskLogListView(ListView):
paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
context_object_name = 'tasks'
template_name = 'abonapp/task_log.html'
def get_queryset(self):
abon = get_object_or_404(models.Abon, pk=self.kwargs.get('uid'))
self.abon = abon
return Task.objects.filter(abon=abon)
def get_context_data(self, **kwargs):
context = super(TaskLogListView, self).get_context_data(**kwargs)
context['abon_group'] = self.abon.group
context['abon'] = self.abon
return context
@login_required
@ -728,27 +743,34 @@ def abon_ping(request):
}))
@login_required
@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 != '':
tel = abon.telephone.replace('+', '')
logs = AsteriskCDR.objects.filter(
Q(src__contains=tel) | Q(dst__contains=tel)
)
logs = mydefs.pag_mn(request, logs)
else:
logs = None
return render(request, 'abonapp/dial_log.html', {
'logs': logs,
'abon_group': get_object_or_404(models.AbonGroup, pk=gid),
'abon': abon
})
class DialsListView(BaseAbonListView):
context_object_name = 'logs'
template_name = 'abonapp/dial_log.html'
def get_queryset(self):
abon = get_object_or_404(models.Abon, pk=self.kwargs.get('uid'))
if not self.request.user.has_perm('abonapp.can_view_abongroup', abon.group):
raise PermissionDenied
self.abon = abon
if abon.telephone is not None and abon.telephone != '':
tel = abon.telephone.replace('+', '')
logs = AsteriskCDR.objects.filter(
Q(src__contains=tel) | Q(dst__contains=tel)
)
return logs
else:
return AsteriskCDR.objects.empty()
def get_context_data(self, **kwargs):
context = super(DialsListView, self).get_context_data(**kwargs)
context['abon_group'] = get_object_or_404(models.AbonGroup, pk=self.kwargs.get('gid'))
context['abon'] = self.abon
return context
def render_to_response(self, context, **response_kwargs):
if hasattr(self.abon.group, 'pk') and self.abon.group.pk != int(self.kwargs.get('gid')):
return redirect('abonapp:dials', self.abon.group.pk, self.abon.pk)
return super(DialsListView, self).render_to_response(context, **response_kwargs)
@login_required

319
accounts_app/locale/ru/LC_MESSAGES/django.po

@ -6,9 +6,7 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-27 14:20+0300\n"
"POT-Creation-Date: 2018-02-15 15:15+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n"
"Language: ru\n"
@ -19,198 +17,281 @@ msgstr ""
"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
"%100>=11 && n%100<=14)? 2 : 3);\n"
#: accounts_app/models.py:18
#: models.py:22
msgid "Users must have an telephone number"
msgstr "У пользователей должен быть номер телефона"
#: accounts_app/templates/accounts/group.html:7
#: accounts_app/templates/accounts/group_list.html:7
#: models.py:49 templates/accounts/acc_list.html:18
msgid "profile username"
msgstr "Логин"
#: models.py:50
msgid "fio"
msgstr "ФИО"
#: models.py:51
msgid "birth day"
msgstr "дата рождения"
#: models.py:52
msgid "Is active"
msgstr "Активен"
#: models.py:56 templates/accounts/acc_list.html:20
#: templates/accounts/create_acc.html:60 templates/accounts/index.html:9
#: templates/accounts/settings/ch_info.html:37
msgid "Telephone"
msgstr "Телефон"
#: models.py:107
msgid "Can view staff profile"
msgstr "Может просматривать учётку сотрудника"
#: models.py:109
msgid "Staff account profile"
msgstr "Учётная запись работника"
#: models.py:110
msgid "Staff account profiles"
msgstr "Учётные записи работников"
#: templates/accounts/acc_list.html:7 templates/accounts/create_acc.html:6
#: templates/accounts/perms/objects_of_type.html:7
#: templates/accounts/perms/objects_types.html:8
#: templates/accounts/perms/perms_edit.html:8
msgid "Administrators"
msgstr "Сотрудники"
#: accounts_app/templates/accounts/group.html:8
#: accounts_app/templates/accounts/group_list.html:8
msgid "Groups"
msgstr "Группы"
#: templates/accounts/acc_list.html:12
msgid "Admin accounts list"
msgstr "Список аккаунтов администраторов"
#: templates/accounts/acc_list.html:17
msgid "Photo"
msgstr "Фото"
#: templates/accounts/acc_list.html:19
msgid "Fullname, or login if name is empty"
msgstr "ФИО (или ник если нет)"
#: templates/accounts/acc_list.html:21
#: templates/accounts/settings/ch_info.html:27
msgid "Email"
msgstr "Адрес электронной почты"
#: templates/accounts/acc_list.html:38 templates/accounts/acc_list.html:45
msgid "Not assigned"
msgstr "&lt;Не назначено&gt;"
#: templates/accounts/acc_list.html:56
msgid "You have not permissions to delete"
msgstr "У вас нет прав на удаление"
#: templates/accounts/acc_list.html:65
msgid "Users not found"
msgstr "Пользователи не найдены"
#: templates/accounts/acc_list.html:73
msgid "Add account"
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
#: templates/accounts/create_acc.html:7
msgid "Add"
msgstr "Добавить"
#: templates/accounts/create_acc.html:14
msgid "Create new account"
msgstr "Создать новую учётную запись"
#: templates/accounts/create_acc.html:31 templates/accounts/create_acc.html:35
msgid "Username"
msgstr "Логин"
#: templates/accounts/create_acc.html:40 templates/accounts/create_acc.html:45
msgid "Fullname"
msgstr "Полное имя"
#: templates/accounts/create_acc.html:50
msgid "EMail"
msgstr "Адрес электронной почты"
#: templates/accounts/create_acc.html:65
#: templates/accounts/settings/ch_info.html:42
msgid "+[7,8,9,3] and 10,11 digits"
msgstr "+[7,8,9,3] и 10,11 цифр"
#: templates/accounts/create_acc.html:70
msgid "Type password"
msgstr "Введите пароль"
#: templates/accounts/create_acc.html:78
msgid "Repeat password"
msgstr "Повторите пароль"
#: templates/accounts/create_acc.html:87
#: templates/accounts/perms/perms_edit.html:61
#: templates/accounts/profile_chgroup.html:20
#: templates/accounts/set_abon_groups_permission.html:20
#: templates/accounts/settings/ch_info.html:66
msgid "Save"
msgstr "Сохранить"
#: accounts_app/templates/accounts/group.html:44
#: accounts_app/templates/accounts/login.html:55
#: accounts_app/templates/accounts/profile_chgroup.html:20
#: accounts_app/templates/accounts/settings/ch_info.html:69
#: templates/accounts/create_acc.html:90 templates/accounts/login.html:59
#: templates/accounts/perms/perms_edit.html:64
#: templates/accounts/profile_chgroup.html:20
#: templates/accounts/set_abon_groups_permission.html:21
#: templates/accounts/settings/ch_info.html:69
msgid "Reset"
msgstr "Сбросить"
#: accounts_app/templates/accounts/index.html:8
#: accounts_app/templates/accounts/settings/ch_info.html:37
msgid "Telephone"
msgstr "Телефон"
#: accounts_app/templates/accounts/index.html:12
#: accounts_app/templates/accounts/login.html:35
#: accounts_app/templates/accounts/settings/ch_info.html:8
#: accounts_app/templates/accounts/settings/ch_info.html:12
#: templates/accounts/index.html:13 templates/accounts/login.html:39
#: templates/accounts/settings/ch_info.html:8
#: templates/accounts/settings/ch_info.html:12
msgid "User name"
msgstr "Логин"
#: accounts_app/templates/accounts/index.html:16
#: accounts_app/templates/accounts/settings/ch_info.html:18
#: templates/accounts/index.html:17 templates/accounts/settings/ch_info.html:18
msgid "Name and surname"
msgstr "Фамилия и Имя"
#: accounts_app/templates/accounts/index.html:20
#: templates/accounts/index.html:21
msgid "Is enable"
msgstr "Включён-ли"
#: accounts_app/templates/accounts/index.html:24
#: templates/accounts/index.html:25
msgid "Last login"
msgstr "Последняя авторизация"
#: accounts_app/templates/accounts/index.html:29
#: templates/accounts/index.html:30
msgid "All permissions"
msgstr "Административный доступ (все права)"
#: accounts_app/templates/accounts/login.html:5
#: templates/accounts/login.html:5
msgid "Auth"
msgstr "Аутентификация"
#: accounts_app/templates/accounts/login.html:23
#: accounts_app/templates/accounts/login.html:52
#: templates/accounts/login.html:27 templates/accounts/login.html:56
msgid "Login"
msgstr "Войти"
#: accounts_app/templates/accounts/login.html:43
#: templates/accounts/login.html:47
msgid "Password"
msgstr "Пароль"
#: accounts_app/templates/accounts/profile_chgroup.html:5
msgid "The responsibility of the administrator of the group of subscribers"
msgstr "Ответственность администратора за группы абонентов"
#: templates/accounts/login.html:70
msgid "Contact us"
msgstr "Напишите нам"
#: accounts_app/templates/accounts/settings/ch_info.html:27
msgid "Email"
msgstr "Адрес электронной почты"
#: templates/accounts/perms/objects_of_type.html:9
#: templates/accounts/perms/objects_types.html:10
#: templates/accounts/perms/perms_edit.html:10
msgid "Permission options"
msgstr "Права"
#: accounts_app/templates/accounts/settings/ch_info.html:42
msgid "+[7,8,9,3] and 10,11 digits"
msgstr "+[7,8,9,3] и 10,11 цифр"
#: templates/accounts/perms/objects_of_type.html:13
#: templates/accounts/perms/perms_edit.html:16
msgid "Pick object for edit permissions"
msgstr "Выберите объект для редактирования прав доступа"
#: templates/accounts/perms/objects_types.html:13
msgid "Pick the type of object"
msgstr "Выберите тип объекта"
#: templates/accounts/perms/objects_types.html:21
msgid "Group"
msgstr "Группа"
#: accounts_app/templates/accounts/settings/ch_info.html:47
#: templates/accounts/perms/perms_edit.html:24
msgid "Profile is superuser, permissions to change it makes no sense"
msgstr ""
"Учётная запись является суперпользователем, разрешения менять нет смысла"
#: templates/accounts/perms/perms_edit.html:30
msgid "Change permission for that object"
msgstr "Изменение прав доступа для выбранного объекта"
#: templates/accounts/perms/perms_edit.html:52
msgid "Not set"
msgstr "Не найдено"
#: templates/accounts/profile_chgroup.html:5
msgid "The responsibility of the staff of the group of subscribers"
msgstr "Ответственность работника за группы абонентов"
#: templates/accounts/set_abon_groups_permission.html:5
msgid "The list of user groups to which the account has access"
msgstr "Список групп абонентов, к которым учётка имеет доступ"
#: templates/accounts/settings/ch_info.html:47
msgid "Old password"
msgstr "Старый пароль"
#: accounts_app/templates/accounts/settings/ch_info.html:56
#: templates/accounts/settings/ch_info.html:56
msgid "New password"
msgstr "Новый пароль"
#: accounts_app/views.py:42
#: views.py:45
msgid "Wrong login or password, please try again"
msgstr "Неправильный логин или пароль, попробуйте ещё раз"
#: accounts_app/views.py:141
#: views.py:114
msgid "Please select an image"
msgstr "Пожалуйста выберите изображение"
#: views.py:125
msgid "Avatar successfully changed"
msgstr "Аватар успешно изменён"
#: views.py:153
msgid "New password is empty, fill it"
msgstr "Новый пароль пустой, придумайте себе пароль"
#: accounts_app/views.py:143
#: views.py:155
msgid "Wrong password"
msgstr "Неправильный пароль"
#: accounts_app/views.py:145
#: views.py:157
msgid "Empty password, fill it"
msgstr "Пустой пароль, впишите что-то в пароль"
#: accounts_app/views.py:168
#: views.py:180
msgid "You forget specify a password for the new account"
msgstr "Забыли указать пароль для нового аккаунта"
#: accounts_app/views.py:171
#: views.py:183
msgid "You forget to repeat a password for the new account"
msgstr "Забыли повторить пароль для нового аккаунта"
#: accounts_app/views.py:180
#: views.py:192
msgid "Subscriber with this name already exist"
msgstr "Пользователь с таким именем уже есть"
#: accounts_app/views.py:182
#: views.py:194
msgid "Passwords does not match, try again"
msgstr "Пароли не совпадают, попробуйте ещё раз"
msgid "Administrator"
msgstr "Администратор"
msgid "Options"
msgstr "Настройки"
msgid "Not assigned"
msgstr "&lt;Не назначено&gt;"
msgid "Change self onfo"
msgstr "Изменить инфу о себе"
msgid "Permission options"
msgstr "Права"
msgid "Edit"
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 "Изменение прав доступа для выбранного объекта"
#: views.py:209
msgid "Profile has been deleted"
msgstr "Учётная запись удалена"
#: views.py:279
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 "The responsibility of the administrator of the group of subscribers"
#~ msgstr "Ответственность администратора за группы абонентов"
msgid "Pick the type of object"
msgstr "Выберите тип объекта"
#~ msgid "Administrator"
#~ msgstr "Администратор"
msgid "Profile has been deleted"
msgstr "Учётная запись удалена"
#~ msgid "Options"
#~ msgstr "Настройки"
msgid "profile username"
msgstr "Логин"
msgid "fio"
msgstr "ФИО"
#~ msgid "Change self onfo"
#~ msgstr "Изменить инфу о себе"
msgid "birth day"
msgstr "дата рождения"
#~ msgid "Edit"
#~ msgstr "Редактировать"
msgid "Is active"
msgstr "Активен"
#~ msgid "Access to groups"
#~ msgstr "Доступ к группам"

41
accounts_app/templates/accounts/acc_list.html

@ -1,23 +1,24 @@
{% extends 'base.html' %}
{% load i18n %}
{% block main %}
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li class="active">Администраторы</li>
<li class="active">{% trans 'Administrators' %}</li>
</ol>
{% include 'message_block.html' %}
<h3>Список аккаунтов администраторов</h3>
<h3>{% trans 'Admin accounts list' %}</h3>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th class="col-sm-1">Фото</th>
<th class="col-sm-2">Ник</th>
<th class="col-sm-4">ФИО (или ник если нет)</th>
<th class="col-sm-2 hidden-xs">Телефон</th>
<th class="col-sm-2 hidden-xs">Email</th>
<th class="col-sm-1">{% trans 'Photo' %}</th>
<th class="col-sm-2">{% trans 'profile username' %}</th>
<th class="col-sm-4">{% trans 'Fullname, or login if name is empty' %}</th>
<th class="col-sm-2 hidden-xs">{% trans 'Telephone' %}</th>
<th class="col-sm-2 hidden-xs">{% trans 'Email' %}</th>
<th class="col-sm-1 hidden-xs">&mdash;</th>
</tr>
</thead>
@ -30,10 +31,20 @@
</a></td>
<td><a href="{% url 'acc_app:other_profile' usr.id %}">{{ usr.username }}</a></td>
<td>{{ usr.get_full_name }}</td>
<td class="hidden-xs">{% if usr.telephone %}<a href="tel:{{ usr.telephone }}">{{ usr.telephone }}</a>{% else %}
Нету{% endif %}</td>
<td class="hidden-xs">{% if usr.email %}<a href="mailto:{{ usr.email }}">{{ usr.email }}{% else %}
Нету{% endif %}</a></td>
<td class="hidden-xs">
{% if usr.telephone %}
<a href="tel:{{ usr.telephone }}">{{ usr.telephone }}</a>
{% else %}
{% trans 'Not assigned' %}
{% endif %}
</td>
<td class="hidden-xs">
{% if usr.email %}
<a href="mailto:{{ usr.email }}">{{ usr.email }}</a>
{% else %}
{% trans 'Not assigned' %}
{% endif %}
</td>
{% if usr.id == request.user.id or perms.acc_app.delete_userprofile %}
<td class="btn-group hidden-xs">
<a href="{% url 'acc_app:delete_profile' usr.id %}" class="btn btn-sm btn-danger">
@ -42,7 +53,7 @@
</td>
{% else %}
<td class="btn-group hidden-xs">
<a href="#" class="btn btn-sm btn-danger disabled" title="Не прав на удаление">
<a href="#" class="btn btn-sm btn-danger disabled" title="{% trans 'You have not permissions to delete' %}">
<span class="glyphicon glyphicon-remove"></span>
</a>
</td>
@ -51,7 +62,7 @@
</tr>
{% empty %}
<tr>
<td colspan="6"><b>Нет пользователей</b></td>
<td colspan="6"><b>{% trans 'Users not found' %}</b></td>
</tr>
{% endfor %}
</tbody>
@ -59,7 +70,7 @@
<tfoot>
<tr>
<th colspan="6">
<a href="{% url 'acc_app:create_profile' %}" class="btn btn-default" title="Добавить аккаунт">
<a href="{% url 'acc_app:create_profile' %}" class="btn btn-default" title="{% trans 'Add account' %}">
<span class="glyphicon glyphicon-plus-sign"></span>
</a>
</th>
@ -69,6 +80,6 @@
</table>
</div>
{% include 'toolbar_page.html' with pag=users %}
{% include 'pagination.html' %}
{% endblock %}

28
accounts_app/templates/accounts/create_acc.html

@ -3,15 +3,15 @@
<ol class="breadcrumb">
<li><span class="glyphicon glyphicon-home"></span></li>
<li><a href="{% url 'acc_app:accounts_list' %}">Администраторы</a></li>
<li class="active">Добавить</li>
<li><a href="{% url 'acc_app:accounts_list' %}">{% trans 'Administrators' %}</a></li>
<li class="active">{% trans 'Add' %}</li>
</ol>
{% include 'message_block.html' %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Создайте новый аккаунт</h3>
<h3 class="panel-title">{% trans 'Create new account' %}</h3>
</div>
<div class="panel-body">
<div class="row">
@ -28,26 +28,26 @@
<form role="form" action="{% url 'acc_app:create_profile' %}" method="post">{% csrf_token %}
<div class="form-group">
<label for="login">Логин</label>
<label for="login">{% trans 'Username' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
<input id="login" type="text" name="username" placeholder="Имя пользователя" required
<input id="login" type="text" name="username" placeholder="{% trans 'Username' %}" required
value="{{ newuser.username }}" class="form-control">
</div>
</div>
<div class="form-group">
<label for="fio">Фамилия Имя</label>
<label for="fio">{% trans 'Fullname' %}</label>
<div class="input-group">
<span class="input-group-addon"><span
class="glyphicon glyphicon-folder-close"></span></span>
<input id="fio" type="text" name="fio" placeholder="ФИО" value="{{ newuser.fio }}"
<input id="fio" type="text" name="fio" placeholder="{% trans 'Fullname' %}" value="{{ newuser.fio }}"
class="form-control">
</div>
</div>
<div class="form-group">
<label for="mail">Почта</label>
<label for="mail">{% trans 'EMail' %}</label>
<div class="input-group">
<span class="input-group-addon"><span
@ -57,17 +57,17 @@
</div>
</div>
<div class="form-group">
<label for="tel">Телефон</label>
<label for="tel">{% trans 'Telephone' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-phone"></span></span>
<input id="tel" type="tel" pattern="\+[7,8,9,3]\d{10,11}" name="telephone"
placeholder="+[7,8,9,3] и 10,11 цифр" value="{{ newuser.telephone }}"
placeholder="{% trans '+[7,8,9,3] and 10,11 digits' %}" value="{{ newuser.telephone }}"
class="form-control" required>
</div>
</div>
<div class="form-group">
<label for="passw1">Введите пароль</label>
<label for="passw1">{% trans 'Type password' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
@ -75,7 +75,7 @@
</div>
</div>
<div class="form-group">
<label for="passw2">Повторите пароль</label>
<label for="passw2">{% trans 'Repeat password' %}</label>
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
@ -84,10 +84,10 @@
</div>
<div class="btn-group">
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-floppy-disk"></span> Сохранить
<span class="glyphicon glyphicon-floppy-disk"></span> {% trans 'Save' %}
</button>
<button type="reset" class="btn btn-default">
<span class="glyphicon glyphicon-remove"></span> Сбросить
<span class="glyphicon glyphicon-remove"></span> {% trans 'Reset' %}
</button>
</div>
</form>

2
accounts_app/templates/accounts/login.html

@ -67,7 +67,7 @@
<footer class="footer">
<div class="container">
<p class="text-muted">
Напишите нам <i>is-ttk@ya.ru</i>.
{% trans 'Contact us' %} <i>is-ttk@ya.ru</i>.
</p>
</div>
</footer>

2
accounts_app/templates/accounts/perms/objects_of_type.html

@ -29,6 +29,6 @@
</table>
</div>
{% include 'toolbar_page.html' with pag=objects %}
{% include 'pagination.html' %}
{% endblock %}

4
accounts_app/urls.py

@ -13,7 +13,7 @@ urlpatterns = [
url(r'^me$', views.profile_show, name='profile'),
url(r'^$', views.acc_list, name='accounts_list'),
url(r'^$', views.AccountsListView.as_view(), name='accounts_list'),
url(r'^add$', views.create_profile, name='create_profile'),
@ -22,7 +22,7 @@ urlpatterns = [
url(r'^(?P<uid>\d+)$', views.profile_show, name='other_profile'),
url(r'^(?P<uid>\d+)/perms$', views.perms, name='setup_perms'),
url(r'^(?P<uid>\d+)/perms/(?P<klass_name>[a-z_]+\.[a-zA-Z_]+)$', views.perms_klasses, name='perms_klasses'),
url(r'^(?P<uid>\d+)/perms/(?P<klass_name>[a-z_]+\.[a-zA-Z_]+)$', views.PermissionClassListView.as_view(), name='perms_klasses'),
url(r'^(?P<uid>\d+)/perms/(?P<klass_name>[a-z_]+\.[a-zA-Z_]+)/(?P<obj_id>\d+)$', views.perms_edit, name='perms_edit'),
url(r'^(?P<uid>\d+)/chgroup$', views.chgroup, name='profile_setup_group'),
url(r'^(?P<uid>\d+)/del$', views.delete_profile, name='delete_profile'),

67
accounts_app/views.py

@ -5,7 +5,11 @@ from django.core.exceptions import PermissionDenied
from django.urls import NoReverseMatch
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
from django.views.generic import ListView
from django.conf import settings
from abonapp.models import AbonGroup
from photo_app.models import Photo
@ -15,6 +19,11 @@ from guardian.decorators import permission_required_or_403 as permission_require
from guardian.shortcuts import get_objects_for_user, assign_perm, remove_perm
class BaseAccListView(ListView):
http_method_names = ['get']
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@login_required
@mydefs.only_admins
def home(request):
@ -208,15 +217,15 @@ def delete_profile(request, uid):
return redirect('acc_app:accounts_list')
@login_required
@mydefs.only_admins
def acc_list(request):
users = UserProfile.objects.filter(is_admin=True).exclude(pk=request.user.pk)
users = get_objects_for_user(request.user, 'accounts_app.can_view_userprofile', users)
users = mydefs.pag_mn(request, users)
return render(request, 'accounts/acc_list.html', {
'users': users
})
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
class AccountsListView(BaseAccListView):
template_name = 'accounts/acc_list.html'
context_object_name = 'users'
def get_queryset(self):
users = UserProfile.objects.filter(is_admin=True).exclude(pk=self.request.user.pk)
users = get_objects_for_user(self.request.user, 'accounts_app.can_view_userprofile', users)
return users
@login_required
@ -235,24 +244,32 @@ def perms(request, uid):
})
@login_required
def perms_klasses(request, uid, klass_name):
if not request.user.is_superuser:
raise PermissionDenied
from django.apps import apps
userprofile = get_object_or_404(UserProfile, pk=uid)
app_label, model_name = klass_name.split('.', 1)
klass = apps.get_model(app_label, model_name)
@method_decorator(login_required, name='dispatch')
class PermissionClassListView(BaseAccListView):
template_name = 'accounts/perms/objects_of_type.html'
context_object_name = 'objects'
objects = klass.objects.all()
objects = mydefs.pag_mn(request, objects)
def get(self, request, *args, **kwargs):
if not request.user.is_superuser:
raise PermissionDenied
return super(PermissionClassListView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(PermissionClassListView, self).get_context_data(**kwargs)
context['klass'] = self.kwargs.get('klass_name')
context['klass_name'] = self.required_klass_name._meta.verbose_name
context['userprofile'] = get_object_or_404(UserProfile, pk=self.kwargs.get('uid'))
return context
def get_queryset(self):
from django.apps import apps
klass_name = self.kwargs.get('klass_name')
app_label, model_name = klass_name.split('.', 1)
klass = apps.get_model(app_label, model_name)
objects = klass.objects.all()
self.required_klass_name = klass
return objects
return render(request, 'accounts/perms/objects_of_type.html', {
'userprofile': userprofile,
'klass': klass_name,
'klass_name': klass._meta.verbose_name,
'objects': objects
})
@login_required
def perms_edit(request, uid, klass_name, obj_id):

3
clientsideapp/views.py

@ -8,7 +8,7 @@ from django.utils.translation import gettext_lazy as _
from abonapp.models import AbonLog, InvoiceForPayment, Abon
from tariff_app.models import Tariff
from mydefs import pag_mn, LogicError
from mydefs import LogicError
from agent import NasFailedResult, NasNetworkError
@ -20,7 +20,6 @@ def home(request):
@login_required
def pays(request):
pay_history = AbonLog.objects.filter(abon=request.user).order_by('-id')
pay_history = pag_mn(request, pay_history)
return render(request, 'clientsideapp/pays.html', {
'pay_history': pay_history
})

8
devapp/templates/devapp/devices_null_group.html

@ -16,19 +16,19 @@
<thead>
<tr>
<th>
<a href="{% url 'devapp:devices_null_group' %}?order_by=ip_address&dir={{ dir|default:"down" }}">
<a href="{% url 'devapp:devices_null_group' %}?order_by=ip_address&dir={{ dir|default:'down' }}">
{% trans 'Ip address' %}
</a>
{% if order_by == 'ip_address' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th>
<a href="{% url 'devapp:devices_null_group' %}?order_by=comment&dir={{ dir|default:"down" }}">
<a href="{% url 'devapp:devices_null_group' %}?order_by=comment&dir={{ dir|default:'down' }}">
{% trans 'Comment' %}
</a>
{% if order_by == 'comment' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th width="250">
<a href="{% url 'devapp:devices_null_group' %}?order_by=devtype&dir={{ dir|default:"down" }}">
<a href="{% url 'devapp:devices_null_group' %}?order_by=devtype&dir={{ dir|default:'down' }}">
{% trans 'Device type' %}
</a>
{% if order_by == 'devtype' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
@ -78,6 +78,6 @@
</table>
</div>
{% include 'toolbar_page.html' with pag=devices %}
{% include 'pagination.html' %}
{% endblock %}

2
devapp/templates/devapp/group_list.html

@ -46,6 +46,6 @@
</table>
</div>
{% include 'toolbar_page.html' with pag=groups %}
{% include 'pagination.html' %}
{% endblock %}

4
devapp/urls.py

@ -4,8 +4,8 @@ from . import views
app_name = 'devapp'
urlpatterns = [
url(r'^$', views.group_list, name='group_list'),
url(r'^devices_without_groups$', views.devices_null_group, name='devices_null_group'),
url(r'^$', views.GroupsListView.as_view(), name='group_list'),
url(r'^devices_without_groups$', views.DevicesWithoutGroupsListView.as_view(), name='devices_null_group'),
url(r'^fix_onu/$', views.fix_onu, name='fix_onu'),
url(r'^(?P<group_id>\d+)$', views.DevicesListView.as_view(), name='devs'),
url(r'^(?P<group_id>\d+)/add$', views.dev, name='add'),

51
devapp/views.py

@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _, gettext
from easysnmp import EasySNMPTimeoutError, EasySNMPError
from django.views.generic import ListView, DetailView
from mydefs import pag_mn, res_success, res_error, only_admins, ping, order_helper, ip_addr_regex
from mydefs import res_success, res_error, only_admins, ping, ip_addr_regex
from abonapp.models import AbonGroup, Abon
from django.conf import settings
from guardian.decorators import permission_required_or_403 as permission_required
@ -30,12 +30,15 @@ from mydefs import safe_int
PAGINATION_ITEMS_PER_PAGE = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
class BaseDeviceListView(ListView):
http_method_names = ['get']
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
@method_decorator([login_required, only_admins], name='dispatch')
class DevicesListView(ListView, OrderingMixin):
class DevicesListView(BaseDeviceListView, OrderingMixin):
context_object_name = 'devices'
template_name = 'devapp/devices.html'
paginate_by = PAGINATION_ITEMS_PER_PAGE
http_method_names = ['get']
def get_queryset(self):
group_id = safe_int(self.kwargs.get('group_id'))
@ -59,22 +62,11 @@ class DevicesListView(ListView, OrderingMixin):
return response
@login_required
@only_admins
def devices_null_group(request):
devs = Device.objects.filter(user_group=None).only('comment', 'devtype', 'user_group', 'pk', 'ip_address')
dr, field = order_helper(request)
if field:
devs = devs.order_by(field)
devs = pag_mn(request, devs)
return render(request, 'devapp/devices_null_group.html', {
'devices': devs,
'dir': dr,
'order_by': request.GET.get('order_by')
})
@method_decorator([login_required, only_admins], name='dispatch')
class DevicesWithoutGroupsListView(BaseDeviceListView, OrderingMixin):
context_object_name = 'devices'
template_name = 'devapp/devices_null_group.html'
queryset = Device.objects.filter(user_group=None).only('comment', 'devtype', 'user_group', 'pk', 'ip_address')
@login_required
@ -412,14 +404,17 @@ def toggle_port(request, device_id, portid, status=0):
return redirect('devapp:view', dev.user_group.pk if dev.user_group is not None else 0, device_id)
@login_required
@only_admins
def group_list(request):
groups = AbonGroup.objects.all().order_by('title')
groups = get_objects_for_user(request.user, 'abonapp.can_view_abongroup', klass=groups, accept_global_perms=False)
return render(request, 'devapp/group_list.html', {
'groups': groups
})
@method_decorator([login_required, only_admins], name='dispatch')
class GroupsListView(BaseDeviceListView):
context_object_name = 'groups'
template_name = 'devapp/group_list.html'
model = AbonGroup
def get_queryset(self):
groups = super(GroupsListView, self).get_queryset()
groups = get_objects_for_user(self.request.user, 'abonapp.can_view_abongroup', klass=groups,
accept_global_perms=False)
return groups
@login_required

14
djing/urls.py

@ -1,5 +1,5 @@
from django.conf.urls import url, include
# from django.conf import settings
from django.conf import settings
from django.contrib import admin
from .views import home
@ -21,11 +21,9 @@ urlpatterns = [
]
# if settings.DEBUG:
# from django.conf.urls.static import static
# from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# from django.contrib import admin
if settings.DEBUG:
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# urlpatterns += staticfiles_urlpatterns()
# urlpatterns += [url(r'^admin/', admin.site.urls)]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()

2
msg_app/templates/msg_app/conversations.html

@ -57,6 +57,6 @@
</div>
</div>
{% include 'toolbar_page.html' with pag=conversations %}
{% include 'pagination.html' %}
{% endblock %}

2
msg_app/urls.py

@ -6,7 +6,7 @@ app_name = 'msg_app'
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^$', views.ConversationsListView.as_view(), name='home'),
url(r'^new$', views.new_conversation, name='new_conversation'),
url(r'^(?P<conv_id>\d+)/$', views.to_conversation, name='to_conversation'),
url(r'^(?P<conv_id>\d+)/(?P<msg_id>\d+)/del$', views.remove_msg, name='remove_msg'),

21
msg_app/views.py

@ -3,24 +3,26 @@ from django.contrib.auth.decorators import login_required
from django.contrib.gis.shortcuts import render_to_text
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
from django.contrib import messages
from django.shortcuts import render, redirect, get_object_or_404
from django.views.generic import ListView
from chatbot.models import MessageQueue
from mydefs import pag_mn
from .models import Conversation, MessageError, Message
from .forms import ConversationForm, MessageForm
@login_required
def home(request):
# TODO: optimise queries
conversations = Conversation.objects.fetch(request.user)
conversations = pag_mn(request, conversations, 8)
return render(request, 'msg_app/conversations.html', {
'conversations': conversations
})
@method_decorator(login_required, name='dispatch')
class ConversationsListView(ListView):
context_object_name = 'conversations'
template_name = 'msg_app/conversations.html'
def get_queryset(self):
# TODO: optimise queries
return Conversation.objects.fetch(self.request.user)
@login_required
@ -90,4 +92,3 @@ def check_news(request):
else:
r = {'auth': False}
return HttpResponse(dumps(r))

56
mydefs.py

@ -8,15 +8,16 @@ import os
from functools import wraps
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import redirect
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db import models
from django.conf import settings
PAGINATION_ITEMS_PER_PAGE = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
DEBUG = getattr(settings, 'DEBUG', False)
ip_addr_regex = r'^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
ip_addr_regex = r'^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \
r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
def ip2int(addr):
@ -61,19 +62,6 @@ def res_error(request, text):
raise Http404(text)
# Pagination
def pag_mn(request, objs, count_per_page=PAGINATION_ITEMS_PER_PAGE):
page = request.GET.get('p')
pgn = Paginator(objs, count_per_page)
try:
objs = pgn.page(page)
except PageNotAnInteger:
objs = pgn.page(1)
except EmptyPage:
objs = pgn.page(pgn.num_pages)
return objs
class MyGenericIPAddressField(models.GenericIPAddressField):
description = "Int32 notation ip address"
@ -124,26 +112,6 @@ class MyChoicesAdapter(Iterator):
return res
# Для сортировки таблиц
# через get должно быть передано order_by=<поле в бд> а в dir=<up|down> направление сортировки
# возвращает новое направление сортировки и поле для сортировки с направлением
def order_helper(request):
print('DEPRECATION: use global_base_views.OrderingMixin')
dr = request.GET.get('dir')
dfx = ''
if dr == 'down':
dr = 'up'
dfx = '-'
else:
dr = 'down'
orby = request.GET.get('order_by')
if orby:
return dr, dfx + orby
else:
return dr, orby
# Декоратор проверяет аккаунт, чтоб не пускать клиентов в страницы администрации
def only_admins(fn):
@wraps(fn)
@ -163,7 +131,6 @@ def ping(hostname, count=1):
# Русифицированный вывод timedelta
class RuTimedelta(timedelta):
def __new__(cls, tm):
if isinstance(tm, timedelta):
return timedelta.__new__(
@ -174,19 +141,19 @@ class RuTimedelta(timedelta):
)
def __str__(self):
#hours, remainder = divmod(self.seconds, 3600)
#minutes, seconds = divmod(remainder, 60)
#text_date = "%d:%d" % (
# hours, remainder = divmod(self.seconds, 3600)
# minutes, seconds = divmod(remainder, 60)
# text_date = "%d:%d" % (
# hours,
# minutes
#)
# )
if self.days > 1:
ru_days = 'дней'
if 5 > self.days > 1:
ru_days = 'дня'
elif self.days == 1:
ru_days = 'день'
#text_date = '%d %s %s' % (self.days, ru_days, text_date)
# text_date = '%d %s %s' % (self.days, ru_days, text_date)
text_date = '%d %s' % (self.days, ru_days)
else:
text_date = ''
@ -199,17 +166,18 @@ def require_ssl(view):
the page.
from: https://gist.github.com/ckinsey/9709984
"""
@wraps(view)
def wrapper(request, *args, **kwargs):
if not DEBUG and not request.is_secure():
target_url = "https://" + request.META['HTTP_HOST'] + request.path_info
return HttpResponseRedirect(target_url)
return view(request, *args, **kwargs)
return wrapper
class MultipleException(Exception):
def __init__(self, err_list):
if not isinstance(err_list, list):
raise TypeError
@ -222,8 +190,10 @@ class LogicError(Exception):
def singleton(class_):
instances = {}
def getinstance(*args, **kwargs):
if class_ not in instances:
instances[class_] = class_(*args, **kwargs)
return instances[class_]
return getinstance

5
tariff_app/locale/ru/LC_MESSAGES/django.po

@ -132,3 +132,8 @@ msgstr "Пробная логика"
msgid "Add new periodic pay"
msgstr "Добавить периодический платёж"
msgid "Service"
msgstr "Услуга"
msgid "Services"
magstr "Услуги"

23
tariff_app/migrations/0007_auto_20180215_1423.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-02-15 14:23
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('tariff_app', '0006_auto_20180122_1732'),
]
operations = [
migrations.AlterModelOptions(
name='tariff',
options={'ordering': ['title'], 'verbose_name': 'Service', 'verbose_name_plural': 'Services'},
),
migrations.AlterModelTable(
name='tariff',
table='tariffs',
),
]

12
tariff_app/models.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from django.db import models, IntegrityError
from django.utils.translation import gettext_lazy as _
@ -19,8 +18,11 @@ class Tariff(models.Model):
choices=MyChoicesAdapter(TARIFF_CHOICES))
is_admin = models.BooleanField(_('Tech service'), default=False)
# Возвращает потомок класса TariffBase, методы которого дают нужную логику оплаты по тарифу
def get_calc_type(self):
"""
:return: Child of tariff_app.base_intr.TariffBase,
methods which provide the desired logic of payments
"""
calc_code = self.calc_type
for choice_pair in TARIFF_CHOICES:
choice_code, logic_class = choice_pair
@ -37,6 +39,12 @@ class Tariff(models.Model):
def __str__(self):
return "%s (%.2f)" % (self.title, self.amount)
class Meta:
db_table = 'tariffs'
ordering = ['title']
verbose_name = _('Service')
verbose_name_plural = _('Services')
class PeriodicPay(models.Model):
name = models.CharField(_('Periodic pay name'), max_length=64)

2
tariff_app/templates/tariff_app/periodic_pays/list.html

@ -57,6 +57,6 @@
</table>
</div>
{% include 'toolbar_page.html' with pag=pays %}
{% include 'pagination.html' %}
{% endblock %}

12
tariff_app/templates/tariff_app/tarifs.html

@ -7,25 +7,25 @@
<thead>
<tr>
<th>
<a href="{% url 'tarifs:home' %}?order_by=title&dir={{ dir|default:"down" }}">
<a href="{% url 'tarifs:home' %}?order_by=title&dir={{ dir|default:'down' }}">
{% trans 'tariff' %}
</a>
{% if order_by == 'title' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th>
<a href="{% url 'tarifs:home' %}?order_by=speedIn&dir={{ dir|default:"down" }}">
<a href="{% url 'tarifs:home' %}?order_by=speedIn&dir={{ dir|default:'down' }}">
{% trans 'Speed In' %}
</a>
{% if order_by == 'speedIn' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th>
<a href="{% url 'tarifs:home' %}?order_by=speedOut&dir={{ dir|default:"down" }}">
<a href="{% url 'tarifs:home' %}?order_by=speedOut&dir={{ dir|default:'down' }}">
{% trans 'Speed Out' %}
</a>
{% if order_by == 'speedOut' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
</th>
<th>
<a href="{% url 'tarifs:home' %}?order_by=amount&dir={{ dir|default:"down" }}">
<a href="{% url 'tarifs:home' %}?order_by=amount&dir={{ dir|default:'down' }}">
{% trans 'Price' %}
</a>
{% if order_by == 'amount' %}<span class="glyphicon glyphicon-filter"></span>{% endif %}
@ -59,7 +59,7 @@
</tr>
{% empty %}
<tr>
<td colspan="6">{% trans 'Услуги пока не существуют' %}.
<td colspan="6">{% trans 'Services does not exist yet' %}.
{% if perms.tariff_app.add_tariff %}
<a href="{% url 'tarifs:add' %}" class="lgtbx">{% trans 'Create' %}</a>
{% endif %}
@ -84,6 +84,6 @@
</table>
</div>
{% include 'toolbar_page.html' with pag=tariflist %}
{% include 'pagination.html' %}
{% endblock %}

4
tariff_app/urls.py

@ -5,12 +5,12 @@ from . import views
app_name = 'tariff_app'
urlpatterns = [
url(r'^$', views.tarifs, name='home'),
url(r'^$', views.TariffsListView.as_view(), name='home'),
url(r'^(?P<tarif_id>\d+)$', views.edit_tarif, name='edit'),
url(r'^add$', views.edit_tarif, name='add'),
url(r'^del(?P<tid>\d+)$', views.del_tarif, name='del'),
url(r'^periodic_pays$', views.periodic_pays, name='periodic_pays'),
url(r'^periodic_pays$', views.PeriodicPaysListView.as_view(), name='periodic_pays'),
url(r'^periodic_pays/add$', views.periodic_pay, name='periodic_pay_add'),
url(r'^periodic_pays/(?P<pay_id>\d+)$', views.periodic_pay, name='periodic_pay_edit')
]

44
tariff_app/views.py

@ -1,34 +1,34 @@
# -*- coding: utf-8 -*-
from django.contrib.auth.decorators import login_required
from django.contrib.gis.shortcuts import render_to_text
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.views.generic import ListView
from django.conf import settings
from guardian.decorators import permission_required_or_403 as permission_required
from djing.global_base_views import OrderingMixin
from .models import Tariff, PeriodicPay
import mydefs
from . import forms
@login_required
@mydefs.only_admins
def tarifs(request):
tars = Tariff.objects.order_by('title')
# фильтр
direct, field = mydefs.order_helper(request)
if field:
tars = tars.order_by(field)
class BaseServiceListView(ListView):
http_method_names = ['get']
paginate_by = getattr(settings, 'PAGINATION_ITEMS_PER_PAGE', 10)
tars = mydefs.pag_mn(request, tars)
return render(request, 'tariff_app/tarifs.html', {
'tariflist': tars,
'dir': direct,
'order_by': request.GET.get('order_by')
})
@method_decorator([login_required, mydefs.only_admins], name='dispatch')
class TariffsListView(BaseServiceListView, OrderingMixin):
"""
Show Services(Tariffs) list
"""
template_name = 'tariff_app/tarifs.html'
context_object_name = 'tariflist'
model = Tariff
@login_required
@ -74,14 +74,12 @@ def del_tarif(request, tid):
return render_to_text('tariff_app/modal_del_warning.html', {'tid': tid}, request=request)
@login_required
@permission_required('tariff_app.can_view_periodic_pay')
def periodic_pays(request):
pays = PeriodicPay.objects.all()
pays = mydefs.pag_mn(request, pays)
return render(request, 'tariff_app/periodic_pays/list.html', {
'pays': pays
})
@method_decorator(login_required, name='dispatch')
@method_decorator(permission_required('tariff_app.can_view_periodic_pay'), name='dispatch')
class PeriodicPaysListView(BaseServiceListView):
context_object_name = 'pays'
model = PeriodicPay
template_name = 'tariff_app/periodic_pays/list.html'
@login_required

26
templates/toolbar_page.html

@ -1,26 +0,0 @@
{% if pag.paginator.num_pages > 1 %}
{% load dpagination %}
<div class="row">
<div class="col-sm-4 col-sm-offset-4">
<ul class="pagination">
{% if pag.number == 1 %}
<li class="disabled"><a href="#">&laquo;</a></li>
{% else %}
<li><a href="?{% url_page_replace request 'p' 1 %}">&laquo;</a></li>
{% endif %}
{% if pag.has_previous %}
<li><a href="?{% url_page_replace request 'p' pag.previous_page_number %}">{{ pag.previous_page_number }}</a></li>
{% endif %}
<li class="disabled"><a href="#">{{ pag.number }}</a></li>
{% if pag.has_next %}
<li><a href="?{% url_page_replace request 'p' pag.next_page_number %}">{{ pag.next_page_number }}</a></li>
{% endif %}
{% if pag.number == pag.paginator.num_pages %}
<li class="disabled"><a href="#">&raquo;</a></li>
{% else %}
<li><a href="?{% url_page_replace request 'p' pag.paginator.num_pages %}">&raquo;</a></li>
{% endif %}
</ul>
</div>
</div>
{% endif %}
Loading…
Cancel
Save