Update the export operation

to work with the Manager.
Also removes the run method from the runnable.py, since everything is
done in the __main__.py file of the pfbudget module.
This commit is contained in:
Luís Murta 2023-01-08 17:35:48 +00:00
parent 9500e808de
commit 9b45ee4817
Signed by: satprog
GPG Key ID: 169EF1BBD7049F94
10 changed files with 79 additions and 36 deletions

View File

@ -251,4 +251,12 @@ if __name__ == "__main__":
pfbudget.types.Link(args["original"][0], link) for link in args["links"]
]
pfbudget.Manager(db, verbosity, args).action(op, params)
case pfbudget.Operation.Export:
assert args.keys() >= {"interval", "start", "end", "year", "all", "banks", "file"}
start, end = pfbudget.parse_args_period(args)
params = [start, end]
if not args["all"]:
params.append(args["banks"])
params.append(args["file"][0])
pfbudget.Manager(db, verbosity).action(op, params)

View File

@ -1,4 +1,3 @@
from pathlib import Path
import argparse
import datetime as dt
import decimal
@ -6,7 +5,6 @@ import re
from pfbudget.common.types import Operation
from pfbudget.db.model import AccountType, Period
from pfbudget.input.nordigen import NordigenInput
from pfbudget.db.sqlite import DatabaseClient
import pfbudget.reporting.graph
import pfbudget.reporting.report
@ -29,7 +27,6 @@ class DataFileMissing(Exception):
def argparser() -> argparse.ArgumentParser:
universal = argparse.ArgumentParser(add_help=False)
universal.add_argument(
"-db",
@ -75,16 +72,13 @@ def argparser() -> argparse.ArgumentParser:
)
p_init.set_defaults(command=Operation.Init)
"""
Exporting
"""
p_export = subparsers.add_parser(
"export",
description="Exports the selected database to a .csv file",
parents=[universal],
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
p_export.set_defaults(func=lambda args: DatabaseClient(args.database).export())
# Exports transactions to .csv file
export = subparsers.add_parser("export", parents=[period])
export.set_defaults(op=Operation.Export)
export.add_argument("file", nargs=1, type=str)
export_banks = export.add_mutually_exclusive_group()
export_banks.add_argument("--all", action="store_true")
export_banks.add_argument("--banks", nargs="+", type=str)
# Parse from .csv
parse = subparsers.add_parser("parse")
@ -403,9 +397,3 @@ def link(parser: argparse.ArgumentParser):
dismantle.set_defaults(op=Operation.Dismantle)
dismantle.add_argument("original", nargs=1, type=int)
dismantle.add_argument("links", nargs="+", type=int)
def run():
args = vars(argparser().parse_args())
assert "op" in args, "No operation selected"
return args["op"], args

View File

@ -33,6 +33,7 @@ class Operation(Enum):
NordigenAdd = auto()
NordigenMod = auto()
NordigenDel = auto()
Export = auto()
class TransactionError(Exception):

View File

@ -1,8 +1,7 @@
from pathlib import Path
from pfbudget.input.input import Input
from pfbudget.input.nordigen import NordigenInput
from pfbudget.input.parsers import parse_data
from pfbudget.common.types import Operation
from pfbudget.core.categorizer import Categorizer
from pfbudget.db.client import DbClient
from pfbudget.db.model import (
Bank,
@ -15,15 +14,14 @@ from pfbudget.db.model import (
Tag,
TagRule,
)
from pfbudget.common.types import Operation
from pfbudget.core.categorizer import Categorizer
from pfbudget.utils import convert
from pfbudget.input.nordigen import NordigenInput
from pfbudget.input.parsers import parse_data
from pfbudget.output.csv import CSV
from pfbudget.output.output import Output
class Manager:
def __init__(self, db: str, verbosity: int = 0, args: dict = {}):
self._args = args
def __init__(self, db: str, verbosity: int = 0):
self._db = db
self._verbosity = verbosity
@ -143,6 +141,19 @@ class Manager:
links = [link.link for link in params]
session.remove_links(original, links)
case Operation.Export:
with self.db.session() as session:
if len(params) < 4:
banks = [bank.name for bank in session.banks()]
transactions = session.transactions(params[0], params[1], banks)
else:
transactions = session.transactions(
params[0], params[1], params[2]
)
csvwriter: Output = CSV(params[-1])
csvwriter.report(transactions)
# def init(self):
# client = DatabaseClient(self.__db)
# client.init()
@ -176,12 +187,8 @@ class Manager:
@property
def db(self) -> DbClient:
return DbClient(self._db, self._verbosity > 0)
return DbClient(self._db, self._verbosity > 2)
@db.setter
def db(self, url: str):
self._db = url
@property
def args(self) -> dict:
return self._args

View File

@ -1,4 +1,5 @@
from dataclasses import asdict
from datetime import date
from sqlalchemy import create_engine, delete, select, update
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.orm import Session, joinedload, selectinload
@ -128,6 +129,14 @@ class DbClient:
stmt = select(Transaction).where(~Transaction.category.has())
return self.__session.scalars(stmt).all()
def transactions(self, min: date, max: date, banks: list[str]):
stmt = select(Transaction).where(
Transaction.date >= min,
Transaction.date <= max,
Transaction.bank.in_(banks),
)
return self.__session.scalars(stmt).all()
def categories(self) -> list[Category]:
stmt = select(Category)
return self.__session.scalars(stmt).all()
@ -136,5 +145,9 @@ class DbClient:
stmt = select(Tag)
return self.__session.scalars(stmt).all()
def banks(self) -> list[Bank]:
stmt = select(Bank)
return self.__session.scalars(stmt).all()
def session(self) -> ClientSession:
return self.ClientSession(self.engine)

View File

@ -6,4 +6,4 @@ from pfbudget.db.model import Transaction
class Input(ABC):
@abstractmethod
def parse(self) -> list[Transaction]:
return NotImplemented
return NotImplementedError

View File

@ -0,0 +1 @@
__all__ = ["csv", "output"]

17
pfbudget/output/csv.py Normal file
View File

@ -0,0 +1,17 @@
from csv import writer
from pfbudget.db.model import Transaction
from .output import Output
class CSV(Output):
def __init__(self, filename: str):
self.fn = filename
def report(self, transactions: list[Transaction]):
with open(self.fn, "w", newline="") as f:
w = writer(f, delimiter="\t")
w.writerows(
[(t.date, t.description, t.amount, t.bank) for t in transactions]
)

View File

@ -0,0 +1,9 @@
from abc import ABC, abstractmethod
from pfbudget.db.model import Transaction
class Output(ABC):
@abstractmethod
def report(self, transactions: list[Transaction]):
raise NotImplementedError

View File

@ -61,7 +61,6 @@ def find_credit_institution(fn, banks, creditcards):
def parse_args_period(args: dict):
start, end = date.min, date.max
print(args)
if args["start"]:
start = datetime.strptime(args["start"][0], "%Y/%m/%d").date()