now allows downloading, defaults include health care and better leave calc. This is probably good enough now, so I have also saved a snapshot/csv of the data

This commit is contained in:
2025-01-31 20:07:40 +11:00
parent ae867d8fac
commit c2886faa30
7 changed files with 90 additions and 17 deletions

6
README
View File

@@ -1,7 +1,5 @@
NEED to confirm car future TODO:
* need to consider whether we pay GMHBA / HCF at what cadence and include it in calcs better
ALLOW SAVE / export, so I can compare this when we get a chance :)
to run: to run:

View File

@@ -24,10 +24,11 @@ def calculate_savings_depletion(finance):
TLS_price = finance['TLS_price'] TLS_price = finance['TLS_price']
CBA_price = finance['CBA_price'] CBA_price = finance['CBA_price']
# leave in days, 10 business days to a fortnight, salary is per fortnight, and we lose 37% to tax # leave in days, 10 business days to a fortnight,
# (assuming we don't earn over $180k) # paid before tax I earn $7830.42 / fortnight. Tax on that will be at 37% or $4933.16 after tax
# if we could stretch this to July 2026, then would be more (due to less tax) # if we could stretch this to July 2026, then would be more (due to less tax)
D_leave_after_tax = (D_leave_owed_in_days/10) * D_Salary; after_tax_extra_leave_per_fortnight = 4933.16
D_leave_after_tax = (D_leave_owed_in_days/10) * after_tax_extra_leave_per_fortnight;
# Constants for interest calculations # Constants for interest calculations
annual_interest_rate = Interest_Rate / 100.0 annual_interest_rate = Interest_Rate / 100.0

12
db.py
View File

@@ -41,7 +41,7 @@ def init_db():
cur.execute('''INSERT INTO finance (D_Salary, D_Num_fortnights_pay, School_Fees, Car_loan_via_pay, Car_loan, Car_balloon, Living_Expenses, Savings, Interest_Rate, cur.execute('''INSERT INTO finance (D_Salary, D_Num_fortnights_pay, School_Fees, Car_loan_via_pay, Car_loan, Car_balloon, Living_Expenses, Savings, Interest_Rate,
Inflation, Mich_present, Overseas_trip, Mark_reno, D_leave_owed_in_days, D_TLS_shares, M_TLS_shares, D_CBA_shares, TLS_price, CBA_price, Overseas_trip_date, Mark_reno_date, Sell_shares) Inflation, Mich_present, Overseas_trip, Mark_reno, D_leave_owed_in_days, D_TLS_shares, M_TLS_shares, D_CBA_shares, TLS_price, CBA_price, Overseas_trip_date, Mark_reno_date, Sell_shares)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
(4762.29, 6, 22000, 620, 1001.12, 45824.68, 78000, 412000, 5.0, 3.9, 10000, 32000, 10000, 90.6, 1000, 750, 1095, 3.99, 160.61, '2025-06-01', '2025-09-01', 5)) (4762.29, 6, 22000, 620, 1001.12, 45824.68, 83000, 412000, 5.0, 3.9, 10000, 32000, 10000, 90.6, 1000, 750, 1095, 3.99, 160.61, '2025-06-01', '2025-09-01', 6))
# NOTE: 1001.12 car-pay -- is 1017.99 (actual rate) - 16.87 (car park) # NOTE: 1001.12 car-pay -- is 1017.99 (actual rate) - 16.87 (car park)
# NOTE: o/s trip. ~ $4kpp flights x3, then ~$3k / week in barcelona accom, $100pp/pd for food ($2k), + spending money # NOTE: o/s trip. ~ $4kpp flights x3, then ~$3k / week in barcelona accom, $100pp/pd for food ($2k), + spending money
conn.commit() conn.commit()
@@ -55,6 +55,16 @@ def get_finance_data():
conn.close() conn.close()
return dict(finance) return dict(finance)
def get_budget_data(finance_data, CBA, TLS):
# annual bills - health ins (5k), rates (2.4), electricity (1.5), gas (2), internet (1.6), car insurance (.7), rego (.8), house insurance (2.4), GFC (2.2), phones (.5), melb. pollen (.03), nabu casa (.1), eweka (.1) --- noting phone is elevated presuming I also go onto Aldi plan, but that there is no family discount
bills = 19330
BUDGET=[]
BUDGET.append( ('Bills', f"${bills:,.2f}") )
BUDGET.append( ('Buffer', f"${CBA*finance_data['CBA_price']+TLS*finance_data['TLS_price']:,.2f}") )
BUDGET.append( ('Monthly budget', f"${((finance_data['Living_Expenses']-12000) / 12):,.2f}" ) )
BUDGET.append( ('Weekly budget', f"${((finance_data['Living_Expenses']-12000) / 52):,.2f}" ) )
return BUDGET
def update_finance(data): def update_finance(data):
conn = connect_db() conn = connect_db()

