diff --git a/calc.py b/calc.py index e0a37ad..fb247b7 100644 --- a/calc.py +++ b/calc.py @@ -1,9 +1,16 @@ # calc.py from datetime import datetime, timedelta -def add_annotation(finance, dt, amt, text): +def add_annotation(finance, dt, total, delta, text): + # dont add an annotation for small changes (jic) + if abs(delta) < 5000: + return tm = dt.timestamp() * 1000 - finance['annotations'].append( { 'label': text, 'x': tm, 'y': amt } ) + if delta > 0: + text += f": ${int(abs(delta))}" + else: + text += f": -${int(abs(delta))}" + finance['annotations'].append( { 'label': text, 'x': tm, 'y': total } ) return def calculate_savings_depletion(finance): @@ -98,6 +105,7 @@ def calculate_savings_depletion(finance): if D_Num_fortnights_pay == 0 and D_leave_after_tax > 0: print(f"D has resigned {current_date}: get paid out my 9 weeks leave and lose 45% to tax - ${D_leave_after_tax}" ) current_savings += D_leave_after_tax + add_annotation(finance, current_date, current_savings, D_leave_after_tax, "D quit" ) D_leave_after_tax = 0 if fortnight_income: @@ -125,28 +133,28 @@ def calculate_savings_depletion(finance): if current_date.date() == school_fees_date.date(): current_savings -= School_Fees - add_annotation(finance, current_date, current_savings, f"Pay School Fees: ${School_Fees}") + add_annotation(finance, current_date, current_savings, -School_Fees, "School Fees") if current_date.date() == car_balloon_date.date(): current_savings -= Car_balloon - add_annotation(finance, current_date, current_savings, f"car balloon paid: ${Car_balloon}" ) + add_annotation(finance, current_date, current_savings, -Car_balloon, "car balloon") # Anniversary of Car balloon so pay insurance/rego if current_date.year >= car_balloon_date.year and current_date.month == car_balloon_date.month and current_date.day == car_balloon_date.day: current_savings -= post_lease_car_costs - add_annotation(finance, current_date, current_savings, f"IONIQ 6 ins/rego: ${post_lease_car_costs}" ) + add_annotation(finance, current_date, current_savings, -post_lease_car_costs, "IONIQ 6 ins/rego" ) if current_date.date() == overseas_trip_date.date(): current_savings -= Overseas_trip - add_annotation(finance, current_date, current_savings, f"Overseas trip: ${Overseas_trip}") + add_annotation(finance, current_date, current_savings, -Overseas_trip, "O/S trip") if current_date.date() == mich_present_date.date(): current_savings -= Mich_present - add_annotation(finance, current_date, current_savings, f"Michelle's present: ${Mich_present}") + add_annotation(finance, current_date, current_savings, -Mich_present, "Mich's present" ) if current_date.date() == mark_reno_date.date(): current_savings -= Mark_reno - add_annotation(finance, current_date, current_savings, f"Mark/reno costs: ${Mark_reno}") + add_annotation(finance, current_date, current_savings, -Mark_reno, "Mark/reno" ) if current_savings < 0: depletion_date = current_date @@ -177,7 +185,7 @@ def calculate_savings_depletion(finance): Sell_shares -= 1 current_savings += actual_sell - add_annotation(finance, current_date, current_savings, f"Selling shares: ${int(actual_sell)}" ) + add_annotation(finance, current_date, current_savings, actual_sell, "Sell shares" ) current_date += timedelta(days=1) diff --git a/db.py b/db.py index 7a0f852..1892ce1 100644 --- a/db.py +++ b/db.py @@ -34,7 +34,8 @@ def init_db(): CBA_price REAL, Overseas_trip_date STRING, Mark_reno_date STRING, - Sell_shares INTEGER + Sell_shares INTEGER, + compare_to INTEGER )''') cur.execute('''CREATE TABLE IF NOT EXISTS comparison_set ( @@ -82,14 +83,15 @@ def init_db(): # Interest rate # D_leave_owed_in_days # maybe quarterly update Inflation? (this is harder to appreciate, seems much lower officialy than Savings, but which inflation: - # I've decided to consider food only or overall, whichever is worse - but only found a rabobank reference - THIS IS A MATERIAL ISSUE WITH PROJECTING OUT) + # I've decided to consider food only or overall, whichever is worse - using this: https://tradingeconomics.com/australia/food-inflation + # FOR NOW inf=3 THIS IS A MATERIAL ISSUE WITH PROJECTING OUT) ### 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) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', - (4762.29, 6, 22000, 620, 1001.12, 45824.68, 83000, 416670.67, 5.0, 3.9, 10000, 32000, 10000, 93.64, 1000, 750, 1095, 3.94, 158.57, '2025-06-01', '2025-09-01', 6)) - # 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 + 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, compare_to) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', + (4762.29, 6, 22000, 620, 1017.99, 45824.68, 84000, 416670.67, 5.0, 3.0, 10000, 32000, 10000, 93.64, 1000, 750, 1095, 3.92, 167.03, '2025-06-01', '2025-09-01', 6, 0)) + # NOTE: 1017.99 car-lease (NEED TO VERIFY) + # NOTE: o/s trip. ~ $4kpp flights x3, then ~$3k / week in barcelona accom, $100pp/pd for food ($2k), + spending money (could be less) conn.commit() conn.close() @@ -112,8 +114,8 @@ def get_budget_data(finance_data): return BUDGET def update_finance(data): - - conn = connect_db() + print(data) + conn = connect_db(False) cur = conn.cursor() cur.execute('''UPDATE finance SET D_Salary = ?, @@ -137,14 +139,15 @@ def update_finance(data): CBA_price = ?, Overseas_trip_date = ?, Mark_reno_date = ?, - Sell_shares = ? + Sell_shares = ?, + compare_to = ? WHERE id = 1''', data) conn.commit() conn.close() def insert_cset( data ): - conn = connect_db() + conn = connect_db(False) cur = conn.cursor() cur.execute('''INSERT INTO comparison_set ( name, D_Salary, D_Num_fortnights_pay, School_Fees, Car_loan_via_pay, @@ -181,12 +184,12 @@ def get_comp_set_data(cset_id): conn = connect_db(True) cur = conn.cursor() - # HARDCODED FOR NOW - cset_id = 1 - # get saved finance data for this comparison set cur.execute( f"select * from comparison_set where id = {cset_id}" ) - COMP['vars']= dict(cur.fetchone()) + res=cur.fetchone() + if not res: + return None + COMP['vars']= dict(res) conn.close() # open new connection so we get rows back as basic array @@ -201,3 +204,14 @@ def get_comp_set_data(cset_id): COMP['date'], COMP['amount'] = COMP['savings_data'][-1] return COMP + +def get_comp_set_options(finance): + finance['COMP_SETS']=[ ( 0, 'Nothing' ) ] + # get comp data from DB (as object so dict conversion works below) + conn = connect_db(False) + cur = conn.cursor() + + # get saved finance data for this comparison set + cur.execute( f"select id, name from comparison_set order by id" ) + finance['COMP_SETS'].extend( cur.fetchall() ) + return diff --git a/disp.py b/disp.py index 466495f..b676ec3 100644 --- a/disp.py +++ b/disp.py @@ -22,7 +22,7 @@ class FP_VAR(FP): dot-notation of fields """ - def __init__(self, label, varname, display='', cl='col-2', datevarname=''): + def __init__(self, label, varname, display='', cl='col-auto', datevarname=''): ### Var Attributes -- note, simple class, no methods ### self.label=label self.varname=varname diff --git a/main.py b/main.py index 0131f0c..be4654b 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,7 @@ # main.py from flask import Flask, render_template, request, redirect, url_for, Response from calc import calculate_savings_depletion -from db import init_db, get_finance_data, update_finance, get_budget_data, get_comp_set_data +from db import init_db, get_finance_data, update_finance, get_budget_data, get_comp_set_data, get_comp_set_options from collections import defaultdict from datetime import datetime import csv @@ -16,18 +16,15 @@ init_db() @app.route('/') def index(): finance_data = get_finance_data() + get_comp_set_options(finance_data) depletion_date, savings_per_fortnight, final_savings = calculate_savings_depletion(finance_data) BUDGET=get_budget_data(finance_data) if depletion_date: depletion_date=depletion_date.date(); # just show date - #HARDCODE HACK: - finance_data['comp_set']=1 - - # we are comparing... - if finance_data['comp_set'] >= 1: - COMP=get_comp_set_data(finance_data['comp_set']) + # if we are comparing...(compare_to will be 0 / None to start with, and then COMP will be None + COMP=get_comp_set_data(finance_data['compare_to']) DISP=[] # Row 1 @@ -36,7 +33,7 @@ def index(): r.append( FP_VAR( 'Savings', 'Savings' ) ) r.append( FP_VAR( 'Car Loan via Pay', 'Car_loan_via_pay', 'readonly' ) ) r.append( FP_VAR( 'Living Expenses', 'Living_Expenses' ) ) - r.append( FP_VAR( 'Overseas Trip', 'Overseas_trip', 'date', 'col-4', 'Overseas_trip_date' ) ) + r.append( FP_VAR( 'Overseas Trip', 'Overseas_trip', 'date', 'col-auto', 'Overseas_trip_date' ) ) DISP.append(r) # Row 2 @@ -45,12 +42,12 @@ def index(): r.append( FP_VAR( 'Interest Rate', 'Interest_Rate' ) ) r.append( FP_VAR( 'Car Loan', 'Car_loan', 'readonly' ) ) r.append( FP_VAR( 'Inflation', 'Inflation' ) ) - r.append( FP_VAR( 'Reno Costs', 'Mark_reno', 'date', 'col-4', 'Mark_reno_date' ) ) + r.append( FP_VAR( 'Reno Costs', 'Mark_reno', 'date', 'col-auto', 'Mark_reno_date' ) ) DISP.append(r) # Row 2 r=[] - r.append( FP_VAR( 'D leave owed (in days)', 'D_leave_owed_in_days' ) ) + r.append( FP_VAR( 'D # days leave', 'D_leave_owed_in_days' ) ) r.append( FP_VAR( 'M TLS amount', 'M_TLS_shares' ) ) r.append( FP_VAR( 'Car Balloon', 'Car_balloon', 'readonly' ) ) DISP.append(r) @@ -60,7 +57,7 @@ def index(): r.append( FP_VAR( 'D CBA amount', 'D_CBA_shares' ) ) r.append( FP_VAR( 'D TLS amount', 'D_TLS_shares' ) ) r.append( FP_VAR( 'Mich Present', 'Mich_present', 'readonly' ) ) - r.append( FP_VAR( 'Sell Shares for:', 'Sell_shares', 'select', 'offset-2 col-2' ) ) + r.append( FP_VAR( 'Sell Shares for:', 'Sell_shares', 'select', 'col-auto' ) ) DISP.append(r) # Row 4 @@ -100,6 +97,7 @@ def update(): request.form['Overseas_trip_date'], request.form['Mark_reno_date'], request.form['Sell_shares'], + request.form['compare_to'] ) update_finance(finance_data) @@ -110,7 +108,7 @@ def update(): def download_csv(): 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 = calculate_savings_depletion(finance_data) BUDGET=get_budget_data(finance_data) # Group data by year diff --git a/templates/index.html b/templates/index.html index b09893a..3a238e8 100644 --- a/templates/index.html +++ b/templates/index.html @@ -8,38 +8,34 @@ +
-