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()