comdirect ingest: some code structurerefinement
This commit is contained in:
@@ -11,6 +11,7 @@ wheels/
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
settings.py
|
||||
|
||||
# Database instances
|
||||
*.db
|
||||
|
||||
@@ -32,5 +32,6 @@ build-backend = "uv_build"
|
||||
dev = [
|
||||
"black>=26.5.1",
|
||||
"debugpy>=1.8.21",
|
||||
"faker>=40.38.0",
|
||||
"polyfactory>=3.3.0",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
from faker import Faker
|
||||
|
||||
from src.models import ComdirectCreditCard, ComdirectDepot, ComdirectGiro
|
||||
from src.settings.constants import Currency
|
||||
from src.settings.models import AccountInfo
|
||||
|
||||
fake = Faker()
|
||||
|
||||
BANK_ACCOUNTS = {
|
||||
"comdirect": {
|
||||
"Girokonto": AccountInfo(
|
||||
iban=fake.iban(),
|
||||
ingestion_function=lambda x: ComdirectGiro.model_validate(x),
|
||||
currency=Currency.EUR,
|
||||
),
|
||||
"Visa-Karte (Kreditkarte)": AccountInfo(
|
||||
iban=fake.iban(),
|
||||
ingestion_function=lambda x: ComdirectCreditCard.model_validate(x),
|
||||
currency=Currency.EUR,
|
||||
),
|
||||
"Tagesgeld PLUS-Konto": AccountInfo(
|
||||
iban=fake.iban(),
|
||||
ingestion_function=lambda x: ComdirectGiro.model_validate(x),
|
||||
currency=Currency.EUR,
|
||||
),
|
||||
"Depot": AccountInfo(
|
||||
iban=fake.iban(),
|
||||
ingestion_function=lambda x: ComdirectDepot.model_validate(x),
|
||||
currency=Currency.EUR,
|
||||
),
|
||||
}
|
||||
}
|
||||
+1
-14
@@ -4,20 +4,7 @@ from enum import Enum
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
IBAN_PATTERN = r"^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$"
|
||||
|
||||
|
||||
class Currency(str, Enum):
|
||||
EUR = "EUR"
|
||||
USD = "USD"
|
||||
GBP = "GBP"
|
||||
CHF = "CHF"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
def __repr__(self):
|
||||
return f"Currency.{self.name}"
|
||||
from src.settings.constants import IBAN_PATTERN, Currency
|
||||
|
||||
|
||||
class Sign(str, Enum):
|
||||
|
||||
+8
-9
@@ -3,8 +3,9 @@ import re
|
||||
from enum import Enum, auto
|
||||
from pathlib import Path
|
||||
|
||||
from settings import BANK_ACCOUNTS
|
||||
from src.models import B4wExport
|
||||
from src.settings.account_ingest import ACCOUNT_INGESTION_FUNCTIONS
|
||||
from src.settings.models import AccountInfo
|
||||
|
||||
|
||||
def _reader_raw(path: Path):
|
||||
@@ -29,18 +30,16 @@ class EXPECT_LINE(Enum):
|
||||
DATA = auto()
|
||||
|
||||
|
||||
COMDIRECT_ACCOUNTS = BANK_ACCOUNTS.get("comdirect", {})
|
||||
assert isinstance(COMDIRECT_ACCOUNTS, dict)
|
||||
|
||||
def reader_comdirect(path: Path):
|
||||
bank_name = "comdirect"
|
||||
ingestion_functions = ACCOUNT_INGESTION_FUNCTIONS.get(bank_name)
|
||||
assert ingestion_functions
|
||||
|
||||
result = {}
|
||||
raw = _reader_raw_comdirect(path)
|
||||
for account_name, account_data in raw.items():
|
||||
ingestion_function = ingestion_functions.get(account_name)
|
||||
assert ingestion_function
|
||||
result[account_name] = list(map(ingestion_function, account_data))
|
||||
|
||||
account = COMDIRECT_ACCOUNTS.get(account_name)
|
||||
assert isinstance(account, AccountInfo)
|
||||
result[account_name] = list(map(account.ingestion_function, account_data))
|
||||
return result
|
||||
|
||||
def _reader_raw_comdirect(path: Path):
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
from src.models import ComdirectCreditCard, ComdirectDepot, ComdirectGiro
|
||||
|
||||
ACCOUNT_INGESTION_FUNCTIONS = {
|
||||
"comdirect": {
|
||||
"Girokonto": lambda x: ComdirectGiro.model_validate(x),
|
||||
"Visa-Karte (Kreditkarte)": lambda x: ComdirectCreditCard.model_validate(x),
|
||||
"Tagesgeld PLUS-Konto": lambda x: ComdirectGiro.model_validate(x),
|
||||
"Depot": lambda x: ComdirectDepot.model_validate(x),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
from enum import Enum
|
||||
|
||||
IBAN_PATTERN = r"^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$"
|
||||
|
||||
class Currency(str, Enum):
|
||||
EUR = "EUR"
|
||||
USD = "USD"
|
||||
GBP = "GBP"
|
||||
CHF = "CHF"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
def __repr__(self):
|
||||
return f"Currency.{self.name}"
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from src.settings.constants import IBAN_PATTERN, Currency
|
||||
|
||||
|
||||
class AccountInfo(BaseModel):
|
||||
iban: str = Field(pattern=IBAN_PATTERN)
|
||||
ingestion_function: Callable
|
||||
currency: Currency
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
from pathlib import Path
|
||||
|
||||
from src.models import ComdirectCreditCard, ComdirectDepot, ComdirectGiro
|
||||
from src.reader import reader_comdirect
|
||||
from src.settings.account_ingest import ACCOUNT_INGESTION_FUNCTIONS
|
||||
from src.reader import COMDIRECT_ACCOUNTS, reader_comdirect
|
||||
|
||||
TEST_DATA_PATH = ".local/data/comdirect/umsaetze_9773063005_20260906-2043.csv"
|
||||
|
||||
|
||||
def test_reader_comdirect():
|
||||
bank_name = "comdirect"
|
||||
assert bank_name in ACCOUNT_INGESTION_FUNCTIONS
|
||||
test_path = Path(".local/data/comdirect/umsaetze_9773063005_20260906-2043.csv")
|
||||
test_path = Path(TEST_DATA_PATH)
|
||||
assert test_path.exists()
|
||||
data = reader_comdirect(test_path)
|
||||
assert data
|
||||
assert len(data) == len(ACCOUNT_INGESTION_FUNCTIONS.get(bank_name))
|
||||
assert set(data) == set(ACCOUNT_INGESTION_FUNCTIONS.get(bank_name))
|
||||
assert len(data) == len(COMDIRECT_ACCOUNTS)
|
||||
assert set(data) == set(COMDIRECT_ACCOUNTS)
|
||||
assert all(isinstance(row, ComdirectGiro) for row in data["Girokonto"])
|
||||
assert all(isinstance(row, ComdirectCreditCard) for row in data["Visa-Karte (Kreditkarte)"])
|
||||
assert all(isinstance(row, ComdirectGiro) for row in data["Tagesgeld PLUS-Konto"])
|
||||
|
||||
@@ -128,6 +128,7 @@ dependencies = [
|
||||
dev = [
|
||||
{ name = "black" },
|
||||
{ name = "debugpy" },
|
||||
{ name = "faker" },
|
||||
{ name = "polyfactory" },
|
||||
]
|
||||
|
||||
@@ -146,6 +147,7 @@ requires-dist = [
|
||||
dev = [
|
||||
{ name = "black", specifier = ">=26.5.1" },
|
||||
{ name = "debugpy", specifier = ">=1.8.21" },
|
||||
{ name = "faker", specifier = ">=40.38.0" },
|
||||
{ name = "polyfactory", specifier = ">=3.3.0" },
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user