Adds graph date options and report option
Also checks for transactions before loop incase of months without transactions.
This commit is contained in:
parent
ff324ca0a6
commit
647af8be5b
36
main.py
36
main.py
@ -4,6 +4,7 @@ import datetime as dt
|
||||
|
||||
from pfbudget.graph import average, discrete, monthly
|
||||
from pfbudget.transactions import load_transactions, save_transactions
|
||||
import pfbudget.report as report
|
||||
import pfbudget.tools as tools
|
||||
|
||||
|
||||
@ -143,10 +144,31 @@ def status(state, args):
|
||||
|
||||
|
||||
def graph(state, args):
|
||||
start, end = None, None
|
||||
if args.start or args.interval:
|
||||
start = dt.datetime.strptime(args.start[0], "%Y/%m/%d").date()
|
||||
|
||||
if args.end or args.interval:
|
||||
end = dt.datetime.strptime(args.end[0], "%Y/%m/%d").date()
|
||||
|
||||
if args.interval:
|
||||
start = dt.datetime.strptime(args.interval[0], "%Y/%m/%d").date()
|
||||
end = dt.datetime.strptime(args.interval[1], "%Y/%m/%d").date()
|
||||
|
||||
if args.year:
|
||||
start = dt.datetime.strptime(args.year[0], "%Y").date()
|
||||
end = dt.datetime.strptime(
|
||||
str(int(args.year[0]) + 1), "%Y"
|
||||
).date() - dt.timedelta(days=1)
|
||||
|
||||
if args.option == "monthly":
|
||||
monthly(state, args.start, args.end)
|
||||
monthly(state, start, end)
|
||||
elif args.option == "discrete":
|
||||
discrete(state, args.start, args.end)
|
||||
discrete(state, start, end)
|
||||
|
||||
|
||||
def f_report(state, args):
|
||||
report.net(state)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
@ -205,8 +227,13 @@ if __name__ == "__main__":
|
||||
default="monthly",
|
||||
help="graph option help",
|
||||
)
|
||||
p_graph.add_argument("start", type=str, nargs="?", help="graph start date")
|
||||
p_graph.add_argument("end", type=str, nargs="?", help="graph end date")
|
||||
p_graph_interval = p_graph.add_mutually_exclusive_group()
|
||||
p_graph_interval.add_argument(
|
||||
"--interval", type=str, nargs=2, help="graph interval", metavar=("START", "END")
|
||||
)
|
||||
p_graph_interval.add_argument("--start", type=str, nargs=1, help="graph start date")
|
||||
p_graph_interval.add_argument("--end", type=str, nargs=1, help="graph end date")
|
||||
p_graph_interval.add_argument("--year", type=str, nargs=1, help="graph year")
|
||||
|
||||
p_init.set_defaults(func=init)
|
||||
p_restart.set_defaults(func=restart)
|
||||
@ -215,6 +242,7 @@ if __name__ == "__main__":
|
||||
p_vacation.set_defaults(func=vacation)
|
||||
p_status.set_defaults(func=status)
|
||||
p_graph.set_defaults(func=graph)
|
||||
p_report.set_defaults(func=f_report)
|
||||
|
||||
state = tools.pfstate(p)
|
||||
state.filename = p
|
||||
|
||||
@ -148,6 +148,7 @@ def discrete(state, start, end):
|
||||
labels=["Fixed", "Required", "Health", *get_discretionary_expenses()],
|
||||
)
|
||||
plt.legend(loc="upper left")
|
||||
plt.grid()
|
||||
plt.show()
|
||||
|
||||
|
||||
|
||||
85
pfbudget/report.py
Normal file
85
pfbudget/report.py
Normal file
@ -0,0 +1,85 @@
|
||||
from .categories import (
|
||||
get_income_categories,
|
||||
get_fixed_expenses,
|
||||
get_required_expenses,
|
||||
get_health_expenses,
|
||||
get_discretionary_expenses,
|
||||
)
|
||||
from .transactions import (
|
||||
load_transactions,
|
||||
daterange,
|
||||
by_category,
|
||||
by_month,
|
||||
by_month_and_category,
|
||||
by_year_and_category,
|
||||
)
|
||||
|
||||
|
||||
def net(state, start=None, end=None):
|
||||
transactions = load_transactions(state.data_dir)
|
||||
if not start:
|
||||
start = transactions[0].date
|
||||
if not end:
|
||||
end = transactions[-1].date
|
||||
|
||||
income, fixed, required, health, discretionary = [], [], [], [], []
|
||||
yearly_transactions_by_categories = by_year_and_category(transactions, start, end)
|
||||
for _, transactions_by_category in yearly_transactions_by_categories.items():
|
||||
income.append(
|
||||
sum(
|
||||
float(t.value)
|
||||
for category, transactions in transactions_by_category.items()
|
||||
if transactions and category in get_income_categories()
|
||||
for t in transactions
|
||||
)
|
||||
)
|
||||
fixed.append(
|
||||
sum(
|
||||
-float(t.value)
|
||||
for category, transactions in transactions_by_category.items()
|
||||
if transactions and category in get_fixed_expenses()
|
||||
for t in transactions
|
||||
)
|
||||
)
|
||||
required.append(
|
||||
sum(
|
||||
-float(t.value)
|
||||
for category, transactions in transactions_by_category.items()
|
||||
if transactions and category in get_required_expenses()
|
||||
for t in transactions
|
||||
)
|
||||
)
|
||||
health.append(
|
||||
sum(
|
||||
-float(t.value)
|
||||
for category, transactions in transactions_by_category.items()
|
||||
if transactions and category in get_health_expenses()
|
||||
for t in transactions
|
||||
)
|
||||
)
|
||||
discretionary.append(
|
||||
sum(
|
||||
-float(t.value)
|
||||
for category, transactions in transactions_by_category.items()
|
||||
if transactions and category in get_discretionary_expenses()
|
||||
for t in transactions
|
||||
)
|
||||
)
|
||||
|
||||
for i, year in enumerate(yearly_transactions_by_categories.keys()):
|
||||
print(year)
|
||||
print(
|
||||
"Income: {:.2f}, Expenses: {:.2f}, Net: {:.2f}\n"
|
||||
"Fixed Expenses: {:.2f}\n"
|
||||
"Required Expenses: {:.2f}\n"
|
||||
"Health Expenses: {:.2f}\n"
|
||||
"Discretionary Expenses: {:.2f}\n".format(
|
||||
income[i],
|
||||
fixed[i] + required[i] + health[i] + discretionary[i],
|
||||
income[i] - (fixed[i] + required[i] + health[i] + discretionary[i]),
|
||||
fixed[i],
|
||||
required[i],
|
||||
health[i],
|
||||
discretionary[i],
|
||||
)
|
||||
)
|
||||
@ -153,6 +153,8 @@ def by_month(transactions, start=None, end=None) -> dict:
|
||||
|
||||
def by_category(transactions) -> dict:
|
||||
transactions_by_category = dict.fromkeys(get_categories(), None)
|
||||
|
||||
if transactions:
|
||||
for transaction in transactions:
|
||||
try:
|
||||
transactions_by_category[transaction.category].append(transaction)
|
||||
@ -162,6 +164,16 @@ def by_category(transactions) -> dict:
|
||||
return transactions_by_category
|
||||
|
||||
|
||||
def by_year_and_category(transactions, start, end) -> dict:
|
||||
yearly_transactions_by_category = {}
|
||||
|
||||
yearly_transactions = by_year(transactions, start, end)
|
||||
for year, transactions in yearly_transactions.items():
|
||||
yearly_transactions_by_category[year] = by_category(transactions)
|
||||
|
||||
return yearly_transactions_by_category
|
||||
|
||||
|
||||
def by_month_and_category(transactions, start, end) -> dict:
|
||||
monthly_transactions_by_categories = {}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user