resolve conflicts
1
.gitignore
vendored
@ -12,6 +12,7 @@ local_settings.py
|
|||||||
db.sqlite3
|
db.sqlite3
|
||||||
db.sqlite3-journal
|
db.sqlite3-journal
|
||||||
media/
|
media/
|
||||||
|
logs/
|
||||||
|
|
||||||
# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/
|
# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/
|
||||||
# in your Git repository. Update and uncomment the following line accordingly.
|
# in your Git repository. Update and uncomment the following line accordingly.
|
||||||
|
@ -143,41 +143,7 @@ AUTHENTICATION_BACKENDS = [
|
|||||||
|
|
||||||
# Logging system
|
# Logging system
|
||||||
# https://docs.djangoproject.com/en/3.1/topics/logging/
|
# https://docs.djangoproject.com/en/3.1/topics/logging/
|
||||||
LOGGING = {
|
|
||||||
'version': 1,
|
|
||||||
'disable_existing_loggers': False,
|
|
||||||
'formatters': {
|
|
||||||
'verbose': {
|
|
||||||
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
|
|
||||||
'style': '{',
|
|
||||||
},
|
|
||||||
'simple': {
|
|
||||||
'format': '{levelname} {message}',
|
|
||||||
'style': '{',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'handlers': {
|
|
||||||
'console': {
|
|
||||||
'level': 'INFO',
|
|
||||||
'class': 'logging.StreamHandler',
|
|
||||||
'formatter': 'simple'
|
|
||||||
},
|
|
||||||
'mail_admins': {
|
|
||||||
'level': 'ERROR',
|
|
||||||
'class': 'django.utils.log.AdminEmailHandler',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'loggers': {
|
|
||||||
'django': {
|
|
||||||
'handlers': ['console'],
|
|
||||||
'propagate': True,
|
|
||||||
},
|
|
||||||
'main.index': {
|
|
||||||
'handlers': ['console'],
|
|
||||||
'level': 'INFO',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ZENDESK_ROLES = {
|
ZENDESK_ROLES = {
|
||||||
'engineer': 360005209000,
|
'engineer': 360005209000,
|
||||||
|
12
data.json
@ -1,7 +1,7 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"model": "auth.user",
|
"model": "auth.user",
|
||||||
"pk": 1,
|
"pk": 3,
|
||||||
"fields": {
|
"fields": {
|
||||||
"password": "pbkdf2_sha256$216000$gHBBCr1jBELf$ZkEDW3IEd8Wij7u8vkv+0Eze32CS01bcaYWhcD9OIC4=",
|
"password": "pbkdf2_sha256$216000$gHBBCr1jBELf$ZkEDW3IEd8Wij7u8vkv+0Eze32CS01bcaYWhcD9OIC4=",
|
||||||
"last_login": null,
|
"last_login": null,
|
||||||
@ -19,16 +19,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"model": "main.userprofile",
|
"model": "main.userprofile",
|
||||||
"pk": 1,
|
"pk": 3,
|
||||||
"fields": {
|
"fields": {
|
||||||
"name": "ZendeskAdmin",
|
"name": "ZendeskAdmin",
|
||||||
"user": 1,
|
"user": 3,
|
||||||
"role": "admin"
|
"role": "admin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"model": "auth.user",
|
"model": "auth.user",
|
||||||
"pk": 2,
|
"pk": 4,
|
||||||
"fields": {
|
"fields": {
|
||||||
"password": "pbkdf2_sha256$216000$5qLJgrm2Quq9$KDBNNymVZXkUx0HKBPFst2m83kLe0egPBnkW7KnkORU=",
|
"password": "pbkdf2_sha256$216000$5qLJgrm2Quq9$KDBNNymVZXkUx0HKBPFst2m83kLe0egPBnkW7KnkORU=",
|
||||||
"last_login": null,
|
"last_login": null,
|
||||||
@ -46,10 +46,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"model": "main.userprofile",
|
"model": "main.userprofile",
|
||||||
"pk": 2,
|
"pk": 4,
|
||||||
"fields": {
|
"fields": {
|
||||||
"name": "UserForAccessTest",
|
"name": "UserForAccessTest",
|
||||||
"user": 2,
|
"user": 4,
|
||||||
"role": "agent",
|
"role": "agent",
|
||||||
"custom_role_id": "360005209000"
|
"custom_role_id": "360005209000"
|
||||||
}
|
}
|
||||||
|
BIN
docs/source/_static/admin_manage.png
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
docs/source/_static/admin_manage_done.png
Normal file
After Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 53 KiB |
BIN
docs/source/_static/main_logout.png
Normal file
After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 65 KiB |
BIN
docs/source/_static/request.png
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
docs/source/_static/role_change.png
Normal file
After Width: | Height: | Size: 63 KiB |
@ -3,7 +3,7 @@
|
|||||||
=========================
|
=========================
|
||||||
|
|
||||||
******************************
|
******************************
|
||||||
**Управление правами доступа**
|
Управление правами доступа
|
||||||
******************************
|
******************************
|
||||||
|
|
||||||
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
* **"Войти"** - если Вы уже являетесь зарегистрированным пользователем
|
* **"Войти"** - если Вы уже являетесь зарегистрированным пользователем
|
||||||
* **"Зарегистрироваться"** - при первом входе
|
* **"Зарегистрироваться"** - при первом входе
|
||||||
|
|
||||||
.. image:: _static/main.png
|
.. image:: _static/main_logout.png
|
||||||
|
|
||||||
Внимание! Для регистрации используется email с сайта Zendesk. Регистрация по каждому email
|
Внимание! Для регистрации используется email с сайта Zendesk. Регистрация по каждому email
|
||||||
возможна один раз
|
возможна один раз
|
||||||
@ -32,7 +32,7 @@
|
|||||||
* **"Профиль"** - просмотреть свои данные и запросить права доступа
|
* **"Профиль"** - просмотреть свои данные и запросить права доступа
|
||||||
* **"Запрос прав"** - получение прав для работы с тикетами или **"Управление"** - доступно для администратора и предоставляет возможность группового назначения ролей пользователям
|
* **"Запрос прав"** - получение прав для работы с тикетами или **"Управление"** - доступно для администратора и предоставляет возможность группового назначения ролей пользователям
|
||||||
|
|
||||||
.. image:: _static/main_logined_agent.png
|
.. image:: _static/main.png
|
||||||
|
|
||||||
*************
|
*************
|
||||||
Регистрация
|
Регистрация
|
||||||
@ -72,7 +72,11 @@
|
|||||||
На странице запроса прав Вам доступна информация о количестве и списке работающих над тикетами сотрудников,
|
На странице запроса прав Вам доступна информация о количестве и списке работающих над тикетами сотрудников,
|
||||||
а также возможность сдать и запросить права.
|
а также возможность сдать и запросить права.
|
||||||
|
|
||||||
.. image:: _static/permission_request.png
|
.. image:: _static/request.png
|
||||||
|
|
||||||
|
Успешное изменение прав:
|
||||||
|
|
||||||
|
.. image:: _static/role_change.png
|
||||||
|
|
||||||
******************************************
|
******************************************
|
||||||
Управление правами доступа администратором
|
Управление правами доступа администратором
|
||||||
@ -84,6 +88,10 @@
|
|||||||
* Количество и список инженеров и легких агентов
|
* Количество и список инженеров и легких агентов
|
||||||
* Возможность группового назначения прав с использованием чек-боксов
|
* Возможность группового назначения прав с использованием чек-боксов
|
||||||
|
|
||||||
.. image:: _static/permission_management.png
|
.. image:: _static/admin_manage.png
|
||||||
|
|
||||||
|
Изменение прав пользователей наглядно отразится в таблице пользователей:
|
||||||
|
|
||||||
|
.. image:: _static/admin_manage_done.png
|
||||||
|
|
||||||
.. |copy| unicode:: 0xA9 .. Школа программистов S101, группа 2. 2021гю
|
.. |copy| unicode:: 0xA9 .. Школа программистов S101, группа 2. 2021гю
|
||||||
|
@ -80,6 +80,8 @@ API
|
|||||||
functions
|
functions
|
||||||
Serializer
|
Serializer
|
||||||
Serializers
|
Serializers
|
||||||
|
Сериализатор
|
||||||
|
переадресации
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
from datetime import timedelta, datetime, date
|
from datetime import timedelta, datetime, date
|
||||||
|
|
||||||
@ -7,6 +8,7 @@ from django.utils import timezone
|
|||||||
from zenpy import Zenpy
|
from zenpy import Zenpy
|
||||||
from zenpy.lib.exception import APIException
|
from zenpy.lib.exception import APIException
|
||||||
|
|
||||||
|
|
||||||
from access_controller.settings import ZENDESK_ROLES as ROLES, ONE_DAY, ZENDESK_GROUPS, SOLVED_TICKETS_EMAIL
|
from access_controller.settings import ZENDESK_ROLES as ROLES, ONE_DAY, ZENDESK_GROUPS, SOLVED_TICKETS_EMAIL
|
||||||
from main.models import UserProfile, RoleChangeLogs, UnassignedTicket, UnassignedTicketStatus
|
from main.models import UserProfile, RoleChangeLogs, UnassignedTicket, UnassignedTicketStatus
|
||||||
|
|
||||||
@ -139,7 +141,7 @@ class ZendeskAdmin:
|
|||||||
raise ValueError('invalid access_controller`s login data')
|
raise ValueError('invalid access_controller`s login data')
|
||||||
|
|
||||||
|
|
||||||
def update_role(user_profile: UserProfile, role: str) -> UserProfile:
|
def update_role(user_profile: UserProfile, role: int) -> UserProfile:
|
||||||
"""
|
"""
|
||||||
Функция меняет роль пользователя.
|
Функция меняет роль пользователя.
|
||||||
|
|
||||||
@ -162,12 +164,6 @@ def make_engineer(user_profile: UserProfile, who_changes: User) -> UserProfile:
|
|||||||
:param user_profile: Профиль пользователя
|
:param user_profile: Профиль пользователя
|
||||||
:return: Вызов функции **update_role** с параметрами: профиль пользователя, роль "engineer"
|
:return: Вызов функции **update_role** с параметрами: профиль пользователя, роль "engineer"
|
||||||
"""
|
"""
|
||||||
RoleChangeLogs.objects.create(
|
|
||||||
user=user_profile.user,
|
|
||||||
old_role=user_profile.custom_role_id,
|
|
||||||
new_role=ROLES['engineer'],
|
|
||||||
changed_by=who_changes
|
|
||||||
)
|
|
||||||
update_role(user_profile, ROLES['engineer'])
|
update_role(user_profile, ROLES['engineer'])
|
||||||
|
|
||||||
|
|
||||||
@ -191,13 +187,6 @@ def make_light_agent(user_profile: UserProfile, who_changes: User) -> UserProfil
|
|||||||
ticket.assignee = None
|
ticket.assignee = None
|
||||||
ticket.group = ZendeskAdmin().get_group(ZENDESK_GROUPS['buffer'])
|
ticket.group = ZendeskAdmin().get_group(ZENDESK_GROUPS['buffer'])
|
||||||
ZendeskAdmin().admin.tickets.update(ticket)
|
ZendeskAdmin().admin.tickets.update(ticket)
|
||||||
|
|
||||||
RoleChangeLogs.objects.create(
|
|
||||||
user=user_profile.user,
|
|
||||||
old_role=user_profile.custom_role_id,
|
|
||||||
new_role=ROLES['light_agent'],
|
|
||||||
changed_by=who_changes
|
|
||||||
)
|
|
||||||
update_role(user_profile, ROLES['light_agent'])
|
update_role(user_profile, ROLES['light_agent'])
|
||||||
|
|
||||||
|
|
||||||
@ -274,7 +263,7 @@ def check_user_auth(email: str, password: str) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def update_user_in_model(profile: UserProfile, zendesk_user: User) -> UserProfile:
|
def update_user_in_model(profile: UserProfile, zendesk_user: User):
|
||||||
"""
|
"""
|
||||||
Функция обновляет профиль пользователя при изменении данных пользователя на Zendesk.
|
Функция обновляет профиль пользователя при изменении данных пользователя на Zendesk.
|
||||||
|
|
||||||
@ -607,3 +596,72 @@ class StatisticData:
|
|||||||
"""
|
"""
|
||||||
self.statistic.clear()
|
self.statistic.clear()
|
||||||
self.fill_daterange(self.start_date, self.end_date + timedelta(days=1), 0)
|
self.fill_daterange(self.start_date, self.end_date + timedelta(days=1), 0)
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseHandler(logging.Handler):
|
||||||
|
def __init__(self):
|
||||||
|
logging.Handler.__init__(self)
|
||||||
|
|
||||||
|
def emit(self, record):
|
||||||
|
database = RoleChangeLogs()
|
||||||
|
users = record.msg
|
||||||
|
if users[1]:
|
||||||
|
user = users[0]
|
||||||
|
admin = users[1]
|
||||||
|
elif not users[1]:
|
||||||
|
user = users[0]
|
||||||
|
admin = users[0]
|
||||||
|
database.name = user.name
|
||||||
|
database.user = user.user
|
||||||
|
database.changed_by = admin.user
|
||||||
|
if user.custom_role_id == ROLES['engineer']:
|
||||||
|
database.old_role = ROLES['light_agent']
|
||||||
|
elif user.custom_role_id == ROLES['light_agent']:
|
||||||
|
database.old_role = ROLES['engineer']
|
||||||
|
database.new_role = user.custom_role_id
|
||||||
|
database.save()
|
||||||
|
|
||||||
|
|
||||||
|
class CsvFormatter(logging.Formatter):
|
||||||
|
def __init__(self):
|
||||||
|
logging.Formatter.__init__(self)
|
||||||
|
|
||||||
|
def format(self, record):
|
||||||
|
users = record.msg
|
||||||
|
if users[1]:
|
||||||
|
user = users[0]
|
||||||
|
admin = users[1]
|
||||||
|
elif not users[1]:
|
||||||
|
user = users[0]
|
||||||
|
admin = users[0]
|
||||||
|
msg = ''
|
||||||
|
msg += user.name
|
||||||
|
if user.custom_role_id == ROLES['engineer']:
|
||||||
|
msg += ',engineer,'
|
||||||
|
elif user.custom_role_id == ROLES['light_agent']:
|
||||||
|
msg += ',light_agent,'
|
||||||
|
time = str(timezone.now().today())
|
||||||
|
msg += time[:16]
|
||||||
|
msg += ','
|
||||||
|
msg += admin.name
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
def log(user, admin=0):
|
||||||
|
"""
|
||||||
|
Осуществляет запись логов в базу данных и csv файл
|
||||||
|
:param admin:
|
||||||
|
:param user:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
users = [user, admin]
|
||||||
|
logger = logging.getLogger('MY_LOGGER')
|
||||||
|
if not logger.hasHandlers():
|
||||||
|
dbhandler = DatabaseHandler()
|
||||||
|
csvformatter = CsvFormatter()
|
||||||
|
csvhandler = logging.FileHandler('logs/logs.csv', "a")
|
||||||
|
csvhandler.setFormatter(csvformatter)
|
||||||
|
logger.addHandler(dbhandler)
|
||||||
|
logger.addHandler(csvhandler)
|
||||||
|
logger.setLevel('INFO')
|
||||||
|
logger.info(users)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from main.models import UserProfile
|
from main.models import UserProfile
|
||||||
|
from access_controller.settings import ZENDESK_ROLES
|
||||||
|
|
||||||
|
|
||||||
class UserSerializer(serializers.HyperlinkedModelSerializer):
|
class UserSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
@ -13,9 +14,25 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class ProfileSerializer(serializers.HyperlinkedModelSerializer):
|
class ProfileSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
"""Сериализатор для модели профиля пользователя"""
|
"""Класс serializer для модели профиля пользователя"""
|
||||||
user = UserSerializer()
|
user = UserSerializer()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UserProfile
|
model = UserProfile
|
||||||
fields = ['user', 'id', 'name', 'zendesk_role']
|
fields = ['user', 'id', 'name', 'zendesk_role']
|
||||||
|
|
||||||
|
|
||||||
|
class ZendeskUserSerializer(serializers.Serializer):
|
||||||
|
"""Класс serializer для объектов пользователей из zenpy"""
|
||||||
|
name = serializers.CharField()
|
||||||
|
zendesk_role = serializers.SerializerMethodField('get_zendesk_role')
|
||||||
|
email = serializers.EmailField()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_zendesk_role(obj):
|
||||||
|
if obj.custom_role_id == ZENDESK_ROLES['engineer']:
|
||||||
|
return 'engineer'
|
||||||
|
elif obj.custom_role_id == ZENDESK_ROLES['light_agent']:
|
||||||
|
return 'light_agent'
|
||||||
|
else:
|
||||||
|
return "empty"
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
<h6 class="table-title">Список сотрудников</h6>
|
<h6 class="table-title">Список сотрудников</h6>
|
||||||
|
|
||||||
{% block table %}
|
{% block table %}
|
||||||
<table class="light-table">
|
<table class="table table-dark light-table">
|
||||||
|
|
||||||
<thead>
|
<thead>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
@ -42,8 +42,8 @@
|
|||||||
<th>Role</th>
|
<th>Role</th>
|
||||||
<th>Checked</th>
|
<th>Checked</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="tbody">
|
<tbody id="tbody"></tbody>
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
<p id="loading">Данные загружаются...</p>
|
<p id="loading">Данные загружаются...</p>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -3,10 +3,10 @@ import os
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.forms import PasswordResetForm
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
||||||
from django.contrib.auth.models import User, Permission
|
from django.contrib.auth.models import User, Permission
|
||||||
from django.contrib.auth.tokens import default_token_generator
|
from django.contrib.auth.tokens import default_token_generator
|
||||||
|
from django.contrib.auth.forms import PasswordResetForm
|
||||||
from django.contrib.auth.views import LoginView
|
from django.contrib.auth.views import LoginView
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
@ -29,9 +29,9 @@ from access_controller.settings import EMAIL_HOST_USER, ZENDESK_ROLES, ZENDESK_M
|
|||||||
from main.extra_func import ZendeskAdmin
|
from main.extra_func import ZendeskAdmin
|
||||||
from main.extra_func import check_user_exist, update_profile, get_user_organization, \
|
from main.extra_func import check_user_exist, update_profile, get_user_organization, \
|
||||||
make_engineer, make_light_agent, get_users_list, update_users_in_model, count_users, \
|
make_engineer, make_light_agent, get_users_list, update_users_in_model, count_users, \
|
||||||
StatisticData
|
StatisticData, log
|
||||||
from main.forms import AdminPageUsers, CustomRegistrationForm, CustomAuthenticationForm, StatisticForm
|
from main.forms import AdminPageUsers, CustomRegistrationForm, CustomAuthenticationForm, StatisticForm
|
||||||
from main.serializers import ProfileSerializer
|
from main.serializers import ProfileSerializer, ZendeskUserSerializer
|
||||||
from .models import UserProfile
|
from .models import UserProfile
|
||||||
|
|
||||||
|
|
||||||
@ -194,6 +194,7 @@ def user_update(zenpy_user: User, admin: User, request: WSGIRequest) -> UserProf
|
|||||||
|
|
||||||
admin.users.update(zenpy_user)
|
admin.users.update(zenpy_user)
|
||||||
request.user.userprofile.role = "agent"
|
request.user.userprofile.role = "agent"
|
||||||
|
request.user.userprofile.custom_role_id = zenpy_user.custom_role_id
|
||||||
request.user.userprofile.save()
|
request.user.userprofile.save()
|
||||||
messages.success(request, "Права были изменены")
|
messages.success(request, "Права были изменены")
|
||||||
|
|
||||||
@ -207,9 +208,7 @@ def work_hand_over(request: WSGIRequest) -> HttpResponseRedirect:
|
|||||||
:param request: данные текущего пользователя (login_required)
|
:param request: данные текущего пользователя (login_required)
|
||||||
:return: перезагрузка текущей страницы после выполнения смены роли
|
:return: перезагрузка текущей страницы после выполнения смены роли
|
||||||
"""
|
"""
|
||||||
|
|
||||||
make_light_agent(request.user.userprofile,request.user)
|
make_light_agent(request.user.userprofile,request.user)
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse('work', args=(request.user.id,)))
|
return HttpResponseRedirect(reverse('work', args=(request.user.id,)))
|
||||||
|
|
||||||
|
|
||||||
@ -222,16 +221,19 @@ def work_become_engineer(request: WSGIRequest) -> HttpResponseRedirect:
|
|||||||
:return: перезагрузка текущей страницы после выполнения смены роли
|
:return: перезагрузка текущей страницы после выполнения смены роли
|
||||||
"""
|
"""
|
||||||
zenpy_user, admin = auth_user(request)
|
zenpy_user, admin = auth_user(request)
|
||||||
make_engineer(request.user.userprofile,request.user)
|
|
||||||
|
|
||||||
|
make_engineer(request.user.userprofile,request.user)
|
||||||
return HttpResponseRedirect(reverse('work', args=(request.user.id,)))
|
return HttpResponseRedirect(reverse('work', args=(request.user.id,)))
|
||||||
|
|
||||||
|
|
||||||
def main_page(request):
|
def main_page(request: WSGIRequest) -> HttpResponse:
|
||||||
|
"""
|
||||||
|
Функция переадресации на главную страницу.
|
||||||
|
"""
|
||||||
return render(request, 'pages/index.html')
|
return render(request, 'pages/index.html')
|
||||||
|
|
||||||
|
|
||||||
class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin,SuccessMessageMixin, FormView):
|
class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, FormView):
|
||||||
"""
|
"""
|
||||||
Класс отображения страницы администратора.
|
Класс отображения страницы администратора.
|
||||||
|
|
||||||
@ -273,10 +275,18 @@ class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin,SuccessMessageMi
|
|||||||
"""
|
"""
|
||||||
for user in users:
|
for user in users:
|
||||||
make_engineer(user, self.request.user)
|
make_engineer(user, self.request.user)
|
||||||
|
log(user, self.request.user.userprofile)
|
||||||
|
|
||||||
def make_light_agents(self, users):
|
def make_light_agents(self, users):
|
||||||
|
"""
|
||||||
|
Функция проходит по списку пользователей, проставляя статус "light agent".
|
||||||
|
|
||||||
|
:param users: Список пользователей
|
||||||
|
:return: Обновленный список пользователей
|
||||||
|
"""
|
||||||
for user in users:
|
for user in users:
|
||||||
make_light_agent(user, self.request.user)
|
make_light_agent(user, self.request.user)
|
||||||
|
log(user, self.request.user.userprofile)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs) -> dict:
|
def get_context_data(self, **kwargs) -> dict:
|
||||||
"""
|
"""
|
||||||
@ -303,16 +313,34 @@ class UsersViewSet(viewsets.ReadOnlyModelViewSet):
|
|||||||
serializer_class = ProfileSerializer
|
serializer_class = ProfileSerializer
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
users = update_users_in_model().values
|
users = update_users_in_model()
|
||||||
count = count_users(users)
|
count = count_users(users.values)
|
||||||
profiles = UserProfile.objects.filter(role='agent')
|
profiles = UserProfile.objects.filter(role='agent')
|
||||||
serializer = self.get_serializer(profiles, many=True)
|
serializer = self.get_serializer(profiles, many=True)
|
||||||
return Response({
|
res = {
|
||||||
'users': serializer.data,
|
'users': serializer.data,
|
||||||
'engineers': count[0],
|
'engineers': count[0],
|
||||||
'light_agents': count[1]
|
'light_agents': count[1],
|
||||||
})
|
"zendesk_users": self.get_zendesk_users(self.choose_users(users.values, profiles))
|
||||||
|
}
|
||||||
|
return Response(res)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def choose_users(zendesk, model):
|
||||||
|
users = []
|
||||||
|
for zendesk_user in zendesk:
|
||||||
|
if zendesk_user.name not in [user.name for user in model]:
|
||||||
|
users.append(zendesk_user)
|
||||||
|
return users
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_zendesk_users(users):
|
||||||
|
zendesk_users = ZendeskUserSerializer(
|
||||||
|
data=[user for user in users if user.role != 'admin'],
|
||||||
|
many=True
|
||||||
|
)
|
||||||
|
zendesk_users.is_valid()
|
||||||
|
return zendesk_users.data
|
||||||
|
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
|
@ -6,7 +6,8 @@ import sys
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Run administrative tasks."""
|
"""Run administrative tasks."""
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'access_controller.settings')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE',
|
||||||
|
'access_controller.settings')
|
||||||
try:
|
try:
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// React
|
// React
|
||||||
class TableRow extends React.Component {
|
class ModelUserTableRow extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<tr>
|
<tr className={"table-dark"}>
|
||||||
<td>
|
<td>
|
||||||
<a href="#">{this.props.user.name}</a>
|
<a href="#">{this.props.user.name}</a>
|
||||||
</td>
|
</td>
|
||||||
@ -23,6 +23,43 @@ class TableRow extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ModelUserTableRows extends React.Component {
|
||||||
|
render() {
|
||||||
|
return ReactDOM.createPortal(
|
||||||
|
this.props.users.map((user, key) => (
|
||||||
|
<ModelUserTableRow user={user} key={key} />
|
||||||
|
)),
|
||||||
|
document.getElementById("tbody")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ZendeskUserTableRow extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<tr className={"table-secondary"}>
|
||||||
|
<td>
|
||||||
|
<a href="#">{this.props.user.name}</a>
|
||||||
|
</td>
|
||||||
|
<td>{this.props.user.email}</td>
|
||||||
|
<td>{this.props.user.zendesk_role}</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ZendeskUserTableRows extends React.Component {
|
||||||
|
render() {
|
||||||
|
return ReactDOM.createPortal(
|
||||||
|
this.props.users.map((user, key) => (
|
||||||
|
<ZendeskUserTableRow user={user} key={key} />
|
||||||
|
)),
|
||||||
|
document.getElementById("tbody")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TableBody extends React.Component {
|
class TableBody extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -30,6 +67,7 @@ class TableBody extends React.Component {
|
|||||||
users: [],
|
users: [],
|
||||||
engineers: 0,
|
engineers: 0,
|
||||||
light_agents: 0,
|
light_agents: 0,
|
||||||
|
zendesk_users: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +77,7 @@ class TableBody extends React.Component {
|
|||||||
users: response.data.users,
|
users: response.data.users,
|
||||||
engineers: response.data.engineers,
|
engineers: response.data.engineers,
|
||||||
light_agents: response.data.light_agents,
|
light_agents: response.data.light_agents,
|
||||||
|
zendesk_users: response.data.zendesk_users,
|
||||||
});
|
});
|
||||||
let elements = document.querySelectorAll(".info-quantity-value");
|
let elements = document.querySelectorAll(".info-quantity-value");
|
||||||
elements[0].innerHTML = this.state.engineers;
|
elements[0].innerHTML = this.state.engineers;
|
||||||
@ -62,9 +101,12 @@ class TableBody extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return this.state.users.map((user, key) => (
|
return (
|
||||||
<TableRow user={user} key={key} />
|
<tr>
|
||||||
));
|
<ModelUserTableRows users={this.state.users} />
|
||||||
|
<ZendeskUserTableRows users={this.state.zendesk_users} />
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|