Initial commit

This commit is contained in:
2026-07-14 01:16:33 +03:00
commit 92f04e0e8a
29 changed files with 2454 additions and 0 deletions

152
services/sbis_import.py Normal file
View File

@@ -0,0 +1,152 @@
import pandas as pd
from datetime import datetime
from services.contractors import get_contractors
def _find_column(df, aliases):
for name in aliases:
if name in df.columns:
return name
return None
def import_sbis_excel(file, conn):
contractors = {
name: contractor_id
for contractor_id, name in get_contractors(conn)
}
cursor = conn.cursor()
df = pd.read_excel(file)
required = {
"contractor": _find_column(
df, ["Контрагент", "Наименование контрагента", "Организация"]
),
"doc_date": _find_column(df, ["Дата", "Дата документа"]),
"doc_number": _find_column(df, ["Номер", "Номер документа"]),
"doc_type": _find_column(df, ["Вид документа", "Тип документа", "Тип"]),
"amount": _find_column(df, ["Сумма"]),
"state": _find_column(df, ["Состояние", "Статус", "Состояние документа"]),
}
missing = [key for key, col in required.items() if col is None]
if missing:
raise ValueError(
f"В файле не найдены обязательные колонки: {', '.join(missing)}"
)
responsible_col = _find_column(
df, ["Ответственный", "Ответственный сотрудник"]
)
description_col = _find_column(df, ["Описание", "Комментарий", "Примечание"])
imported = 0
updated = 0
skipped = 0
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Получаем максимальный row_order для новых записей
cursor.execute("SELECT COALESCE(MAX(row_order), 0) FROM documents_sbis")
max_order = cursor.fetchone()[0] or 0
for idx, (_, row) in enumerate(df.iterrows()):
contr = str(row[required["contractor"]]).strip()
if contr not in contractors:
skipped += 1
continue
doc_type = row[required["doc_type"]]
doc_date = row[required["doc_date"]]
number = row[required["doc_number"]]
summ = row[required["amount"]]
state = row[required["state"]]
amount = float(summ) if pd.notna(summ) else 0
responsible = (
str(row[responsible_col]).strip()
if responsible_col and pd.notna(row[responsible_col])
else None
)
description = (
str(row[description_col]).strip()
if description_col and pd.notna(row[description_col])
else None
)
# Проверяем существование документа
cursor.execute(
"""
SELECT id
FROM documents_sbis
WHERE contractor = ?
AND doc_type = ?
AND doc_date = ?
AND doc_number = ?
AND amount = ?
""",
(
contr,
str(doc_type),
str(doc_date),
str(number),
amount,
),
)
document = cursor.fetchone()
if document:
cursor.execute(
"""
UPDATE documents_sbis
SET state = ?,
responsible = COALESCE(?, responsible),
description = COALESCE(?, description),
updated_at = ?
WHERE id = ?
""",
(str(state), responsible, description, now, document[0]),
)
updated += 1
else:
row_order = max_order + idx + 1
cursor.execute(
"""
INSERT INTO documents_sbis (
raw_text,
doc_date,
doc_number,
contractor,
doc_type,
amount,
description,
state,
responsible,
created_at,
updated_at,
row_order
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
None,
str(doc_date),
str(number),
contr,
str(doc_type),
amount,
description,
str(state),
responsible,
now,
now,
row_order,
),
)
imported += 1
conn.commit()
return imported, updated, skipped