Binary file not shown.

View File

@@ -0,0 +1,29 @@
2025-Date,2025-Value,2026-Date,2026-Value,2027-Date,2027-Value,2028-Date,2028-Value,2029-Date,2029-Value,2030-Date,2030-Value,2031-Date,2031-Value
2025-02-05,414887.73,2026-01-07,374779.5,2027-01-06,262498.3,2028-01-05,219760.58,2029-01-03,171153.2,2030-01-02,116169.68,2031-01-01,32136.61,,Bills,"$19,330.00",,Variable,Value
2025-02-19,415836.12,2026-01-21,370468.42,2027-01-20,259056.92,2028-01-19,216182.55,2029-01-17,167433.11,2030-01-16,112301.89,2031-01-15,28269.95,,Buffer,$0.00,,D_Salary,4762.29
2025-03-05,418367.1,2026-02-04,367735.83,2027-02-03,256717.17,2028-02-02,213523.9,2029-01-31,163713.02,2030-01-30,108434.09,2031-01-29,24248.59,,Monthly
budget,"$5,916.67",,D_Num_fortnights_pay,6
2025-03-19,419305.1,2026-02-18,363413.99,2027-02-17,253264.6,2028-02-16,209934.25,2029-02-14,160692.72,2030-02-13,105031.25,2031-02-12,20334.57,,Weekly
budget,"$1,365.38",,School_Fees,22000
2025-04-02,422012.43,2026-03-04,360488.77,2027-03-03,250783.27,2028-03-01,206344.6,2029-02-28,156960.54,2030-02-27,101150.88,2031-02-26,16300.14,,,,,Car_loan_via_pay,620
2025-04-16,467253.33,2026-03-18,356156.14,2027-03-17,247319.48,2028-03-15,203577.26,2029-03-14,153831.92,2030-03-13,97659.91,2031-03-12,12329.53,,,,,Car_loan,1001.12
2025-04-30,463037.5,2026-04-01,351823.5,2027-03-31,243855.69,2028-03-29,199975.94,2029-03-28,150087.61,2030-03-27,93766.93,2031-03-26,8281.98,,,,,Car_balloon,45824.68
2025-05-14,460631.46,2026-04-15,348996.24,2027-04-14,241431.71,2028-04-12,197227.75,2029-04-11,146984.46,2030-04-10,90275.82,2031-04-09,4273.14,,,,,Living_Expenses,83000
2025-05-28,456405.19,2026-04-29,344652.78,2027-04-28,237956.66,2028-04-26,193614.73,2029-04-25,143227.98,2030-04-24,86370.19,,,,,,,Savings,412000
2025-06-11,422125.83,2026-05-13,341734.41,2027-05-12,235462.37,2028-05-10,190799.91,2029-05-09,140062.51,2030-05-08,82821.76,,,,,,,Interest_Rate,5.0
2025-06-25,417889.08,2026-05-27,337380.09,2027-05-26,231976.03,2028-05-24,187175.14,2029-05-23,136293.82,2030-05-22,78903.44,,,,,,,Inflation,3.9
2025-07-09,451750.54,2026-06-10,334466.85,2027-06-09,229477.84,2028-06-07,184347.87,2029-06-06,133106.4,2030-06-05,75322.5,,,,,,,Mich_present,10000
2025-07-23,447503.27,2026-06-24,330101.63,2027-06-23,225980.16,2028-06-21,180711.33,2029-06-20,129325.47,2030-06-19,71391.44,,,,,,,Overseas_trip,32000
2025-08-06,445162.62,2026-07-08,363397.17,2027-07-07,259710.84,2028-07-05,214116.72,2029-07-04,162375.12,2030-07-03,82530.95,,,,,,,Mark_reno,10000
2025-08-20,440904.8,2026-07-22,359021.02,2027-07-21,256201.8,2028-07-19,210468.35,2029-07-18,158581.9,2030-07-17,78587.12,,,,,,,D_leave_owed_in_days,90.6
2025-09-03,428524.06,2026-08-05,356175.3,2027-08-04,253782.55,2028-08-02,207715.12,2029-08-01,154788.67,2030-07-31,74643.29,,,,,,,D_TLS_shares,1000
2025-09-17,424255.66,2026-08-19,351788.17,2027-08-18,250262.11,2028-08-16,204054.9,2029-08-15,151657.7,2030-08-14,71021.28,,,,,,,M_TLS_shares,750
2025-10-01,419987.25,2026-09-02,348899.23,2027-09-01,246741.66,2028-08-30,200394.68,2029-08-29,147852.15,2030-08-28,67064.63,,,,,,,D_CBA_shares,1095
2025-10-15,417454.7,2026-09-16,344501.1,2027-09-15,244273.6,2028-09-13,197589.68,2029-09-12,144678.6,2030-09-11,63396.8,,,,,,,TLS_price,3.99
2025-10-29,413175.68,2026-09-30,340102.97,2027-09-29,240741.72,2028-09-27,193917.56,2029-09-26,140860.68,2030-09-25,59427.29,,,,,,,CBA_price,160.61
2025-11-12,410660.56,2026-10-14,337111.91,2027-10-13,238202.3,2028-10-11,191045.16,2029-10-10,137624.31,2030-10-09,55704.53,,,,,,,Overseas_trip_date,2025-06-01
2025-11-26,406370.89,2026-10-28,322702.74,2027-10-27,234658.94,2028-10-25,187361.11,2029-10-24,133793.99,2030-10-23,51722.12,,,,,,,Mark_reno_date,2025-09-01
2025-12-10,381758.47,2026-11-11,319692.08,2027-11-10,232115.41,2028-11-08,184475.65,2029-11-07,130534.62,2030-11-06,47961.98,,,,,,,Sell_shares,6
2025-12-24,377458.1,2026-11-25,270448.27,2027-11-24,228560.53,2028-11-22,180779.63,2029-11-21,126691.85,2030-11-20,43966.63,,,,,,
,,2026-12-09,268232.01,2027-12-08,225946.99,2028-12-06,177828.21,2029-12-05,123371.23,2030-12-04,40153.28,,,,,,
,,2026-12-23,264801.78,2027-12-22,222380.56,2028-12-20,174120.17,2029-12-19,119515.97,2030-12-18,36144.95,,,,,,
1 2025-Date 2025-Value 2026-Date 2026-Value 2027-Date 2027-Value 2028-Date 2028-Value 2029-Date 2029-Value 2030-Date 2030-Value 2031-Date 2031-Value
2 2025-02-05 414887.73 2026-01-07 374779.5 2027-01-06 262498.3 2028-01-05 219760.58 2029-01-03 171153.2 2030-01-02 116169.68 2031-01-01 32136.61 Bills $19,330.00 Variable Value
3 2025-02-19 415836.12 2026-01-21 370468.42 2027-01-20 259056.92 2028-01-19 216182.55 2029-01-17 167433.11 2030-01-16 112301.89 2031-01-15 28269.95 Buffer $0.00 D_Salary 4762.29
4 2025-03-05 418367.1 2026-02-04 367735.83 2027-02-03 256717.17 2028-02-02 213523.9 2029-01-31 163713.02 2030-01-30 108434.09 2031-01-29 24248.59 Monthly
5 budget $5,916.67 D_Num_fortnights_pay 6
6 2025-03-19 419305.1 2026-02-18 363413.99 2027-02-17 253264.6 2028-02-16 209934.25 2029-02-14 160692.72 2030-02-13 105031.25 2031-02-12 20334.57 Weekly
7 budget $1,365.38 School_Fees 22000
8 2025-04-02 422012.43 2026-03-04 360488.77 2027-03-03 250783.27 2028-03-01 206344.6 2029-02-28 156960.54 2030-02-27 101150.88 2031-02-26 16300.14 Car_loan_via_pay 620
9 2025-04-16 467253.33 2026-03-18 356156.14 2027-03-17 247319.48 2028-03-15 203577.26 2029-03-14 153831.92 2030-03-13 97659.91 2031-03-12 12329.53 Car_loan 1001.12
10 2025-04-30 463037.5 2026-04-01 351823.5 2027-03-31 243855.69 2028-03-29 199975.94 2029-03-28 150087.61 2030-03-27 93766.93 2031-03-26 8281.98 Car_balloon 45824.68
11 2025-05-14 460631.46 2026-04-15 348996.24 2027-04-14 241431.71 2028-04-12 197227.75 2029-04-11 146984.46 2030-04-10 90275.82 2031-04-09 4273.14 Living_Expenses 83000
12 2025-05-28 456405.19 2026-04-29 344652.78 2027-04-28 237956.66 2028-04-26 193614.73 2029-04-25 143227.98 2030-04-24 86370.19 Savings 412000
13 2025-06-11 422125.83 2026-05-13 341734.41 2027-05-12 235462.37 2028-05-10 190799.91 2029-05-09 140062.51 2030-05-08 82821.76 Interest_Rate 5.0
14 2025-06-25 417889.08 2026-05-27 337380.09 2027-05-26 231976.03 2028-05-24 187175.14 2029-05-23 136293.82 2030-05-22 78903.44 Inflation 3.9
15 2025-07-09 451750.54 2026-06-10 334466.85 2027-06-09 229477.84 2028-06-07 184347.87 2029-06-06 133106.4 2030-06-05 75322.5 Mich_present 10000
16 2025-07-23 447503.27 2026-06-24 330101.63 2027-06-23 225980.16 2028-06-21 180711.33 2029-06-20 129325.47 2030-06-19 71391.44 Overseas_trip 32000
17 2025-08-06 445162.62 2026-07-08 363397.17 2027-07-07 259710.84 2028-07-05 214116.72 2029-07-04 162375.12 2030-07-03 82530.95 Mark_reno 10000
18 2025-08-20 440904.8 2026-07-22 359021.02 2027-07-21 256201.8 2028-07-19 210468.35 2029-07-18 158581.9 2030-07-17 78587.12 D_leave_owed_in_days 90.6
19 2025-09-03 428524.06 2026-08-05 356175.3 2027-08-04 253782.55 2028-08-02 207715.12 2029-08-01 154788.67 2030-07-31 74643.29 D_TLS_shares 1000
20 2025-09-17 424255.66 2026-08-19 351788.17 2027-08-18 250262.11 2028-08-16 204054.9 2029-08-15 151657.7 2030-08-14 71021.28 M_TLS_shares 750
21 2025-10-01 419987.25 2026-09-02 348899.23 2027-09-01 246741.66 2028-08-30 200394.68 2029-08-29 147852.15 2030-08-28 67064.63 D_CBA_shares 1095
22 2025-10-15 417454.7 2026-09-16 344501.1 2027-09-15 244273.6 2028-09-13 197589.68 2029-09-12 144678.6 2030-09-11 63396.8 TLS_price 3.99
23 2025-10-29 413175.68 2026-09-30 340102.97 2027-09-29 240741.72 2028-09-27 193917.56 2029-09-26 140860.68 2030-09-25 59427.29 CBA_price 160.61
24 2025-11-12 410660.56 2026-10-14 337111.91 2027-10-13 238202.3 2028-10-11 191045.16 2029-10-10 137624.31 2030-10-09 55704.53 Overseas_trip_date 2025-06-01
25 2025-11-26 406370.89 2026-10-28 322702.74 2027-10-27 234658.94 2028-10-25 187361.11 2029-10-24 133793.99 2030-10-23 51722.12 Mark_reno_date 2025-09-01
26 2025-12-10 381758.47 2026-11-11 319692.08 2027-11-10 232115.41 2028-11-08 184475.65 2029-11-07 130534.62 2030-11-06 47961.98 Sell_shares 6
27 2025-12-24 377458.1 2026-11-25 270448.27 2027-11-24 228560.53 2028-11-22 180779.63 2029-11-21 126691.85 2030-11-20 43966.63
28 2026-12-09 268232.01 2027-12-08 225946.99 2028-12-06 177828.21 2029-12-05 123371.23 2030-12-04 40153.28
29 2026-12-23 264801.78 2027-12-22 222380.56 2028-12-20 174120.17 2029-12-19 119515.97 2030-12-18 36144.95

34
main.py
View File

@@ -1,7 +1,7 @@
# main.py # main.py
from flask import Flask, render_template, request, redirect, url_for, Response from flask import Flask, render_template, request, redirect, url_for, Response
from calc import calculate_savings_depletion from calc import calculate_savings_depletion
from db import init_db, get_finance_data, update_finance from db import init_db, get_finance_data, update_finance, get_budget_data
from collections import defaultdict from collections import defaultdict
from datetime import datetime from datetime import datetime
import csv import csv
@@ -16,16 +16,10 @@ init_db()
def index(): def index():
finance_data = get_finance_data() finance_data = get_finance_data()
depletion_date, savings_per_fortnight, final_savings, TLS, CBA = calculate_savings_depletion(finance_data) depletion_date, savings_per_fortnight, final_savings, TLS, CBA = calculate_savings_depletion(finance_data)
BUDGET=get_budget_data(finance_data, CBA, TLS)
if depletion_date: if depletion_date:
depletion_date=depletion_date.date(); # just show date depletion_date=depletion_date.date(); # just show date
# annual bills - rates (2.4), electricity (1.5), gas (2), internet (1.6), car insurance (.7), rego (.8), house insurance (2.4), GFC (2.2), phones (.5), melb. pollen (.03), nabu casa (.1), eweka (.1) --- noting phone is elevated presuming I also go onto Aldi plan, but that there is no family discount
bills = 14330
BUDGET=[]
BUDGET.append( ('Bills', f"${bills:,.2f}") )
BUDGET.append( ('Buffer', f"${CBA*finance_data['CBA_price']:,.2f}") )
BUDGET.append( ('Monthly budget', f"${((finance_data['Living_Expenses']-12000) / 12):,.2f}" ) )
BUDGET.append( ('Weekly budget', f"${((finance_data['Living_Expenses']-12000) / 52):,.2f}" ) )
return render_template('index.html', finance=finance_data, depletion_date=depletion_date, savings=savings_per_fortnight, TLS=TLS, CBA=CBA, BUDGET=BUDGET) return render_template('index.html', finance=finance_data, depletion_date=depletion_date, savings=savings_per_fortnight, TLS=TLS, CBA=CBA, BUDGET=BUDGET)
@app.route('/update', methods=['POST']) @app.route('/update', methods=['POST'])
@@ -65,6 +59,7 @@ def download_csv():
finance_data = get_finance_data() finance_data = get_finance_data()
depletion_date, savings_per_fortnight, final_savings, TLS, CBA = calculate_savings_depletion(finance_data) depletion_date, savings_per_fortnight, final_savings, TLS, CBA = calculate_savings_depletion(finance_data)
BUDGET=get_budget_data(finance_data, CBA, TLS)
# Group data by year # Group data by year
data_by_year = defaultdict(list) data_by_year = defaultdict(list)
@@ -78,6 +73,10 @@ def download_csv():
# Sort years for column ordering # Sort years for column ordering
years = sorted(data_by_year.keys()) years = sorted(data_by_year.keys())
# get finance data into a list for spitting out during csv last column dump
fd_lst = list(finance_data.items())
fd_lst[0]=('Variable', 'Value')
# Create an in-memory output file # Create an in-memory output file
output = io.StringIO() output = io.StringIO()
@@ -91,6 +90,7 @@ def download_csv():
writer.writerow(header) writer.writerow(header)
# Write the data rows # Write the data rows
cnt=0
for i in range(max_entries_per_year): for i in range(max_entries_per_year):
row = [] row = []
for year in years: for year in years:
@@ -100,8 +100,26 @@ def download_csv():
row.extend([date, value]) row.extend([date, value])
else: else:
row.extend(["", ""]) # If no data for this year, leave blank cells row.extend(["", ""]) # If no data for this year, leave blank cells
# spacer
row.extend([""])
# now add budget data
if cnt < len(BUDGET):
row.extend( BUDGET[cnt] )
else:
row.extend(["", ""]) # If no data for this year, leave blank cells
# spacer
row.extend([""])
# now add reference data
if cnt < len(fd_lst):
row.extend(fd_lst[cnt])
writer.writerow(row) writer.writerow(row)
cnt += 1
csv_data = output.getvalue() csv_data = output.getvalue()
# Create a Flask Response object, with CSV mime type and downloadable as a file # Create a Flask Response object, with CSV mime type and downloadable as a file

View File

@@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Finance Form</title> <title>Finance Form</title>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</head> </head>
<body> <body>
<div class="container-fluid"> <div class="container-fluid">
@@ -167,6 +168,22 @@
<input type="number" class="form-control text-end float-end bg-light" id="TLS_shares" value="{{TLS}}" readonly> <input type="number" class="form-control text-end float-end bg-light" id="TLS_shares" value="{{TLS}}" readonly>
</div> </div>
</div> </div>
<div class="col-1">
<button type="button" class="btn btn-primary" onClick="
$.ajax( { type: 'GET', url: '/download_csv', xhrFields: { responseType: 'blob' },
success: function(res){
// Create a link element
const link = document.createElement('a');
const url = window.URL.createObjectURL(res);
link.href = url;
link.download = 'finance_data.csv'; // Set the file name
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url); // Clean up the object URL
console.log('done') } })
"> Export to CSV </button>
</div>
</div> </div>
</form> </form>
</div> </div>