очистка перед API
This commit is contained in:
@@ -1,82 +0,0 @@
|
||||
# 📦 ПАСПОРТ СНАПШОТА ПРОЕКТА: `scud_orion_ai_v2`
|
||||
|
||||
> **Архитектура:** Автоматизированный конвейер кадрового контроллинга и детекции аномалий
|
||||
> **Интеграционный стек:** `СКУД «Орион Pro»` ⟷ `1С:ЗУП` ⟷ `AI-Аудитор`
|
||||
> **Статус:** 🟢 **Готовая боевая сборка** с прямой SQL-интеграцией, обработкой 1С-реестров и обучением на лету.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Итоговая структура каталогов
|
||||
|
||||
```plaintext
|
||||
scud_orion_ai_v2/
|
||||
├── .gitignore # Настройки исключений отслеживания Git
|
||||
├── exceptions.json # Реестр постоянных исключений (ОВК, подрядчики, особые роли)
|
||||
├── knowledge_base.json # Динамическая база знаний (накопленные правила ИИ из режима Human-in-the-Loop)
|
||||
├── config.py # Глобальная конфигурация путей, моделей Ollama и функций нормализации
|
||||
├── main.py # Главный оркестратор (Этапы 0–5, логика слияния, детекция аномалий)
|
||||
│
|
||||
├── data/ # 📂 Папка входных сырых данных
|
||||
│ ├── scud/ # [Автовыгрузка СКУД] Файлы Сотрудники_ДД.ММ.ГГГГ.xlsx из MS SQL
|
||||
│ ├── 1c/ # [Кадровые реестры] Файлы из 1С:ЗУП:
|
||||
│ │ # • Штатные сотрудники - ОУП.xlsx
|
||||
│ │ # • Отсутствия сотрудников - выгрузка.xlsx
|
||||
│ └── static_reason_workers.csv# [Справочник] Реестр постоянных причин (Удаленка и т.д.)
|
||||
│
|
||||
├── output/ # 📂 Результаты работы (Excel-сводки и ИИ-отчеты в Markdown)
|
||||
│ ├── Сводка_контроллинга_ДД.ММ.ГГГГ.md
|
||||
│ ├── ДД месяца ГГГГ сводка.xlsx
|
||||
│ └── ДД месяца ГГГГ отчет.xlsx
|
||||
│
|
||||
└── modules/ # 📂 Функциональные ядро-модули
|
||||
├── scud_export.py # Модуль прямого подключения к MS SQL Server (Орион Pro)
|
||||
├── data_loader.py # Загрузка и первичная предобработка СКУД/1С файлов
|
||||
├── data_validator.py # Валидатор свежести и корректности входных таблиц
|
||||
├── ai_verifier.py # Интеграция с Ollama (Qwen2.5) для нечеткого поиска ФИО и опечаток
|
||||
├── text_reporter.py # Формирователь экспертного аналитического отчета ИИ
|
||||
├── excel_exporter.py # Генератор итоговых стилизованных Excel-отчетов
|
||||
├── feedback_loop.py # Модуль интерактивного обучения и дообучения ИИ (Human-in-the-Loop)
|
||||
└── knowledge_base.py # Менеджер чтения/записи базы знаний knowledge_base.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Главные технические наработки и решённые задачи
|
||||
|
||||
### 1. Автоматический забор данных СКУД из БД MS SQL Server (`scud_export.py`)
|
||||
* **Прямой коннект:** Запрос к БД СКУД `Orion-14.01.21-1` через `pyodbc`.
|
||||
* **Высокая скорость (0.2 сек):** Использование оконной функции `ROW_NUMBER() OVER (PARTITION BY HozOrgan ORDER BY TimeVal DESC)` для мгновенного сбора событий за 24 часа.
|
||||
* **Корректный учет текущего присутствия (`СЕГОДНЯ`):**
|
||||
* Если день ещё не окончен и последнее событие — **Вход**, в колонке выводится `Нет выхода`.
|
||||
* Ограничено искажение времени для тех, кто ещё находится в здании или уходил на обед.
|
||||
* **Поддержка отладки (`-d` / `--debug`):** Вывод детальной статистики в консоль (сколько в здании, сколько ушло, сколько отсутствовало).
|
||||
|
||||
### 2. Нормализация и ИИ-сборка данных (`config.py` + `data_loader.py` + `ai_verifier.py`)
|
||||
* **Удаление технического мусора:** Автоматическая очистка служебных пометок 1С в скобках (`(осн.)`, `(совм.)`, `(сводная)`), предотвращающая расхождение ФИО.
|
||||
* **Умное слияние с 1С:** Поиск опечаток и несопоставленных записей в реестре отсутствий через нейросеть `Qwen2.5:14b`.
|
||||
|
||||
### 3. Комплексный детектор аномалий (`main.py`)
|
||||
Автоматическое пересечение всех 4 источников (*СКУД* + *1С* + *Статический реестр* + *Исключения*) с перехватом конфликтов:
|
||||
* 🔴 **Критическая аномалия:** Физический проход по СКУД при наличии оформленного документа в 1С (*Отпуск* / *Больничный* / *Командировка*).
|
||||
* 🟠 **Удалёнщик в офисе:** Сотрудник числится на постоянной удалёнке, но пришёл через турникет.
|
||||
* 🟡 **Конфликт справочников:** Нестыковка данных 1С:ЗУП и реестра статических причин.
|
||||
|
||||
### 4. Обучение на лету / Human-in-the-Loop (`feedback_loop.py` + `knowledge_base.json`)
|
||||
* **Запоминание правил:** Если пользователь разрешает спорную ситуацию *(например: «Незнанова иногда в офисе — не считать аномалией»)*, правило фиксируется в `knowledge_base.json`.
|
||||
* **Авто-фильтрация:** Детектор аномалий проверяет Базу Знаний до формирования вопросов, избавляя пользователя от повторных уведомлений по решённым случаям.
|
||||
|
||||
### 5. Лаконичная аналитическая отчетность (`text_reporter.py`)
|
||||
* Формирование строгой сводки в формате Markdown.
|
||||
* Выведение отдельным блоком нумерованного списка истинно неизвестных случаев.
|
||||
* Отсутствие дублирования ФИО в разделе кадровых рекомендаций.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Команды для запуска снапшота
|
||||
|
||||
| Режим запуска | Команда в терминале |
|
||||
| :--- | :--- |
|
||||
| **Стандартный запуск** *(Экспорт СКУД из SQL + ИИ Анализ)* | `python main.py` |
|
||||
| **Режим отладки** *(С детальными логами)* | `python main.py -d` |
|
||||
| **Без повторного обращения к SQL** *(На сохраненных файлах)* | `python main.py --skip-export` |
|
||||
| **Отладка только модуля выгрузки СКУД** | `python modules/scud_export.py -d` |
|
||||
@@ -1,133 +0,0 @@
|
||||
# Архитектура и документация проекта СКУД v2
|
||||
|
||||
## 1. Фактическая структура проекта
|
||||
|
||||
```text
|
||||
scud_root_v2/
|
||||
│
|
||||
├── config.py # Конфигурация, глобальные пути (DATA_DIR, OUTPUT_DIR), даты (DATE_TODAY, DATE_YESTERDAY)
|
||||
├── exceptions.json # Фильтры исключений (ОВК, клинеры, конкретные ФИО)
|
||||
├── PROJECT_SNAPSHOT.md # 📄 Архитектурный снимок состояния проекта
|
||||
├── main.py # Главный скрипт запуска и оркестрации всего конвейера
|
||||
│
|
||||
├── data/ # 📂 Входные файлы (Выгрузки СКУД и 1С)
|
||||
│ ├── knowledge_base.json # Накопленная база знаний и динамические правила компании
|
||||
│ ├── Штатные сотрудники - ОУП.xlsx # Выгрузка штата из 1С
|
||||
│ ├── Отсутствия сотрудников - выгрузка.xlsx # Выгрузка докум. отсутствий из 1С
|
||||
│ ├── Сотрудники_24.07.2026.xlsx # Выгрузка СКУД за ВЧЕРА (для детального отчета)
|
||||
│ └── Сотрудники_27.07.2026.xlsx # Выгрузка СКУД за СЕГОДНЯ (для оперативной сводки)
|
||||
│
|
||||
├── modules/ # 📂 Исполняемые модули системы
|
||||
│ ├── __init__.py
|
||||
│ ├── data_validator.py # 🛡️ Детерминированный контроль актуальности и свежести входных файлов СКУД/1С
|
||||
│ ├── data_loader.py # Загрузка и объединение Excel-выгрузок СКУД и 1С
|
||||
│ ├── ai_verifier.py # Интеграция с Ollama (qwen2.5:14b) для исправления опечаток в ФИО из СКУД
|
||||
│ ├── excel_exporter.py # 📊 Единый модуль генерации Excel-файлов (Сводка + Детальный отчет за вчера)
|
||||
│ ├── text_reporter.py # 📝 ИИ-аудитор (формирование текстовой сводки с проверкой совмещений)
|
||||
│ ├── knowledge_base.py # Чтение/запись динамических правил компании
|
||||
│ └── feedback_loop.py # Модуль обратной связи для обучения базы знаний
|
||||
│
|
||||
└── output/ # 📂 Результаты работы (генерируются автоматически):
|
||||
├── 26 июля 2026 отчет.xlsx
|
||||
├── 27 июля 2026 сводка.xlsx
|
||||
└── Сводка_контроллинга_27.07.2026.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Подробное описание модулей и их логики
|
||||
|
||||
### ⚙️ `config.py`
|
||||
**Константы:**
|
||||
- `OLLAMA_URL = "http://localhost:11434/api/chat"`
|
||||
- `OLLAMA_MODEL = "qwen2.5:14b"`
|
||||
- `DATE_TODAY`, `DATE_YESTERDAY` — расчет рабочих дат.
|
||||
|
||||
**Основные функции:**
|
||||
- `normalize_fio()` — приводит ФИО к нижнему регистру, удаляет скобки `(...)`, меняет латинские визуальные дубликаты букв на кириллицу, заменяет `ё` на `е`.
|
||||
- `clean_scud_fio_light()` — облегченная очистка ФИО из СКУД от системных символов и артефактов.
|
||||
- `load_exceptions()` — загружает фильтры и исключения из `exceptions.json`.
|
||||
|
||||
---
|
||||
|
||||
### 🛡️ `modules/data_validator.py`
|
||||
Модуль детерминированного контроля актуальности данных (**Data Quality & Freshness Control**).
|
||||
|
||||
- Проверяет наличие файлов за сегодня и вчера в папке `data/`.
|
||||
- Проверяет дату и время изменения файлов (`mtime`), предотвращая запуск системы на устаревших выгрузках прошлого дня.
|
||||
- В случае отсутствия или устаревания данных блокирует запуск основного конвейера и предупреждает оператора.
|
||||
|
||||
---
|
||||
|
||||
### 🛡️ `exceptions.json`
|
||||
Содержит конфигурационные списки исключений, отфильтровываемые при сборе аналитики:
|
||||
- **Департаменты:** отдел ОВК и др.
|
||||
- **Должности:** Уборщик, Клинер, Дворник и т.д.
|
||||
- **Персональные исключения:** конкретные ФИО сотрудников или подрядчиков.
|
||||
|
||||
---
|
||||
|
||||
### 📥 `modules/data_loader.py`
|
||||
- Выполняет загрузку данных из папки `data/`.
|
||||
- Определяет факт присутствия на рабочем месте (`Пришел = True`, если зафиксирован проход в СКУД).
|
||||
- Применяет правила фильтрации `is_excluded()` на основе данных из `exceptions.json`.
|
||||
|
||||
---
|
||||
|
||||
### 🤖 `modules/ai_verifier.py`
|
||||
- Отправляет список нераспознанных ФИО из СКУД и эталонный список из 1С в модель Ollama (`qwen2.5:14b`).
|
||||
- Автоматически выявляет опечатки, несоответствия в написании и возвращает JSON сопоставлений.
|
||||
|
||||
---
|
||||
|
||||
### 📊 `modules/excel_exporter.py`
|
||||
Универсальный модуль формирования отчетов в формате Excel. Автоматически формирует имена файлов с названием месяца прописью (например, `27 июля 2026 сводка.xlsx` и `26 июля 2026 отчет.xlsx`).
|
||||
|
||||
#### 1. Оперативная сводка за сегодня (`generate_summary_excel`):
|
||||
- **Древовидная группировка:** Категория *«неизвестно»* раскрыта по умолчанию, остальные категории свернуты под плюсики `[+]` / `[-]`.
|
||||
- **Настройка структуры:** Принудительно включено отображение боковой панели со значками группировки через `showOutlineSymbols = True`.
|
||||
- **Палитра:**
|
||||
- Шапка: `#D9E1F2` *(Светло-голубой)*
|
||||
- По списку: `#F2F2F2` *(Светло-серый)*
|
||||
- Неизвестно: `#FCE4D6` *(Персиковый)*
|
||||
- Категории 1С: Циклическая пастельная палитра (`#FFF2CC`, `#E1D5E7`, `#E1F5FE`, `#FFF0F5`, `#E8F8F5`, `#FCF3CF`)
|
||||
- Итого на работе: `#E2EFDA` *(Светло-зеленый)*
|
||||
|
||||
#### 2. Детальный отчет за вчера (`generate_detailed_excel`):
|
||||
- **Динамическая ширина колонок:** Ширина столбцов рассчитывается по длине самого широкого значения ячеек.
|
||||
- **Столбец G (Причина отсутствия):** Ширина фиксирована на `25.0` (180 px), включен автоперенос текста (`wrap_text = True`) с адаптивным расширением высоты строк под длинные тексты.
|
||||
- **Цветовая маркировка:**
|
||||
- `#FFF2CC` *(Желтый)* — есть официальная причина в 1С.
|
||||
- `#FCE4D6` *(Светло-красный)* — приход отсутствует, документ в 1С не найден.
|
||||
|
||||
---
|
||||
|
||||
### 📝 `modules/text_reporter.py`
|
||||
- Формирует с помощью Ollama текстовую Markdown-сводку для руководства.
|
||||
- **Форматирование нумерованного списка неизвестных:** Строгий формат `N. ФИО — [Аббревиатура], Должность`.
|
||||
- **Контроль математики:** Количество человек в поле *«Неизвестно»* строго совпадает с количеством элементов в сгенерированном нумерованном списке.
|
||||
- **Подсветка аномалий:** Выявление совмещений и сотрудников с несколькими табельными номерами/картами СКУД (например, Кондрашова Е.В.).
|
||||
|
||||
---
|
||||
|
||||
### 🚀 `main.py`
|
||||
Главный исполнительный модуль системы. Координирует конвейер обработки:
|
||||
|
||||
1. `check_file_freshness()` — **Этап 0:** жесткая проверка свежести файлов.
|
||||
2. `load_all_data()` — загрузка реестров 1С и СКУД.
|
||||
3. `ai_verify()` — сопоставление опечаток в ФИО через ИИ.
|
||||
4. `merge()` — связывание, фильтрация и категоризация данных.
|
||||
5. **Генерация отчетов** — создание `[дата] сводка.xlsx` и `[дата] отчет.xlsx`.
|
||||
6. **Вывод ИИ-сводки** — формирование и сохранение текстового итогового отчета в `output/`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Текущие и будущие задачи
|
||||
|
||||
### 🗄️ Разворачивание локальной базы данных
|
||||
- Переход от плоских файлов Excel к локальной СУБД (SQLite / PostgreSQL).
|
||||
- Хранение истории проходов и статусов сотрудников с временными метками для быстрого формирования аналитики за любой выбранный период.
|
||||
|
||||
### 🔄 Переход на прямое подключение к СКУД через T-SQL
|
||||
- Настройка прямого подключения Python к базе данных СКУД через `pyodbc` / `sqlalchemy`.
|
||||
- Отказ от ручной выгрузки Excel-файлов СКУД оператором.
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"rules": [
|
||||
"Кондрашова Елена Владимировна имеет 2 пропуска в СКУД. Если один 'Отсутствовал', а второй с временем входа — считать ПРИШЕДШЕЙ.",
|
||||
"ГЛОБАЛЬНОЕ ПРАВИЛО 1: Документы отсутствий из 1С:ЗУП (отпуск, больничный, командировка) имеют 100% высший приоритет над статическим реестром удалёнщиков.",
|
||||
"ГЛОБАЛЬНОЕ ПРАВИЛО 2: Удалённые сотрудники имеют право беспрепятственно работать в офисе по СКУД в любое время (это не является аномалией)."
|
||||
],
|
||||
"fio_corrections": {
|
||||
"кондрашава елена владимировна": "Кондрашова Елена Владимировна"
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import sqlite3
|
||||
import os
|
||||
from config import DATA_DIR
|
||||
|
||||
DB_PATH = os.path.join(DATA_DIR, "scud_orion_ai.db")
|
||||
|
||||
system_ai_prompt = (
|
||||
"СИСТЕМНЫЙ ПРОМПТ ИИ (MATCHING & VERIFICATION):\n"
|
||||
"Ты — экспертный ИИ-аудитор СКУД и кадрового учета 1С. Твоя задача — проводить интеллектуальный анализ аномалий "
|
||||
"и сопоставление (Fuzzy Matching) нераспознанных ФИО из СКУД с эталонным Штатным расписанием 1С.\n\n"
|
||||
"1. ЗАЩИТА ОТ ПОЛНЫХ ТЁЗОК (FULL NAME COLLISION):\n"
|
||||
" - Если в эталонном штате 1С присутствуют два или более сотрудников с ОДИНАКОВЫМИ ФИО (полные тёзки), "
|
||||
"ты ОБЯЗАН учитывать контекст: Подразделение и Должность.\n"
|
||||
" - Ни в коем случае не объединяй записи разных людей! Если контекст не позволяет однозначно определить, кто именно из тёзок совершил проход, ПОМЕТЬ СЛУЧАЙ КАК НЕОДНОЗНАЧНЫЙ и НЕ делай автоматическую подмену.\n\n"
|
||||
"2. ПРАВИЛА СОПОСТАВЛЕНИЯ (MATCHING RULES):\n"
|
||||
" - Допускаются исправления мелких опечаток, перестановки порядка (Имя Фамилия -> Фамилия Имя), замена букв Е/Ё, И/Й.\n"
|
||||
" - Учитывай сокращения инициалов (например, 'Иванов И.В.' -> 'Иванов Иван Васильевич').\n"
|
||||
" - Если уверенность в совпадении меньше 85% — НЕ сопоставляй, оставляй запись как нераспознанную.\n\n"
|
||||
"3. ФОРМАТ ВЫХОДНЫХ ДАННЫХ:\n"
|
||||
" Верни строго JSON-объект без вводных слов и Markdown-разметки: {\"mappings\": [...], \"unmatched\": [...]}"
|
||||
)
|
||||
|
||||
rules = [
|
||||
(system_ai_prompt, "System_AI"),
|
||||
("ГЛОБАЛЬНОЕ ПРАВИЛО 1: Любое физическое присутствие сотрудника по СКУД при наличии в 1С документа отсутствия (отпуск, больничный, уход за ребенком и др.), КРОМЕ командировок и служебных поездок — ЯВЛЯЕТСЯ СТРОГОЙ ИСТИННОЙ АНОМАЛИЕЙ.", "Human"),
|
||||
("ГЛОБАЛЬНОЕ ПРАВИЛО 2: Документы отсутствий из 1С:ЗУП имеют 100% высший приоритет над статическим реестром удалёнщиков.", "Human"),
|
||||
("ГЛОБАЛЬНОЕ ПРАВИЛО 3: Удалённые сотрудники имеют право беспрепятственно работать в офисе по СКУД в любое время (это не является аномалией).", "Human")
|
||||
]
|
||||
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Очищаем таблицу перед записью, чтобы избежать дублей и UNIQUE constraint error
|
||||
cursor.execute("DELETE FROM ai_knowledge_base;")
|
||||
|
||||
for rule_text, added_by in rules:
|
||||
cursor.execute(
|
||||
"INSERT INTO ai_knowledge_base (rule_text, added_by) VALUES (?, ?)",
|
||||
(rule_text, added_by)
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
print("✅ База знаний успешно перезаписана с включением системного промпта ИИ!")
|
||||
@@ -1,63 +0,0 @@
|
||||
import pyodbc
|
||||
from config import ZUP_SQL_CONFIG
|
||||
|
||||
print("="*60)
|
||||
print("🕵️♂️ ZUP DETECTIVE: ПОИСК СТАТУСА 'УВОЛЕН'")
|
||||
print("="*60)
|
||||
|
||||
conn_str = (
|
||||
f"DRIVER={ZUP_SQL_CONFIG['driver']};"
|
||||
f"SERVER={ZUP_SQL_CONFIG['server']};"
|
||||
f"DATABASE={ZUP_SQL_CONFIG['database']};"
|
||||
f"UID={ZUP_SQL_CONFIG['user']};"
|
||||
f"PWD={ZUP_SQL_CONFIG['password']};"
|
||||
f"TrustServerCertificate=yes;"
|
||||
)
|
||||
|
||||
with pyodbc.connect(conn_str) as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 1. Получаем ID наших подопытных
|
||||
cursor.execute("SELECT TOP 1 _IDRRef FROM dbo._Reference299 WHERE _Description LIKE '%Шумский Алексей Анатольевич%'")
|
||||
id_work = cursor.fetchone()[0]
|
||||
|
||||
cursor.execute("SELECT TOP 1 _IDRRef FROM dbo._Reference299 WHERE _Description LIKE '%Щелканов Дмитрий Викторович%'")
|
||||
id_fired = cursor.fetchone()[0]
|
||||
|
||||
# 2. Сканируем два самых больших кадровых регистра, которые нашел наш сканер
|
||||
for table in ['_InfoRg16684', '_InfoRg32796']:
|
||||
print(f"\n🔍 АНАЛИЗ РЕГИСТРА: {table}")
|
||||
|
||||
# Ищем все колонки-ссылки
|
||||
cursor.execute(f"SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('{table}') AND system_type_id = 173 AND max_length = 16")
|
||||
cols_bin = [r[0] for r in cursor.fetchall()]
|
||||
|
||||
found = False
|
||||
for col in cols_bin:
|
||||
cursor.execute(f"SELECT COUNT(*) FROM dbo.{table} WITH (NOLOCK) WHERE {col} = ?", (id_work,))
|
||||
if cursor.fetchone()[0] > 0:
|
||||
print(f"✅ Найдена колонка связи с Сотрудником: {col}")
|
||||
|
||||
# Забираем полные строки обоих людей
|
||||
cursor.execute(f"SELECT * FROM dbo.{table} WITH (NOLOCK) WHERE {col} = ?", (id_work,))
|
||||
data_work = cursor.fetchone()
|
||||
all_cols = [c[0] for c in cursor.description]
|
||||
|
||||
cursor.execute(f"SELECT * FROM dbo.{table} WITH (NOLOCK) WHERE {col} = ?", (id_fired,))
|
||||
data_fired = cursor.fetchone()
|
||||
|
||||
if data_work and data_fired:
|
||||
print("\n⚖️ ОТЛИЧИЯ В ДАННЫХ (Работает vs Уволен):")
|
||||
for i, c in enumerate(all_cols):
|
||||
# Выводим только те поля, где есть отличия
|
||||
if data_work[i] != data_fired[i]:
|
||||
print(f"Поле [{c}]:")
|
||||
print(f" 🟢 Шумский: {data_work[i]}")
|
||||
print(f" 🔴 Щелканов: {data_fired[i]}\n")
|
||||
found = True
|
||||
break
|
||||
|
||||
if found:
|
||||
break
|
||||
|
||||
print("✅ Расследование завершено!")
|
||||
@@ -1,60 +0,0 @@
|
||||
import pyodbc
|
||||
from config import ZUP_SQL_CONFIG
|
||||
|
||||
print("="*60)
|
||||
print("🔍 ЗАПУСК СКАНЕРА СТРУКТУРЫ 1С:ЗУП 3.1")
|
||||
print("="*60)
|
||||
|
||||
conn_str = (
|
||||
f"DRIVER={ZUP_SQL_CONFIG['driver']};"
|
||||
f"SERVER={ZUP_SQL_CONFIG['server']};"
|
||||
f"DATABASE={ZUP_SQL_CONFIG['database']};"
|
||||
f"UID={ZUP_SQL_CONFIG['user']};"
|
||||
f"PWD={ZUP_SQL_CONFIG['password']};"
|
||||
f"TrustServerCertificate=yes;"
|
||||
f"Encrypt=no;"
|
||||
)
|
||||
|
||||
with pyodbc.connect(conn_str) as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
print("⏳ Анализ справочников...")
|
||||
cursor.execute("SELECT name FROM sys.tables WHERE name LIKE '_Reference%'")
|
||||
for row in cursor.fetchall():
|
||||
t = row[0]
|
||||
try:
|
||||
cursor.execute(f"SELECT TOP 5 CAST(_Description AS NVARCHAR(255)) FROM {t} WITH (NOLOCK) WHERE _Description <> ''")
|
||||
vals = [r[0].strip() for r in cursor.fetchall() if r[0]]
|
||||
if not vals: continue
|
||||
text = " ".join(vals).lower()
|
||||
|
||||
# Ищем сотрудников (исключая физлиц _Reference299)
|
||||
if t != '_Reference299' and any(w in text for w in ["александров", "иванов", "смирнов", "петрова", "сергеев"]):
|
||||
print(f"👤 СОТРУДНИКИ ({t}): {vals[:3]}")
|
||||
# Ищем должности
|
||||
elif any(w in text for w in ["инженер", "специалист", "директор", "уборщик"]):
|
||||
print(f"💼 ДОЛЖНОСТИ ({t}): {vals[:3]}")
|
||||
# Ищем подразделения
|
||||
elif any(w in text for w in ["отдел", "управление", "служба"]):
|
||||
print(f"🏢 ПОДРАЗДЕЛЕНИЯ ({t}): {vals[:3]}")
|
||||
except:
|
||||
pass
|
||||
|
||||
print("\n⏳ Анализ регистров кадровой истории...")
|
||||
cursor.execute("SELECT name FROM sys.tables WHERE name LIKE '_InfoRg%'")
|
||||
for row in cursor.fetchall():
|
||||
t = row[0]
|
||||
try:
|
||||
# Ищем широкие регистры (Текущие кадровые данные имеют много колонок)
|
||||
cursor.execute(f"SELECT COUNT(*) FROM sys.columns WHERE object_id = OBJECT_ID('{t}')")
|
||||
col_count = cursor.fetchone()[0]
|
||||
|
||||
cursor.execute(f"SELECT COUNT(*) FROM {t} WITH (NOLOCK)")
|
||||
row_count = cursor.fetchone()[0]
|
||||
|
||||
if col_count > 15 and row_count > 500:
|
||||
print(f"📋 ШИРОКИЙ РЕГИСТР КАДРОВ ({t}) -> Колонок: {col_count}, Строк: {row_count}")
|
||||
except:
|
||||
pass
|
||||
|
||||
print("\n✅ Сканирование завершено!")
|
||||
Reference in New Issue
Block a user