From 1949a461b2e456c469497fc4810433936c5921af Mon Sep 17 00:00:00 2001 From: Denis Krivchenko Date: Sat, 4 Jul 2026 17:55:35 +0700 Subject: [PATCH] feat: add department exclusion for auto-approval - Add department attribute to LDAP search - Add APPROVAL_EXCLUDED_DEPARTMENTS config - Skip auto-approval if user department is excluded --- config/config.py | 8 ++++++++ sd_dispatcher.py | 18 ++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/config/config.py b/config/config.py index ca8bec4..1355dac 100644 --- a/config/config.py +++ b/config/config.py @@ -287,6 +287,14 @@ APPROVAL_CATEGORIES = { "1с": ["*"] } +# Отделы, исключающие пользователя из автосогласования +# Если department пользователя совпадает с любым из этих значений — +# автосогласование НЕ запускается, даже если все остальные условия выполнены. +APPROVAL_EXCLUDED_DEPARTMENTS = [ + # "IT-Администраторы", + # "Системные аналитики", +] + # План «Б» маршрутизации: жесткое определение локации по телефонному префиксу внутренней АТС PREFIX_ROUTING = { "700": {"city": "Красноярск", "company": "ООО Комбинат Волна"}, diff --git a/sd_dispatcher.py b/sd_dispatcher.py index acaefff..be1c6bd 100644 --- a/sd_dispatcher.py +++ b/sd_dispatcher.py @@ -170,7 +170,7 @@ def find_user_in_ad(requester, caller_phone=None, ticket_id=None): try: server = Server(AD_SERVER, get_info=ALL, connect_timeout=AD_CONNECT_TIMEOUT) conn = Connection(server, user=AD_USER, password=AD_PASSWORD, auto_bind=True, receive_timeout=AD_RECEIVE_TIMEOUT) - conn.search(search_base=AD_BASE, search_filter=ldap_filter, attributes=["l", "company", "manager"]) + conn.search(search_base=AD_BASE, search_filter=ldap_filter, attributes=["l", "company", "manager", "department"]) if not conn.entries: log_to_file(f" [AD] ❌ Объект ({search_by}) не найден in AD!", ticket_id) @@ -195,7 +195,8 @@ def find_user_in_ad(requester, caller_phone=None, ticket_id=None): if conn.entries and 'mail' in conn.entries[0]: manager_email = conn.entries[0].mail.value - return {"city": city, "company": company, "ad_path": ad_path, "manager_email": manager_email, "source": f"AD ({search_by})"} + department = user.department.value if "department" in user and user.department.value else None + return {"city": city, "company": company, "department": department, "ad_path": ad_path, "manager_email": manager_email, "source": f"AD ({search_by})"} except Exception as e: log_to_file(f"❌ Ошибка LDAP или таймаут сети AD: {e}", ticket_id) return None @@ -764,6 +765,7 @@ def process_ticket_logic(req_id): ad_path = user_info["ad_path"] if user_info else None manager_email = user_info["manager_email"] if user_info else None info_source = user_info["source"] if user_info else "Не определен" + user_department = user_info["department"] if user_info else None prefix_used = False if caller_phone and not user_info: @@ -892,6 +894,18 @@ def process_ticket_logic(req_id): if "*" in allowed_subcats or subcat_name in allowed_subcats: is_cat_ok = True + # Проверка: отдел пользователя в списке исключений + is_excluded = False + if user_department and APPROVAL_EXCLUDED_DEPARTMENTS: + for dept in APPROVAL_EXCLUDED_DEPARTMENTS: + if dept.lower() in user_department.lower() or user_department.lower() in dept.lower(): + is_excluded = True + t_log(f" ⚠️ Отдел '{user_department}' в списке исключений — автосогласование отменено") + break + if is_excluded: + t_log(" ⏭ Пропуск: пользователь в исключённом отделе.") + continue + if is_city_ok and (is_group_ok or is_cat_ok): if manager_email: t_log(f"✔ Условия совпали. Запуск процесса согласования для {manager_email}...")