diff --git a/pfbudget/report.py b/pfbudget/report.py index fbecd35..d58e605 100644 --- a/pfbudget/report.py +++ b/pfbudget/report.py @@ -55,9 +55,83 @@ def net(db: DBManager, start: dt.date = dt.date.min, end: dt.date = dt.date.max) print(f"\nNet total: {income-expenses:.2f} €") if income != 0: print( - f"Total expenses are {expenses:.2f} ({expenses/income*100:.1f}% of income)\n" + f"Total expenses are {expenses:.2f} € ({expenses/income*100:.1f}% of income)\n" ) else: - print(f"Total expenses are {expenses:.2f}. No income this year!\n") + print(f"Total expenses are {expenses:.2f} €. No income this year!\n") + + print(f"Invested: {investments:.2f}€\n") + +def detailed(db: DBManager, start: dt.date = dt.date.min, end: dt.date = dt.date.max): + transactions = db.get_daterange(start, end) + start, end = transactions[0].date, transactions[-1].date + + yearly_transactions: tuple[int, dict[str, float]] = tuple( + ( + year.year, + { + category: sum( + transaction.value + for transaction in transactions + if transaction.category == category + and year <= transaction.date <= year.replace(month=12, day=31) + ) + for category in pfbudget.categories.categories + }, + ) + for year in [ + year.date() + for year in rrule( + YEARLY, dtstart=start.replace(day=1), until=end.replace(day=1) + ) + ] + ) + + for year, categories in yearly_transactions: + print(f"\n{year}\n") + + income = sum( + sum + for category, sum in categories.items() + if category in pfbudget.categories.groups["income-fixed"] + or category in pfbudget.categories.groups["income-extra"] + ) + print(f"Income: {income:.2f}€\n") + + investments = -sum( + sum + for category, sum in categories.items() + if category in pfbudget.categories.groups["investment"] + ) + + expenses = 0 + for category, value in categories.items(): + if ( + category not in pfbudget.categories.groups["income-fixed"] + and category not in pfbudget.categories.groups["income-extra"] + and category not in pfbudget.categories.groups["investment"] + ): + if category == "Null": + if value != 0: + print(f"Null: {value} != 0€") + continue + expenses -= value + + if income != 0: + print( + f"{category.capitalize()} expenses: {-value:.2f} € ({-value/income*100:.1f}%)" + ) + else: + print(f"{category.capitalize()} expenses: {-value:.2f} €") + if income != 0: + print( + f"\nNet total: {income-expenses:.2f} € ({(income-expenses)/income*100:.1f}% of income)" + ) + print( + f"Total expenses are {expenses:.2f} € ({expenses/income*100:.1f}% of income)\n" + ) + else: + print(f"\nNet total: {income-expenses:.2f} €") + print(f"Total expenses are {expenses:.2f} €. No income this year!\n") print(f"Invested: {investments:.2f}€\n") diff --git a/pfbudget/runnable.py b/pfbudget/runnable.py index d1404d5..365f9f3 100644 --- a/pfbudget/runnable.py +++ b/pfbudget/runnable.py @@ -140,6 +140,14 @@ def argparser() -> argparse.ArgumentParser: parents=[help, period], formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) + p_report.add_argument( + "option", + type=str, + choices=["net", "detailed"], + nargs="?", + default="net", + help="report option help", + ) p_report.set_defaults(func=report) return parser @@ -184,7 +192,10 @@ def report(args): args (dict): argparse variables """ start, end = pfbudget.utils.parse_args_period(args) - pfbudget.report.net(DBManager(args.database), start, end) + if args.option == "net": + pfbudget.report.net(DBManager(args.database), start, end) + elif args.option == "detailed": + pfbudget.report.detailed(DBManager(args.database), start, end) def run():