add outflows from investment to cash flow statement report

This commit is contained in:
Roger Oriol
2023-12-27 12:10:09 +01:00
parent c1e103010d
commit fe8e87ad0e
2 changed files with 32 additions and 11 deletions

View File

@@ -5,7 +5,7 @@ from beancount.parser import printer
import argparse import argparse
from tabulate import tabulate from tabulate import tabulate
from decimal import Decimal from decimal import Decimal
from beancount.core.amount import Amount, sub, mul from beancount.core.amount import Amount, add, sub, mul
from datetime import date from datetime import date
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@@ -55,17 +55,26 @@ def get_total_inflows(income):
else: else:
return Amount(Decimal(0), "EUR") return Amount(Decimal(0), "EUR")
def get_total_outflows(expenses): def get_total_outflows(expenses, total_investments):
sum = 0 sum = 0
for account, balance in expenses.items(): for account, balance in expenses.items():
sum = balance if sum == 0 else sum + balance sum = balance if sum == 0 else sum + balance
if sum != 0 and sum.get_only_position() != None: if sum != 0 and sum.get_only_position() != None:
result = sum.get_only_position().units result = sum.get_only_position().units
return Amount(Decimal(round(result.number, 2)), result.currency) return add(Amount(Decimal(round(result.number, 2)), result.currency), total_investments)
else:
return total_investments
def get_total_investments(investments):
sum = 0
for inv in investments:
sum = inv.cost_position if sum == 0 else sum + inv.cost_position
if sum != 0 and sum != None:
return Amount(Decimal(round(sum.number, 2)), sum.currency)
else: else:
return Amount(Decimal(0), "EUR") return Amount(Decimal(0), "EUR")
def print_report(start_date, period, income, expenses): def print_report(start_date, period, income, expenses, investments):
print(f"{bcolors.BOLD}Cash Flow Statement (period={period}, start_date={start_date}){bcolors.ENDC}") print(f"{bcolors.BOLD}Cash Flow Statement (period={period}, start_date={start_date}){bcolors.ENDC}")
draw_line() draw_line()
print(f"{bcolors.BOLD}Inflows{bcolors.ENDC}") print(f"{bcolors.BOLD}Inflows{bcolors.ENDC}")
@@ -95,11 +104,16 @@ def print_report(start_date, period, income, expenses):
draw_line() draw_line()
print(f"{bcolors.BOLD}Outflows{bcolors.ENDC}") print(f"{bcolors.BOLD}Outflows{bcolors.ENDC}")
print_expenses_table(expenses) print_expenses_table(expenses)
print(f"{bcolors.BOLD}Outflows from Investment{bcolors.ENDC}")
total_investments = get_total_investments(investments)
print(tabulate([ print(tabulate([
["Total Outflows", f"{bcolors.BOLD}{get_total_outflows(expenses).to_string()}{bcolors.ENDC}"] ["Compra de fons i accions", total_investments.to_string()]
]))
print(tabulate([
["Total Outflows", f"{bcolors.BOLD}{get_total_outflows(expenses, total_investments).to_string()}{bcolors.ENDC}"]
])) ]))
draw_line() draw_line()
net_cash_flow = sub(get_total_inflows(income), get_total_outflows(expenses)) net_cash_flow = sub(get_total_inflows(income), get_total_outflows(expenses, total_investments))
print(tabulate([ print(tabulate([
["NET CASH FLOW", f"{bcolors.BOLD}{bcolors.OKGREEN if net_cash_flow.number >= 0 else bcolors.FAIL}{net_cash_flow.to_string()}{bcolors.ENDC}"] ["NET CASH FLOW", f"{bcolors.BOLD}{bcolors.OKGREEN if net_cash_flow.number >= 0 else bcolors.FAIL}{net_cash_flow.to_string()}{bcolors.ENDC}"]
])) ]))
@@ -126,6 +140,14 @@ def get_expenses(entries, options, period, start_date):
expenses[row.account] = row.sum_position expenses[row.account] = row.sum_position
return expenses return expenses
def get_investments(entries, options, period, start_date):
period_delta = relativedelta(months=1) if period == "monthly" else relativedelta(years=1)
end_date = date.fromisoformat(start_date) + period_delta
expenses_query = f"SELECT account, cost(position), currency, date WHERE account ~ \"Assets:Invest:R4:\" AND NOT currency ~ '^(EUR|USD)' AND date >= {start_date} AND date < {end_date.isoformat()}"
rtypes, rrows = query.run_query(
entries, options, expenses_query)
return rrows
def main(): def main():
parser = argparse.ArgumentParser(description='Generate cash flow report') parser = argparse.ArgumentParser(description='Generate cash flow report')
parser.add_argument('start_date', metavar='start_date', type=str, nargs=1, parser.add_argument('start_date', metavar='start_date', type=str, nargs=1,
@@ -145,6 +167,7 @@ def main():
income = get_income(entries, options, period, start_date) income = get_income(entries, options, period, start_date)
expenses = get_expenses(entries, options, period, start_date) expenses = get_expenses(entries, options, period, start_date)
print_report(start_date, period, income, expenses) investments = get_investments(entries, options, period, start_date)
print_report(start_date, period, income, expenses, investments)
main() main()

View File

@@ -46,11 +46,9 @@
2024-01-01 balance Assets:Debt:DeutesPerCobrar 0 EUR 2024-01-01 balance Assets:Debt:DeutesPerCobrar 0 EUR
2024-01-01 * "Zurich" "Cuota gimnàs Andjoy" 2024-01-01 * "Zurich" "Cuota gimnàs Andjoy"
;amortize_months: 12
Expenses:Gimnàs 508.80 EUR Expenses:Gimnàs 508.80 EUR
Income:Work:Zurich:Gimnas Income:Work:Zurich:Gimnas
2024-01-01 * "Zurich" "Cuota seguro salut Cigna Salud OPT (solo cobertura extra hospitalaria)" 2024-01-01 * "Zurich" "Cuota seguro salut Cigna Salud OPT (solo cobertura extra hospitalaria)"
;amortize_months: 12
Expenses:Medic 414.60 EUR Expenses:Medic 414.60 EUR
Income:Work:Zurich:SeguroMedic Income:Work:Zurich:SeguroMedic
2024-01-01 * "Zurich" "Targeta Transport" 2024-01-01 * "Zurich" "Targeta Transport"
@@ -62,14 +60,14 @@
2024-02-01 balance Assets:Liquid:Caixabank:Corrent 18903.80 EUR 2024-02-01 balance Assets:Liquid:Caixabank:Corrent 18903.80 EUR
2024-02-01 balance Assets:Liquid:Caixabank:Estalvi 12666.49 EUR 2024-02-01 balance Assets:Liquid:Caixabank:Estalvi 12666.49 EUR
;2024-02-01 balance Assets:Liquid:R4:EUR 44.04 EUR 2024-02-01 balance Assets:Liquid:R4:EUR 44.04 EUR
2024-02-01 balance Assets:Invest:R4:Amundi:MSCIWRLD 86.005 AMNDMSCIWRLD 2024-02-01 balance Assets:Invest:R4:Amundi:MSCIWRLD 86.005 AMNDMSCIWRLD
2024-02-01 balance Assets:Invest:R4:Vanguard:EMMK 14.99 VANEMMK 2024-02-01 balance Assets:Invest:R4:Vanguard:EMMK 14.99 VANEMMK
2024-02-01 balance Assets:Invest:R4:Fidelity:GLTECH 344.47 FIGLTECH 2024-02-01 balance Assets:Invest:R4:Fidelity:GLTECH 344.47 FIGLTECH
2024-02-01 balance Assets:Invest:R4:Amundi:SUSTINC 11.295 AMNDSUSINC 2024-02-01 balance Assets:Invest:R4:Amundi:SUSTINC 11.295 AMNDSUSINC
2024-02-01 balance Assets:Invest:R4:BNP:DISTECH 0.359 BNPDISTECH 2024-02-01 balance Assets:Invest:R4:BNP:DISTECH 0.359 BNPDISTECH
2024-02-01 balance Assets:Invest:R4:PLTR 10 PLTR 2024-02-01 balance Assets:Invest:R4:PLTR 10 PLTR
;2024-02-01 balance Assets:Invest:R4:MSFT 4 MSFT 2024-02-01 balance Assets:Invest:R4:MSFT 4 MSFT
2024-02-01 balance Assets:Benefits:Edenred:TicketsRestaurant 209 EUR 2024-02-01 balance Assets:Benefits:Edenred:TicketsRestaurant 209 EUR
2024-02-01 balance Assets:Benefits:Edenred:TargetaTransport 40 EUR 2024-02-01 balance Assets:Benefits:Edenred:TargetaTransport 40 EUR
2024-02-01 balance Assets:PersonalProperty:VivendaPrincipal 0 EUR 2024-02-01 balance Assets:PersonalProperty:VivendaPrincipal 0 EUR