101 lines
4.1 KiB
Python
101 lines
4.1 KiB
Python
import os
|
|
import sys
|
|
import pandas as pd
|
|
|
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
from config import DATE_TODAY, DATE_YESTERDAY, OUTPUT_DIR
|
|
from modules.data_validator import check_file_freshness
|
|
from modules.data_loader import load_all_data
|
|
from modules.excel_exporter import generate_summary_excel, generate_detailed_excel
|
|
from modules.ai_verifier import ai_verify_scud_against_staff
|
|
from modules.text_reporter import generate_markdown_report
|
|
from modules.knowledge_base import load_knowledge_base
|
|
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("ЗАПУСК СИСТЕМЫ МОДУЛЬНОГО КОНТРОЛЛИНГА СКУД ⟷ 1С")
|
|
print("=" * 60)
|
|
|
|
# 0. Валидация файлов
|
|
print("[0/5] Проверка актуальности и свежести входных файлов...")
|
|
is_valid, warnings, errors = check_file_freshness()
|
|
|
|
if warnings:
|
|
print("\n--- ⚠️ ПРЕДУПРЕЖДЕНИЯ ОБ АКТУАЛЬНОСТИ ---")
|
|
for w in warnings:
|
|
print(f" {w}")
|
|
print("-" * 45)
|
|
|
|
if not is_valid:
|
|
print("\n" + "!" * 60)
|
|
print("🛑 ОСТАНОВКА ВЫПОЛНЕНИЯ: Обнаружены критические ошибки данных!")
|
|
for e in errors:
|
|
print(f" {e}")
|
|
print("!" * 60)
|
|
sys.exit(1)
|
|
|
|
print("[✓] Проверка актуальности успешно пройдена!\n")
|
|
|
|
# 1. Загрузка
|
|
print("[1/5] Загрузка данных СКУД, 1С и исключений...")
|
|
raw_scud_df, staff_fios_clean, df_absent = load_all_data()
|
|
|
|
# 2. ИИ-сверка
|
|
print("[2/5] Проверка опечаток и сопоставление ФИО через ИИ...")
|
|
scud_unrecognized = raw_scud_df[~raw_scud_df['fio_clean'].isin(staff_fios_clean)]['fio_clean'].tolist()
|
|
fio_mapping = ai_verify_scud_against_staff(scud_unrecognized, staff_fios_clean)
|
|
|
|
if fio_mapping:
|
|
print(f" [ИИ] Найдено и исправлено совпадений/опечаток: {len(fio_mapping)}")
|
|
raw_scud_df['fio_clean'] = raw_scud_df['fio_clean'].apply(
|
|
lambda x: fio_mapping[x]['staff_fio'] if x in fio_mapping else x
|
|
)
|
|
|
|
# 3. Объединение
|
|
print("[3/5] Объединение реестров 1С и СКУД...")
|
|
merged = raw_scud_df[raw_scud_df['fio_clean'].isin(staff_fios_clean)].copy()
|
|
merged = merged.merge(df_absent, on='fio_clean', how='left')
|
|
|
|
absent_explained = merged[(merged['Пришел'] == False) & (merged['Вид_отсутствия'].notna())]
|
|
absent_unexplained = merged[(merged['Пришел'] == False) & (merged['Вид_отсутствия'].isna())]
|
|
scud_present_but_absent_in_1c = merged[(merged['Пришел'] == True) & (merged['Вид_отсутствия'].notna())]
|
|
|
|
# 4. Формирование Excel-файлов (автоматическое наименование вида "27 июля 2026 сводка.xlsx")
|
|
print("[4/5] Формирование Excel-файлов...")
|
|
|
|
generate_summary_excel(
|
|
merged_df=merged,
|
|
date_str=DATE_TODAY
|
|
)
|
|
|
|
generate_detailed_excel(
|
|
merged_df=merged,
|
|
date_str=DATE_YESTERDAY
|
|
)
|
|
|
|
# 5. Текстовый ИИ-отчет
|
|
print("[5/5] Запуск ИИ-аудитора...")
|
|
report_text = generate_markdown_report(
|
|
merged_df=merged,
|
|
absent_explained=absent_explained,
|
|
absent_unexplained=absent_unexplained,
|
|
scud_present_but_absent_in_1c=scud_present_but_absent_in_1c,
|
|
raw_scud_df=raw_scud_df,
|
|
date_str=DATE_TODAY
|
|
)
|
|
|
|
print("\n" + "=" * 60)
|
|
print("ГОТОВАЯ ТЕКСТОВАЯ СВОДКА ИИ:")
|
|
print("=" * 60)
|
|
print(report_text)
|
|
|
|
md_report_path = os.path.join(OUTPUT_DIR, f"Сводка_контроллинга_{DATE_TODAY}.md")
|
|
with open(md_report_path, "w", encoding="utf-8") as f:
|
|
f.write(report_text)
|
|
print(f"\n[✓] Текстовый отчет сохранен в: {md_report_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |