add outflows from investment to cash flow statement report
This commit is contained in:
@@ -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()
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user