проект теперь работает с использованием локальной базы данных SQLite. Все данные аккумулируются и хранятся в ней. Впереди - разработка веб интерфейса.
This commit is contained in:
+29
-19
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Модуль автоматического экспорта данных СКУД (Orion) из MS SQL Server в Excel.
|
||||
Модуль автоматического экспорта данных СКУД (Orion) из MS SQL Server в SQLite и Excel.
|
||||
Исправлена логика определения направления проходов (Mode = 2 -> OUT).
|
||||
"""
|
||||
|
||||
@@ -14,7 +14,8 @@ import pandas as pd
|
||||
import pyodbc
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
from config import SCUD_DIR
|
||||
from config import SCUD_DIR, clean_scud_fio_light, load_exceptions
|
||||
from modules.database import save_scud_to_db
|
||||
|
||||
warnings.filterwarnings("ignore", message="pandas only supports SQLAlchemy connectable")
|
||||
|
||||
@@ -64,7 +65,6 @@ DECLARE @TargetDate DATE = @InputDate;
|
||||
DECLARE @StartDate DATETIME = CAST(@TargetDate AS DATETIME);
|
||||
DECLARE @EndDate DATETIME = DATEADD(SECOND, -1, DATEADD(DAY, 1, @StartDate));
|
||||
|
||||
-- 1. Фильтруем логи только за нужные 24 часа с ПРАВИЛЬНЫМ ПРИОРИТЕТОМ ВЫХОДА (Mode = 2)
|
||||
WITH DailyLogs AS (
|
||||
SELECT
|
||||
log.HozOrgan AS EmployeeID,
|
||||
@@ -83,7 +83,6 @@ WITH DailyLogs AS (
|
||||
AND log.HozOrgan > 0
|
||||
AND (log.Event IN (28, 29, 26, 27, 32, 33) OR log.Mode IN (1, 2))
|
||||
),
|
||||
-- 2. Агрегируем первичное время входа и последнее время выхода
|
||||
Passages AS (
|
||||
SELECT
|
||||
EmployeeID,
|
||||
@@ -195,7 +194,7 @@ def get_targets(input_date: str | None):
|
||||
return targets
|
||||
|
||||
|
||||
def run_export(input_date: str | None = None, debug: bool = False):
|
||||
def run_export(input_date: str | None = None, save_xlsx: bool = True, debug: bool = False):
|
||||
if debug:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
log("=== ВКЛЮЧЕН РЕЖИМ ОТЛАДКИ (DEBUG MODE) ===", "WARNING")
|
||||
@@ -223,15 +222,6 @@ def run_export(input_date: str | None = None, debug: bool = False):
|
||||
|
||||
log(f"--- Обработка периода: {period_label} ({processing_date_str}) ---")
|
||||
|
||||
file_name = f"Сотрудники_{processing_date_str}.xlsx"
|
||||
file_path = os.path.join(SCUD_DIR, file_name)
|
||||
|
||||
if os.path.exists(file_path):
|
||||
try:
|
||||
os.remove(file_path)
|
||||
except OSError as e:
|
||||
log(f"ОШИБКА при удалении старого файла {file_name}: {e}", "ERROR")
|
||||
|
||||
sql_query = SQL_QUERY_TEMPLATE.format(target_date=processing_date.strftime("%Y-%m-%d"))
|
||||
|
||||
connection = None
|
||||
@@ -242,9 +232,28 @@ def run_export(input_date: str | None = None, debug: bool = False):
|
||||
log(f"База вернула {len(df)} строк за {processing_date_str}")
|
||||
|
||||
if len(df) > 0:
|
||||
df.to_excel(file_path, sheet_name="Отчет", index=False, engine="openpyxl")
|
||||
auto_fit_columns(file_path, sheet_name="Отчет")
|
||||
log(f"[✓] Успешно экспортирован файл: data/scud/{file_name}", "SUCCESS")
|
||||
# 1. Готовим колонки для локальной БД
|
||||
df['fio_clean'] = df['Сотрудник'].apply(clean_scud_fio_light)
|
||||
df['Пришел'] = df['Статус'].str.contains('Присутствовал', case=False, na=False)
|
||||
|
||||
# 2. ПРЯМОЕ СОХРАНЕНИЕ В SQLite (scud_orion_ai.db)
|
||||
save_scud_to_db(df, processing_date_str)
|
||||
log(f"[✓] Записи за {processing_date_str} успешно сохранены в SQLite!", "SUCCESS")
|
||||
|
||||
# 3. Сохранение в Excel (если включен флаг save_xlsx)
|
||||
if save_xlsx:
|
||||
file_name = f"Сотрудники_{processing_date_str}.xlsx"
|
||||
file_path = os.path.join(SCUD_DIR, file_name)
|
||||
|
||||
if os.path.exists(file_path):
|
||||
try:
|
||||
os.remove(file_path)
|
||||
except OSError as e:
|
||||
log(f"ОШИБКА при удалении старого файла {file_name}: {e}", "ERROR")
|
||||
|
||||
df.to_excel(file_path, sheet_name="Отчет", index=False, engine="openpyxl")
|
||||
auto_fit_columns(file_path, sheet_name="Отчет")
|
||||
log(f"[✓] Успешно экспортирован файл: data/scud/{file_name}", "SUCCESS")
|
||||
else:
|
||||
log(f"Запрос за {processing_date_str} вернул 0 строк.", "WARNING")
|
||||
|
||||
@@ -260,9 +269,10 @@ def run_export(input_date: str | None = None, debug: bool = False):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Экспорт данных СКУД в Excel")
|
||||
parser = argparse.ArgumentParser(description="Экспорт данных СКУД в SQLite и Excel")
|
||||
parser.add_argument("--date", dest="input_date", default=None)
|
||||
parser.add_argument("-d", "--debug", action="store_true")
|
||||
parser.add_argument("--no-xlsx", dest="save_xlsx", action="store_false", default=True, help="Отключить сохранение в XLSX")
|
||||
args = parser.parse_args()
|
||||
|
||||
run_export(args.input_date, debug=args.debug)
|
||||
run_export(args.input_date, save_xlsx=args.save_xlsx, debug=args.debug)
|
||||
Reference in New Issue
Block a user