Fix converters

Python's single dispatch can´t use type aliases and lists of classes.
All converters now work on a class, and lists need to be generated
inplace and call the converter for each item.

Adds the bank class both to the DB schema and the common types.
This commit is contained in:
Luís Murta 2022-10-09 17:24:42 +01:00
parent e2f731a961
commit cfcc182f35
Signed by: satprog
GPG Key ID: 169EF1BBD7049F94
3 changed files with 75 additions and 27 deletions

View File

@ -1,7 +1,7 @@
from dataclasses import dataclass
from datetime import date from datetime import date
from decimal import Decimal, InvalidOperation from decimal import Decimal, InvalidOperation
from enum import Enum, auto
COMMENT_TOKEN = "#"
class TransactionError(Exception): class TransactionError(Exception):
@ -104,3 +104,25 @@ class Transaction:
Transactions = list[Transaction] Transactions = list[Transaction]
class PrimaryKey(Enum):
ID = auto()
NAME = auto()
BIC = auto()
@dataclass
class Bank:
name: str
bic: str
requisition_id: str
invert: bool
key: PrimaryKey = PrimaryKey.ID
Banks = list[Bank]
class NoBankSelected(Exception):
pass

View File

@ -1,3 +1,4 @@
from dataclasses import dataclass
from decimal import Decimal from decimal import Decimal
CREATE_TRANSACTIONS_TABLE = """ CREATE_TRANSACTIONS_TABLE = """
@ -12,7 +13,18 @@ CREATE TABLE IF NOT EXISTS "transactions" (
); );
""" """
DbTransaction = tuple[str, str | None, str, Decimal, str | None, str | None, str | None]
@dataclass
class DbTransaction:
date: str
description: str
bank: str
value: Decimal
category: str
original: str
comments: str
DbTransactions = list[DbTransaction] DbTransactions = list[DbTransaction]
CREATE_BACKUPS_TABLE = """ CREATE_BACKUPS_TABLE = """
@ -25,13 +37,27 @@ CREATE TABLE IF NOT EXISTS backups (
CREATE_BANKS_TABLE = """ CREATE_BANKS_TABLE = """
CREATE TABLE IF NOT EXISTS banks ( CREATE TABLE IF NOT EXISTS banks (
name TEXT NOT NULL PRIMARY KEY, name TEXT NOT NULL PRIMARY KEY,
requisition TEXT, bic TEXT,
invert INTEGER, nordigen_id TEXT,
description TEXT nordigen_name TEXT,
requisition_id TEXT,
invert INTEGER
) )
""" """
Bank = tuple[str, str, bool]
@dataclass
class DbBank:
name: str
bic: str
nordigen_id: str
nordigen_name: str
requisition_id: str
invert: bool
DbBanks = list[DbBank]
ADD_TRANSACTION = """ ADD_TRANSACTION = """
INSERT INTO transactions (date, description, bank, value, category) values (?,?,?,?,?) INSERT INTO transactions (date, description, bank, value, category) values (?,?,?,?,?)

View File

@ -1,11 +1,13 @@
from functools import singledispatch from functools import singledispatch
from pfbudget.common.types import Transaction, Transactions, TransactionError from pfbudget.common.types import Bank, Transaction, TransactionError
from pfbudget.db.schema import DbTransaction, DbTransactions from pfbudget.db.schema import DbBank, DbTransaction
from .utils import parse_decimal
@singledispatch @singledispatch
def convert(t): def convert(t):
print("No converter as been found")
pass pass
@ -14,31 +16,29 @@ def _(t: Transaction) -> DbTransaction:
return (t.date, t.description, t.bank, t.value, t.category) return (t.date, t.description, t.bank, t.value, t.category)
def convert_dbtransaction(db) -> Transaction: @convert.register
def _(db: DbTransaction) -> Transaction:
try: try:
return Transaction(db) return Transaction(db)
except TransactionError: except TransactionError:
print(f"{db} is in the wrong format") print(f"{db} is in the wrong format")
convert.register(type(DbTransaction), convert_dbtransaction) @convert.register
def _(db: DbBank, key: str = "") -> Bank:
bank = Bank(db.name, db.bic, db.requisition_id, db.invert, key=key)
return bank
def convert_transactions(ts: Transactions) -> DbTransactions: @convert.register
def _(json: dict, bank: str, invert: bool) -> Transaction:
i = -1 if invert else 1
try: try:
return [convert(t) for t in ts] return Transaction(
json["bookingDate"],
json["remittanceInformationUnstructured"],
bank,
i * parse_decimal(json["transactionAmount"]["amount"]),
)
except TransactionError: except TransactionError:
print(f"{ts} is in the wrong format") print(f"{json} is in the wrong format")
convert.register(type(Transactions), convert_transactions)
def convert_dbtransactions(ts: DbTransactions) -> Transactions:
try:
return [convert(t) for t in ts]
except TransactionError:
print(f"{ts} is in the wrong format")
convert.register(type(DbTransactions), convert_dbtransactions)