#!/usr/bin/env python3 """Диагностика данных сотрудника для модуля ЛК (расчетnye listki).""" import os import sys BASE_DIR = "/opt/trueconf_bot" os.chdir(BASE_DIR) # Загрузка .env def load_env(filepath): with open(filepath, "r", encoding="utf-8") as f: for line in f: line = line.strip() if line and not line.startswith("#") and "=" in line: key, value = line.split("=", 1) value = value.strip(' "') value = value.strip("'") value = value.strip() os.environ[key.strip()] = value load_env(os.path.join(BASE_DIR, "config", ".env")) # Загрузка passwork for pw_path in ["/opt/passwork", os.path.join(BASE_DIR, "passwork")]: if os.path.isdir(pw_path) and pw_path not in sys.path: sys.path.insert(0, pw_path) from passwork import get_passwork_secrets card_name = os.getenv("PW_ID_SQL", "").strip() passwork_pool = get_passwork_secrets(required_cards=[card_name]) card_data = passwork_pool[card_name] DB_USER = card_data["login"] DB_PASSWORD = card_data["password"] SQL_SERVER = os.getenv("SQL_SERVER", "SRVKEM-MOBILEIN.sibcem.ru") SQL_DB_NAME = os.getenv("SQL_DB_NAME", "BossCopy") import pymssql import ldap3 # --- Подключение к AD --- print("=" * 60) print("Диагностика сотрудника: la.guseynova@sibcem.ru") print("=" * 60) email = "la.guseynova@sibcem.ru" search_id = email.replace("@tcs.sibcem.ru", "@sibcem.ru") short_name = search_id.split("@")[0] # la.guseynova — без домена print(f"\n--- 0. Поиск в AD ---") print(f" Email: {email}") print(f" Search ID: {search_id}") print(f" Short (без домена): {short_name}") AD_SERVER = "172.16.20.20" AD_BASE = "DC=sibcem,DC=ru" try: conn = ldap3.Connection( ldap3.Server(AD_SERVER, connect_timeout=5), auto_bind=True, read_only=True ) # Разделяем поиск: # - mail: полный email с доменом (la.guseynova@sibcem.ru) # - sAMAccountName: только логин без домена (la.guseynova) # - userPrincipalName: полный UPN с доменом # - anr: логин без домена (ANR ищет по sAMAccountName, displayName, etc.) search_filter = f"(|(mail={search_id}*)(sAMAccountName={short_name})(userPrincipalName={search_id}*)(anr={short_name}))" print(f" LDAP-фильтр: {search_filter}") print(f" mail: {search_id} (полный email)") print(f" sAMAccountName: {short_name} (без домена)") print(f" userPrincipalName: {search_id} (полный UPN)") print(f" anr: {short_name} (без домена)") conn.search( search_base=AD_BASE, search_filter=search_filter, attributes=["cn", "sAMAccountName", "mail", "userPrincipalName", "extensionAttribute2", "mobile", "personalPager"] ) if conn.entries: entry = conn.entries[0] cn = str(entry.cn) sam = str(entry.sAMAccountName) mail = str(entry.mail) if 'mail' in entry else "" upn = str(entry.userPrincipalName) if 'userPrincipalName' in entry else "" ext2 = str(entry.extensionAttribute2) if 'extensionAttribute2' in entry else "" mobile = str(entry.mobile) if 'mobile' in entry else "" pager = str(entry.personalPager) if 'personalPager' in entry else "" print(f"\n НАЙДЕН:") print(f" CN: {cn}") print(f" sAMAccountName: {sam}") print(f" mail: {mail}") print(f" UPN: {upn}") print(f" extensionAttribute2 (CARD_ID): {ext2}") print(f" mobile: {mobile}") print(f" pager: {pager}") else: print(" Не найден по расширенному фильтру. Пробую ANR отдельно...") conn.search( search_base=AD_BASE, search_filter=f"(anr={short_name})", attributes=["cn", "sAMAccountName", "mail", "userPrincipalName", "extensionAttribute2", "mobile", "personalPager"] ) if conn.entries: entry = conn.entries[0] cn = str(entry.cn) sam = str(entry.sAMAccountName) mail = str(entry.mail) if 'mail' in entry else "" upn = str(entry.userPrincipalName) if 'userPrincipalName' in entry else "" ext2 = str(entry.extensionAttribute2) if 'extensionAttribute2' in entry else "" mobile = str(entry.mobile) if 'mobile' in entry else "" pager = str(entry.personalPager) if 'personalPager' in entry else "" print(f"\n НАЙДЕН (ANR fallback):") print(f" CN: {cn}") print(f" sAMAccountName: {sam}") print(f" mail: {mail}") print(f" UPN: {upn}") print(f" extensionAttribute2 (CARD_ID): {ext2}") print(f" mobile: {mobile}") print(f" pager: {pager}") else: print(" НЕ НАЙДЕН в AD!") conn.unbind() sys.exit(0) conn.unbind() except Exception as e: print(f" Ошибка подключения к AD: {e}") sys.exit(0) # --- Подключение к SQL --- print(f"\n--- 1. Подключение к SQL ---") try: conn_sql = pymssql.connect( server=SQL_SERVER, user=DB_USER, password=DB_PASSWORD, database=SQL_DB_NAME, charset="cp1251", login_timeout=10 ) cursor = conn_sql.cursor() print(f" Подключено к {SQL_SERVER}/{SQL_DB_NAME}") except Exception as e: print(f" Ошибка подключения к SQL: {e}") sys.exit(0) # Определяем card_id: через поиск в БД card_id = None # Пробуем найти CARD_ID через PR_CARD + PR_EMP print(f"\n--- 2. Поиск CARD_ID в PR_CARD ---") cursor.execute( "SELECT c.ID FROM UOV_SELFSERVICE_PR_CARD c " "JOIN UOV_SELFSERVICE_PR_EMP e ON e.CARD_ID = c.ID " "WHERE e.EMAIL_ID LIKE %s OR e.USERNAME LIKE %s", (f"%{short_name}%", f"%{short_name}%") ) rows = cursor.fetchall() if rows: for r in rows: print(f" CARD_ID (по username): {r[0]}") card_id = rows[0][0] else: print(f" Не найден по username в PR_CARD/PR_EMP") if not card_id: cursor.execute( "SELECT c.ID FROM UOV_SELFSERVICE_PR_CARD c " "JOIN UOV_SELFSERVICE_PR_EMP e ON e.CARD_ID = c.ID " "WHERE e.EMAIL_ID LIKE %s", (f"%{search_id.split('@')[0]}%",) ) rows = cursor.fetchall() if rows: for r in rows: print(f" CARD_ID (по email): {r[0]}") card_id = rows[0][0] else: print(f" Не найден по email в PR_CARD/PR_EMP") if not card_id: print("\n CARD_ID не найден в БД!") conn_sql.close() sys.exit(0) print(f"\n Используем CARD_ID: {card_id}") # --- 3. PR_EMP --- print(f"\n--- 3. PR_EMP (профиль сотрудника) ---") cursor.execute( "SELECT ID, FIRM_ID, EMAIL_ID, USERNAME FROM UOV_SELFSERVICE_PR_EMP WHERE CARD_ID = %s", (card_id,) ) emp_rows = cursor.fetchall() if emp_rows: for r in emp_rows: print(f" EMP_ID: {r[0]}, FIRM_ID: {r[1]}, EMAIL: {r[2]}, USERNAME: {r[3]}") else: print(" ПУСТО - нет записей в PR_EMP") # --- 4. PR_TRANS --- print(f"\n--- 4. PR_TRANS (кадровые назначения) ---") if emp_rows: emp_ids = [r[0] for r in emp_rows] placeholders = ",".join(["%s"] * len(emp_ids)) cursor.execute( f"SELECT EMP_ID, D_FROM, D_TO, TP_ABBR, SYSPAY_ID " f"FROM UOV_SELFSERVICE_PR_TRANS " f"WHERE EMP_ID IN ({placeholders}) " f"ORDER BY D_FROM DESC", emp_ids ) trans_rows = cursor.fetchall() if trans_rows: print(f" Найдено записей: {len(trans_rows)}") for r in trans_rows[:10]: print(f" EMP_ID: {r[0]}, D_FROM: {r[1]}, D_TO: {r[2]}, TP: {r[3]}, SYSPAY: {r[4]}") else: print(" ПУСТО - нет записей в PR_TRANS") else: print(" Пропуск (нет PR_EMP)") # --- 5. SL_YTAX --- print(f"\n--- 5. SL_YTAX (периоды с данными) ---") cursor.execute( "SELECT DISTINCT TYEAR, TMONTH, CMONTH FROM UOV_SELFSERVICE_SL_YTAX " "WHERE CARD_ID = %s ORDER BY CMONTH DESC", (card_id,) ) tax_rows = cursor.fetchall() if tax_rows: print(f" Найдено периодов: {len(tax_rows)}") for r in tax_rows[:10]: print(f" {r[0]}-{r[1]:02d} (CMONTH={r[2]})") else: print(" ПУСТО - нет периодов в SL_YTAX") # --- 6. Проверка q_firm --- print(f"\n--- 6. Проверка q_firm для последнего периода ---") if tax_rows: latest_cmonth = tax_rows[0][2] tyear = (latest_cmonth - 1) // 12 tmonth = (latest_cmonth - 1) % 12 + 1 import calendar _, last_day = calendar.monthrange(tyear, tmonth) date_start = f"{tyear}-{tmonth:02d}-01" date_end = f"{tyear}-{tmonth:02d}-{last_day:02d}" date_params = (date_start, date_start, date_end, date_end, date_end) print(f" Период: {tyear}-{tmonth:02d}") q_firm = """ select e.FIRM_ID, f.SNAME from (select e.id, e.FIRM_ID from UOV_SELFSERVICE_PR_EMP e join UOV_SELFSERVICE_PR_CARD c on c.ID=e.CARD_ID where c.ID = %s group by e.ID, e.FIRM_ID ) as e join UOV_SELFSERVICE_PR_TRANS t on t.EMP_ID = e.ID join UOV_SELFSERVICE_HR_FIRM f on f.ID = e.FIRM_ID where ((t.D_FROM <= %s and t.D_TO >= %s) or (t.D_FROM <= %s and t.D_TO >= %s) or (t.D_FROM <= %s and t.D_TO = '1999-12-31')) group by e.FIRM_ID, f.SNAME """ cursor.execute(q_firm, (card_id, *date_params)) firm_row = cursor.fetchone() if firm_row: print(f" q_firm НАШЁЛ: FIRM_ID={firm_row[0]}, SNAME={firm_row[1]}") else: print(f" q_firm НЕ НАШЁЛ (NULL) - это вызовет ошибку!") q_firm_fb = """ select e.FIRM_ID from UOV_SELFSERVICE_PR_EMP e join UOV_SELFSERVICE_PR_CARD c on c.ID=e.CARD_ID where c.ID = %s group by e.ID, e.FIRM_ID """ cursor.execute(q_firm_fb, (card_id,)) fb_row = cursor.fetchone() if fb_row: print(f" Фоллбэк НАШЁЛ: FIRM_ID={fb_row[0]}") else: print(f" Фоллбэк НЕ НАШЁЛ - критическая ошибка!") # --- 7. Сводка --- print(f"\n--- 7. Сводка ---") cursor.execute( "SELECT COUNT(DISTINCT CMONTH), MIN(CMONTH), MAX(CMONTH) FROM UOV_SELFSERVICE_SL_YTAX WHERE CARD_ID = %s", (card_id,) ) summary = cursor.fetchone() if summary: print(f" Периодов в SL_YTAX: {summary[0]}") print(f" Диапазон: {summary[1]} - {summary[2]}") print(f"\n{'=' * 60}") print("Диагностика завершена") print("=" * 60) conn_sql.close()