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:
parent
9500e808de
commit
9b45ee4817
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -33,6 +33,7 @@ class Operation(Enum):
|
||||
NordigenAdd = auto()
|
||||
NordigenMod = auto()
|
||||
NordigenDel = auto()
|
||||
Export = auto()
|
||||
|
||||
|
||||
class TransactionError(Exception):
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -6,4 +6,4 @@ from pfbudget.db.model import Transaction
|
||||
class Input(ABC):
|
||||
@abstractmethod
|
||||
def parse(self) -> list[Transaction]:
|
||||
return NotImplemented
|
||||
return NotImplementedError
|
||||
|
||||
1
pfbudget/output/__init__.py
Normal file
1
pfbudget/output/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__all__ = ["csv", "output"]
|
||||
17
pfbudget/output/csv.py
Normal file
17
pfbudget/output/csv.py
Normal 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]
|
||||
)
|
||||
9
pfbudget/output/output.py
Normal file
9
pfbudget/output/output.py
Normal 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
|
||||
@ -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()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user