From a430ee871d20439a1a885e526285d65fdc16a706 Mon Sep 17 00:00:00 2001 From: Sokurov Idar Date: Sun, 14 Mar 2021 17:13:41 +0300 Subject: [PATCH] Add ticket unassignment(exclude solved tickets) --- access_controller/settings.py | 6 ++ main/extra_func.py | 73 ++++++++++--------- ...312_1225.py => 0014_auto_20210314_1455.py} | 10 ++- main/views.py | 20 ++--- 4 files changed, 59 insertions(+), 50 deletions(-) rename main/migrations/{0012_auto_20210312_1225.py => 0014_auto_20210314_1455.py} (61%) diff --git a/access_controller/settings.py b/access_controller/settings.py index deadf32..953d2f6 100644 --- a/access_controller/settings.py +++ b/access_controller/settings.py @@ -183,4 +183,10 @@ ZENDESK_ROLES = { 'light_agent': 360005208980, } +ZENDESK_GROUPS = { + 'employees': 'Поддержка', + 'buffer': 'Сменная группа', +} + ONE_DAY = 12 # Количество часов в 1 рабочем дне + diff --git a/main/extra_func.py b/main/extra_func.py index 3583867..c7946fc 100644 --- a/main/extra_func.py +++ b/main/extra_func.py @@ -5,7 +5,7 @@ from django.contrib.auth.models import User from zenpy import Zenpy from zenpy.lib.exception import APIException -from access_controller.settings import ZENDESK_ROLES as ROLES, ONE_DAY +from access_controller.settings import ZENDESK_ROLES as ROLES, ONE_DAY, ZENDESK_GROUPS from main.models import UserProfile, RoleChangeLogs, UnassignedTicket, UnassignedTicketStatus @@ -29,12 +29,6 @@ class ZendeskAdmin: email: str = os.getenv('ACCESS_CONTROLLER_API_EMAIL') token: str = os.getenv('ACCESS_CONTROLLER_API_TOKEN') password: str = os.getenv('ACCESS_CONTROLLER_API_PASSWORD') - _instance = None - - def __new__(cls, *args, **kwargs): - if cls._instance is None: - cls._instance = super().__new__(cls) - return cls._instance def __init__(self): self.create_admin() @@ -82,6 +76,12 @@ class ZendeskAdmin: """ return self.admin.users.search(email).values[0] + def get_group(self, name): + groups = self.admin.search(name) + for group in groups: + return group + return None + def get_user_org(self, email: str) -> str: """ Функция **get_user_org** возвращает организацию, к которой относится пользователь по его email @@ -126,43 +126,42 @@ def update_role(user_profile: UserProfile, role: str) -> UserProfile: zendesk.admin.users.update(user) -def make_engineer(user_profile: UserProfile) -> UserProfile: +def make_engineer(user_profile: UserProfile, who_changes: User) -> UserProfile: """ Функция **make_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']) def make_light_agent(user_profile: UserProfile, who_changes: User) -> UserProfile: """ Функция **make_light_agent** устанавливапет пользователю роль легкого агента. - - .. todo:: - Решить проблему с ошибкой при выполнении этой функции из-за неотвязанных тикетов. А именно: - - - найти все тикеты, ответственным которых является снимаемый аккаунт - - для всех этих тикетов - перенести ответственность на буферную группу. - - [PARTIALY DONE] создать записи о снятых тикетах и их прошлом авторстве. Если тикет уже был закрыт - выставить в логе CLOSED. Иначе UNASSIGNED - - [DONE] после этого снять права c инженера - - [DONE] создать запись в логе о снятии прав инженера """ + tickets = get_ticket_list(user_profile.user.email) + for ticket in tickets: + if ticket.status=='solved': + continue + UnassignedTicket.objects.create( + assignee=user_profile.user, + ticket_id=ticket.id, + status=UnassignedTicketStatus.UNASSIGNED + ) + ticket.group = ZendeskAdmin().get_group(ZENDESK_GROUPS['buffer']) + ZendeskAdmin().admin.tickets.update(ticket) - # tickets = [] - # # TODO: set ticket fields correct - # for ticket in tickets: - # UnassignedTicket.create( - # assignee=user_profile.user, - # ticket_id=ticket.number, - # status=UnassignedTicketStatus.UNASSIGNED if ticket.status=='opened' else UnassignedTicketStatus.CLOSED - # ) - update_role(user_profile, ROLES['light_agent']) - RoleChangeLogs.create( + RoleChangeLogs.objects.create( user=user_profile.user, - old_role=ROLES['engineer'], + old_role=user_profile.custom_role_id, new_role=ROLES['light_agent'], changed_by=who_changes ) + update_role(user_profile, ROLES['light_agent']) def get_users_list() -> list: @@ -175,9 +174,13 @@ def get_users_list() -> list: return zendesk.admin.organizations.users(org) +def get_ticket_list(email): + return ZendeskAdmin().admin.search(assignee=email, type='ticket') + + def update_profile(user_profile: UserProfile) -> UserProfile: """ - Функция обновляет профиль пользователя в соотвтетствии с текущим в Zendesk + Функция обновляет профиль пользователя в соотвтетствии с текущим в Zendesk """ user = ZendeskAdmin().get_user(user_profile.user.email) user_profile.name = user.name @@ -189,7 +192,7 @@ def update_profile(user_profile: UserProfile) -> UserProfile: def check_user_exist(email: str) -> bool: """ - Функция проверяет, существует ли пользователь + Функция проверяет, существует ли пользователь """ return ZendeskAdmin().check_user(email) @@ -241,9 +244,9 @@ class StatisticData: self.warnings = list() self.data = dict() self.statistic = dict() - self._set_data() + self._init_data() if stat is None: - self._set_statistic() + self._init_statistic() else: self.statistic = stat @@ -346,7 +349,7 @@ class StatisticData: return False return True - def _set_data(self): + def _init_data(self): """ Получение логов в диапазоне дат start_date-end_date для пользователя с почтой email """ @@ -361,7 +364,7 @@ class StatisticData: except User.DoesNotExist: self.errors += ['Пользователь не найден'] - def _set_statistic(self): + def _init_statistic(self): """ Функция заполняет словарь, в котором ключ - дата, значение - кол-во проработанных в этот день секунд """ diff --git a/main/migrations/0012_auto_20210312_1225.py b/main/migrations/0014_auto_20210314_1455.py similarity index 61% rename from main/migrations/0012_auto_20210312_1225.py rename to main/migrations/0014_auto_20210314_1455.py index 6d33580..77db2ec 100644 --- a/main/migrations/0012_auto_20210312_1225.py +++ b/main/migrations/0014_auto_20210314_1455.py @@ -1,12 +1,13 @@ -# Generated by Django 3.1.6 on 2021-03-12 09:25 +# Generated by Django 3.1.6 on 2021-03-14 11:55 from django.db import migrations, models +import django.utils.timezone class Migration(migrations.Migration): dependencies = [ - ('main', '0011_auto_20210311_1734'), + ('main', '0013_auto_20210311_2040'), ] operations = [ @@ -15,6 +16,11 @@ class Migration(migrations.Migration): name='custom_role_id', field=models.IntegerField(default=0, help_text='Код роли пользователя'), ), + migrations.AlterField( + model_name='rolechangelogs', + name='change_time', + field=models.DateTimeField(default=django.utils.timezone.now, help_text='Дата и время изменения роли'), + ), migrations.AlterField( model_name='userprofile', name='role', diff --git a/main/views.py b/main/views.py index 4c596ad..221e693 100644 --- a/main/views.py +++ b/main/views.py @@ -1,6 +1,5 @@ import logging import os -from datetime import datetime from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import PasswordResetForm @@ -19,11 +18,12 @@ from django_registration.views import RegistrationView from zenpy import Zenpy from zenpy.lib.api_objects import User as ZenpyUser -from access_controller.settings import EMAIL_HOST_USER, ZENDESK_ROLES +from access_controller.settings import EMAIL_HOST_USER, ZENDESK_ROLES, ZENDESK_GROUPS from main.extra_func import check_user_exist, update_profile, get_user_organization, make_engineer, make_light_agent, \ - get_users_list, StatisticData + get_users_list, StatisticData, get_ticket_list, ZendeskAdmin from main.forms import AdminPageUsers, CustomRegistrationForm, CustomAuthenticationForm, StatisticForm -from .models import UserProfile +from .models import UserProfile, UnassignedTicket, UnassignedTicketStatus + class CustomRegistrationView(RegistrationView): """ @@ -106,12 +106,7 @@ def profile_page(request: WSGIRequest) -> HttpResponse: def auth_user(request): - admin_creds = { - 'email': os.environ.get('ACCESS_CONTROLLER_API_EMAIL'), - 'subdomain': 'ngenix1612197338', - 'token': os.environ.get('ACCESS_CONTROLLER_API_TOKEN'), - } - admin = Zenpy(**admin_creds) + admin = ZendeskAdmin().admin zenpy_user: ZenpyUser = admin.users.search(request.user.email).values[0] return zenpy_user, admin @@ -163,7 +158,7 @@ def work_become_engineer(request): def main_page(request): """ - Отображение логгирования на главной странице + Отображение логгирования на главной странице """ logger = logging.getLogger('main.index') logger.info('Index page opened') @@ -178,7 +173,7 @@ class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, FormView): def form_valid(self, form: AdminPageUsers) -> AdminPageUsers: """ - Функция установки ролей пользователям + Функция установки ролей пользователям """ if 'engineer' in self.request.POST: self.make_engineers(form.cleaned_data['users']) @@ -194,7 +189,6 @@ class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, FormView): for user in users: make_light_agent(user, self.request.user) - @staticmethod def count_users(users) -> tuple: """