Files
finance/backend/app/imports/adapters/__init__.py
T
k1nq e43428c1a2
Gitea Actions CI / detect (push) Successful in 3s
Gitea Actions CI / Compose & nginx validation (push) Failing after 20s
Gitea Actions CI / Frontend (lint / type / test / build) (push) Failing after 24s
Gitea Actions CI / Backend (lint / type / test / build) (push) Failing after 1m34s
Implement Gitea CI and real statement imports
2026-09-18 17:59:02 +05:00

43 lines
1.5 KiB
Python

from app.imports.adapters.alfa_xlsx import (
AlfaCreditXlsxAdapter as AlfaCreditXlsxAdapter,
)
from app.imports.adapters.alfa_xlsx import AlfaDebitXlsxAdapter
from app.imports.adapters.base import StatementAdapter, UnsupportedStatementLayout
from app.imports.adapters.ozon_pdf import OzonCreditPdfAdapter as OzonCreditPdfAdapter
from app.imports.adapters.ozon_pdf import OzonDebitPdfAdapter
from app.imports.adapters.rocketbank_pdf import RocketbankDebitPdfAdapter
# Only the three evidenced-format development contracts are active. The credit
# adapters stay present but unregistered until real fixtures exist for them.
ADAPTERS: tuple[StatementAdapter, ...] = (
AlfaDebitXlsxAdapter(),
OzonDebitPdfAdapter(),
RocketbankDebitPdfAdapter(),
)
XLSX_MAGIC = b"PK\x03\x04"
PDF_MAGIC = b"%PDF-"
def magic_kind(raw: bytes) -> str | None:
if raw.startswith(XLSX_MAGIC):
return "xlsx"
if raw.startswith(PDF_MAGIC):
return "pdf"
return None
def detect_adapter(raw: bytes, magic: str) -> StatementAdapter:
attempted: list[str] = []
for adapter in ADAPTERS:
expected = "xlsx" if adapter.adapter_id.endswith("xlsx") else "pdf"
if expected != magic:
continue
attempted.append(adapter.adapter_id)
if adapter.detect(raw):
return adapter
raise UnsupportedStatementLayout(
"no registered adapter recognizes this document layout; "
f"attempted: {', '.join(attempted) or 'none for this file type'}"
)