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.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 argparse
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
import decimal
|
import decimal
|
||||||
@ -6,7 +5,6 @@ import re
|
|||||||
|
|
||||||
from pfbudget.common.types import Operation
|
from pfbudget.common.types import Operation
|
||||||
from pfbudget.db.model import AccountType, Period
|
from pfbudget.db.model import AccountType, Period
|
||||||
from pfbudget.input.nordigen import NordigenInput
|
|
||||||
from pfbudget.db.sqlite import DatabaseClient
|
from pfbudget.db.sqlite import DatabaseClient
|
||||||
import pfbudget.reporting.graph
|
import pfbudget.reporting.graph
|
||||||
import pfbudget.reporting.report
|
import pfbudget.reporting.report
|
||||||
@ -29,7 +27,6 @@ class DataFileMissing(Exception):
|
|||||||
|
|
||||||
|
|
||||||
def argparser() -> argparse.ArgumentParser:
|
def argparser() -> argparse.ArgumentParser:
|
||||||
|
|
||||||
universal = argparse.ArgumentParser(add_help=False)
|
universal = argparse.ArgumentParser(add_help=False)
|
||||||
universal.add_argument(
|
universal.add_argument(
|
||||||
"-db",
|
"-db",
|
||||||
@ -75,16 +72,13 @@ def argparser() -> argparse.ArgumentParser:
|
|||||||
)
|
)
|
||||||
p_init.set_defaults(command=Operation.Init)
|
p_init.set_defaults(command=Operation.Init)
|
||||||
|
|
||||||
"""
|
# Exports transactions to .csv file
|
||||||
Exporting
|
export = subparsers.add_parser("export", parents=[period])
|
||||||
"""
|
export.set_defaults(op=Operation.Export)
|
||||||
p_export = subparsers.add_parser(
|
export.add_argument("file", nargs=1, type=str)
|
||||||
"export",
|
export_banks = export.add_mutually_exclusive_group()
|
||||||
description="Exports the selected database to a .csv file",
|
export_banks.add_argument("--all", action="store_true")
|
||||||
parents=[universal],
|
export_banks.add_argument("--banks", nargs="+", type=str)
|
||||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
||||||
)
|
|
||||||
p_export.set_defaults(func=lambda args: DatabaseClient(args.database).export())
|
|
||||||
|
|
||||||
# Parse from .csv
|
# Parse from .csv
|
||||||
parse = subparsers.add_parser("parse")
|
parse = subparsers.add_parser("parse")
|
||||||
@ -403,9 +397,3 @@ def link(parser: argparse.ArgumentParser):
|
|||||||
dismantle.set_defaults(op=Operation.Dismantle)
|
dismantle.set_defaults(op=Operation.Dismantle)
|
||||||
dismantle.add_argument("original", nargs=1, type=int)
|
dismantle.add_argument("original", nargs=1, type=int)
|
||||||
dismantle.add_argument("links", nargs="+", 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()
|
NordigenAdd = auto()
|
||||||
NordigenMod = auto()
|
NordigenMod = auto()
|
||||||
NordigenDel = auto()
|
NordigenDel = auto()
|
||||||
|
Export = auto()
|
||||||
|
|
||||||
|
|
||||||
class TransactionError(Exception):
|
class TransactionError(Exception):
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from pfbudget.input.input import Input
|
from pfbudget.common.types import Operation
|
||||||
from pfbudget.input.nordigen import NordigenInput
|
from pfbudget.core.categorizer import Categorizer
|
||||||
from pfbudget.input.parsers import parse_data
|
|
||||||
from pfbudget.db.client import DbClient
|
from pfbudget.db.client import DbClient
|
||||||
from pfbudget.db.model import (
|
from pfbudget.db.model import (
|
||||||
Bank,
|
Bank,
|
||||||
@ -15,15 +14,14 @@ from pfbudget.db.model import (
|
|||||||
Tag,
|
Tag,
|
||||||
TagRule,
|
TagRule,
|
||||||
)
|
)
|
||||||
from pfbudget.common.types import Operation
|
from pfbudget.input.nordigen import NordigenInput
|
||||||
from pfbudget.core.categorizer import Categorizer
|
from pfbudget.input.parsers import parse_data
|
||||||
from pfbudget.utils import convert
|
from pfbudget.output.csv import CSV
|
||||||
|
from pfbudget.output.output import Output
|
||||||
|
|
||||||
|
|
||||||
class Manager:
|
class Manager:
|
||||||
def __init__(self, db: str, verbosity: int = 0, args: dict = {}):
|
def __init__(self, db: str, verbosity: int = 0):
|
||||||
self._args = args
|
|
||||||
|
|
||||||
self._db = db
|
self._db = db
|
||||||
self._verbosity = verbosity
|
self._verbosity = verbosity
|
||||||
|
|
||||||
@ -143,6 +141,19 @@ class Manager:
|
|||||||
links = [link.link for link in params]
|
links = [link.link for link in params]
|
||||||
session.remove_links(original, links)
|
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):
|
# def init(self):
|
||||||
# client = DatabaseClient(self.__db)
|
# client = DatabaseClient(self.__db)
|
||||||
# client.init()
|
# client.init()
|
||||||
@ -176,12 +187,8 @@ class Manager:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def db(self) -> DbClient:
|
def db(self) -> DbClient:
|
||||||
return DbClient(self._db, self._verbosity > 0)
|
return DbClient(self._db, self._verbosity > 2)
|
||||||
|
|
||||||
@db.setter
|
@db.setter
|
||||||
def db(self, url: str):
|
def db(self, url: str):
|
||||||
self._db = url
|
self._db = url
|
||||||
|
|
||||||
@property
|
|
||||||
def args(self) -> dict:
|
|
||||||
return self._args
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
from dataclasses import asdict
|
from dataclasses import asdict
|
||||||
|
from datetime import date
|
||||||
from sqlalchemy import create_engine, delete, select, update
|
from sqlalchemy import create_engine, delete, select, update
|
||||||
from sqlalchemy.dialects.postgresql import insert
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
from sqlalchemy.orm import Session, joinedload, selectinload
|
from sqlalchemy.orm import Session, joinedload, selectinload
|
||||||
@ -128,6 +129,14 @@ class DbClient:
|
|||||||
stmt = select(Transaction).where(~Transaction.category.has())
|
stmt = select(Transaction).where(~Transaction.category.has())
|
||||||
return self.__session.scalars(stmt).all()
|
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]:
|
def categories(self) -> list[Category]:
|
||||||
stmt = select(Category)
|
stmt = select(Category)
|
||||||
return self.__session.scalars(stmt).all()
|
return self.__session.scalars(stmt).all()
|
||||||
@ -136,5 +145,9 @@ class DbClient:
|
|||||||
stmt = select(Tag)
|
stmt = select(Tag)
|
||||||
return self.__session.scalars(stmt).all()
|
return self.__session.scalars(stmt).all()
|
||||||
|
|
||||||
|
def banks(self) -> list[Bank]:
|
||||||
|
stmt = select(Bank)
|
||||||
|
return self.__session.scalars(stmt).all()
|
||||||
|
|
||||||
def session(self) -> ClientSession:
|
def session(self) -> ClientSession:
|
||||||
return self.ClientSession(self.engine)
|
return self.ClientSession(self.engine)
|
||||||
|
|||||||
@ -6,4 +6,4 @@ from pfbudget.db.model import Transaction
|
|||||||
class Input(ABC):
|
class Input(ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def parse(self) -> list[Transaction]:
|
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):
|
def parse_args_period(args: dict):
|
||||||
start, end = date.min, date.max
|
start, end = date.min, date.max
|
||||||
print(args)
|
|
||||||
if args["start"]:
|
if args["start"]:
|
||||||
start = datetime.strptime(args["start"][0], "%Y/%m/%d").date()
|
start = datetime.strptime(args["start"][0], "%Y/%m/%d").date()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user