80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
|
|
@dataclass
|
|
class BankProfile:
|
|
id: str
|
|
name: str
|
|
account_type: str # BANK | CREDIT_CARD | INVESTMENT
|
|
strategy: str # A | B
|
|
date_column: str
|
|
description_column: str
|
|
detect_columns: list[str]
|
|
category_column: Optional[str] = None
|
|
# Strategy A
|
|
amount_column: Optional[str] = None
|
|
invert_amount_sign: Optional[bool] = None
|
|
# Strategy B
|
|
debit_column: Optional[str] = None
|
|
credit_column: Optional[str] = None
|
|
# Strategy C
|
|
type_column: Optional[str] = None
|
|
|
|
|
|
BANK_PROFILES: list[BankProfile] = [
|
|
BankProfile(
|
|
id="discover-savings",
|
|
name="Discover High Yield Savings",
|
|
account_type="BANK",
|
|
strategy="C",
|
|
date_column="Transaction Date",
|
|
description_column="Transaction Description",
|
|
amount_column="Transaction Amount",
|
|
type_column="Transaction Type",
|
|
detect_columns=["Transaction Date", "Transaction Description", "Transaction Type", "Transaction Amount", "Balance"],
|
|
),
|
|
BankProfile(
|
|
id="discover-cc",
|
|
name="Discover Credit Card",
|
|
account_type="CREDIT_CARD",
|
|
strategy="B",
|
|
date_column="Transaction Date",
|
|
description_column="Description",
|
|
debit_column="Debit",
|
|
credit_column="Credit",
|
|
category_column="Category",
|
|
detect_columns=["Transaction Date", "Posted Date", "Card No.", "Description", "Category", "Debit", "Credit"],
|
|
),
|
|
BankProfile(
|
|
id="huntington-checking",
|
|
name="Huntington Checking",
|
|
account_type="BANK",
|
|
strategy="A",
|
|
date_column="Date",
|
|
description_column="Description",
|
|
amount_column="Amount",
|
|
invert_amount_sign=True, # negative = DEBIT (withdrawal), positive = CREDIT (deposit)
|
|
detect_columns=["Date", "Description", "Amount", "Split", "Tags"],
|
|
),
|
|
BankProfile(
|
|
id="fidelity",
|
|
name="Fidelity",
|
|
account_type="BANK",
|
|
strategy="A",
|
|
date_column="Run Date",
|
|
description_column="Description",
|
|
amount_column="Amount($)",
|
|
invert_amount_sign=True, # negative = DEBIT (purchase/withdrawal), positive = CREDIT
|
|
detect_columns=["Run Date", "Description", "Amount($)"],
|
|
),
|
|
]
|
|
|
|
|
|
def detect_profile(headers: list[str]) -> Optional[BankProfile]:
|
|
header_set = {h.strip() for h in headers}
|
|
for profile in BANK_PROFILES:
|
|
if all(col in header_set for col in profile.detect_columns):
|
|
return profile
|
|
return None
|