fix: search existing tickets by subject without status filter, check status in code, get details for CN matching

This commit is contained in:
Денис Кривоченко
2026-07-29 01:28:10 +07:00
parent 6ad50dcd4d
commit c42854c3a5
+41 -22
View File
@@ -212,39 +212,58 @@ async def _send_sd_api_request(
async def _find_existing_trueconf_ticket(cn: str, requester_email: str = None) -> str | None: async def _find_existing_trueconf_ticket(cn: str, requester_email: str = None) -> str | None:
""" """
Найти существующую открытую заявку с темой 'Запрос доступа к Trueconf' для пользователя. Найти существующую открытую заявку с темой 'Запрос доступа к Trueconf' для пользователя.
Ищет по ФИО (name), затем по email, затем по системному имени с пометкой пользователя. Ищет по ФИО (name), затем по email, затем по CN в описании.
Статусы: Open (Открыто) и InProgress (В работе).
""" """
subject = "Запрос доступа к Trueconf" subject = "Запрос доступа к Trueconf"
try: try:
url = f"{SD_URL.rstrip('/')}/api/v3/requests?filter=status:Open&fields=id,subject,requester,description" # Забираем все заявки с темой (без фильтра по статусу — проверяем в коде)
url = f"{SD_URL.rstrip('/')}/api/v3/requests?filter=subject:{subject}&fields=id,subject,requester,status"
headers = {"TECHNICIAN_KEY": SD_TOKEN} headers = {"TECHNICIAN_KEY": SD_TOKEN}
async with httpx.AsyncClient(verify=False) as client: async with httpx.AsyncClient(verify=False) as client:
resp = await client.get(url, headers=headers, timeout=10.0) resp = await client.get(url, headers=headers, timeout=10.0)
if resp.status_code == 200: if resp.status_code == 200:
data = resp.json() data = resp.json()
requests_list = data.get("requests", []) requests_list = data.get("requests", [])
logger.info(f"Found {len(requests_list)} tickets with subject='{subject}', searching for CN={cn}")
for req in requests_list: for req in requests_list:
if subject not in req.get("subject", ""): req_status = req.get("status", {})
status_name = req_status.get("name", "") if isinstance(req_status, dict) else str(req_status)
req_id = req.get("id")
req_name = req_status.get("requester", {}).get("name", "") if isinstance(req_status.get("requester"), dict) else ""
logger.info(f"Ticket {req_id}: status={status_name}")
# Пропускаем закрытые заявки
if status_name in ("Resolved", "Rejected", "Closed", "Solved"):
continue continue
requester = req.get("requester", {})
# 1. Поиск по ФИО # Получаем детали заявки для поиска по описанию
req_name = requester.get("name", "") or requester.get("display_name", "") detail_url = f"{SD_URL.rstrip('/')}/api/v3/requests/{req_id}"
if cn and cn in req_name: detail_resp = await client.get(detail_url, headers=headers, timeout=10.0)
ticket_id = req.get("id") if detail_resp.status_code == 200:
logger.info(f"Found existing Trueconf ticket #{ticket_id} for CN={cn} (by name)") detail = detail_resp.json()
return str(ticket_id) requester = detail.get("requester", {})
# 2. Поиск по email req_name = requester.get("name", "") or requester.get("display_name", "")
req_email = requester.get("email", "") or requester.get("email_id", "") req_email = requester.get("email", "") or requester.get("email_id", "")
if req_email == requester_email and requester_email and requester_email not in (DEFAULT_REQUESTER, "ai@sibcem.ru"): req_desc = (detail.get("description", "") or "")[:500]
ticket_id = req.get("id") logger.info(f"Detail ticket {req_id}: name='{req_name}', email='{req_email}', desc_preview='{req_desc[:100]}'")
logger.info(f"Found existing Trueconf ticket #{ticket_id} for {requester_email} (by email)")
return str(ticket_id) # 1. Поиск по ФИО в имени заявителя
# 3. Поиск по системному заявщику с пометкой пользователя в описании if cn and cn in req_name:
req_desc = req.get("description", "") or "" logger.info(f"Match ticket {req_id} for CN={cn} (by name: {req_name})")
if f"[Пользователь: {cn}]" in req_desc: return str(req_id)
ticket_id = req.get("id") # 2. Поиск по email
logger.info(f"Found existing Trueconf ticket #{ticket_id} for CN={cn} (by description note)") if req_email == requester_email and requester_email and requester_email not in (DEFAULT_REQUESTER, "ai@sibcem.ru"):
return str(ticket_id) logger.info(f"Match ticket {req_id} for {requester_email} (by email)")
return str(req_id)
# 3. Поиск по системному заявщику с пометкой пользователя в описании
if f"[Пользователь: {cn}]" in req_desc:
logger.info(f"Match ticket {req_id} for CN={cn} (by description note)")
return str(req_id)
# 4. Поиск по CN в описании заявки
if cn in req_desc:
logger.info(f"Match ticket {req_id} for CN={cn} (CN in description)")
return str(req_id)
except Exception as e: except Exception as e:
logger.warning(f"Failed to search existing tickets: {e}") logger.warning(f"Failed to search existing tickets: {e}")
return None return None