redid bills UI, you can now choose CPI or FLAT X% as well, via a drop-down not a set of buttons. The changing of inflation also tweaks any bills using CPI, all works
This commit is contained in:
2
BUGS
2
BUGS
@@ -1,2 +1,4 @@
|
|||||||
|
* kayo bills are wrong in between normal bills
|
||||||
|
|
||||||
* added an electricity bill by accident for 2018, that kills lots :(
|
* added an electricity bill by accident for 2018, that kills lots :(
|
||||||
- something to do with missing year of data in quarterly bills - still an issue
|
- something to do with missing year of data in quarterly bills - still an issue
|
||||||
|
|||||||
17
TODO
17
TODO
@@ -1,11 +1,22 @@
|
|||||||
|
bills html, and growth types are very lame... could I do something more like:
|
||||||
|
{% for gt in growth %}
|
||||||
|
{% if gt.name == 'Min' %}
|
||||||
|
<option value='min'
|
||||||
|
{% if bt.which_growth == gt.name %}selected{% endif %}
|
||||||
|
>{{'%.2f'|format(bt.ann_growth_min)}}% {{gt.name}}</option>
|
||||||
|
|
||||||
|
|
||||||
CALC:
|
CALC:
|
||||||
* if I quit at different times of the financial year, technically the amount I earn will be taxed
|
* if I quit at different times of the financial year, technically the amount I earn will be taxed
|
||||||
differently, but hard to calc - slides around with tax brackets in future
|
differently, but hard to calc - slides around with tax brackets in future
|
||||||
|
|
||||||
UI:
|
UI:
|
||||||
* allow changing comparison when in tab with graph of comparisons - remember to force redraw page and then come to graph again
|
* to allow <yr> total on bill summary, need to re-work annual growth to a drop-down
|
||||||
* I *COULD* have a basic date check/workflow, e.g. it now>last_update+14 (and its more than a paydate <- need to think that bit through)
|
- [DONE] mock-up
|
||||||
then the question mark can be more prominent -> use an <alert> that suggests updating as per ?
|
- need to change 'which growth' to accommodate new growth models (cpi, override*)
|
||||||
|
- [DONE] do this in DB with new table - then don't do crazy pattern matching/making up overrides in the UI code
|
||||||
|
- get UI to use bill_growth_types table
|
||||||
|
- get UseGrowth() to use bill_growth_types table
|
||||||
|
|
||||||
For bills:
|
For bills:
|
||||||
* might need to be able to mark a specific bill as an outlier:
|
* might need to be able to mark a specific bill as an outlier:
|
||||||
|
|||||||
29
bills.py
29
bills.py
@@ -2,6 +2,7 @@ from db import set_bill_type_growth, new_bill, deleteFutureEstimates, get_financ
|
|||||||
from calc import calc_key_dates
|
from calc import calc_key_dates
|
||||||
from defines import END_YEAR
|
from defines import END_YEAR
|
||||||
import datetime
|
import datetime
|
||||||
|
import re
|
||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
|
|
||||||
|
|
||||||
@@ -238,6 +239,8 @@ def actually_add_estimated_new_quarter_bill_forced( bill_type, bill_info, yr, q
|
|||||||
# NOTE: ALWAYS called for first year - don't always add bills/see below
|
# NOTE: ALWAYS called for first year - don't always add bills/see below
|
||||||
def add_missing_monthly_bills_in_yr( bill_type, bill_info, yr ):
|
def add_missing_monthly_bills_in_yr( bill_type, bill_info, yr ):
|
||||||
|
|
||||||
|
print( f"add_missing_monthly_bills_in_yr for ( bt={bill_type} -- yr={yr} )" )
|
||||||
|
|
||||||
# start date arithmetic from first bill (this is possibly an issue if monthly is not
|
# start date arithmetic from first bill (this is possibly an issue if monthly is not
|
||||||
# really perfectly the same each month, but its only for an estimate so should be ok
|
# really perfectly the same each month, but its only for an estimate so should be ok
|
||||||
dd = bill_info[bill_type]['first_bill']['bill_date'][8:]
|
dd = bill_info[bill_type]['first_bill']['bill_date'][8:]
|
||||||
@@ -295,8 +298,18 @@ def get_growth_value( bt, bill_type ):
|
|||||||
return el['ann_growth_min']
|
return el['ann_growth_min']
|
||||||
elif which == 'simple':
|
elif which == 'simple':
|
||||||
return el['ann_growth_simple']
|
return el['ann_growth_simple']
|
||||||
else:
|
elif which == 'max':
|
||||||
return el['ann_growth_max']
|
return el['ann_growth_max']
|
||||||
|
elif which == 'cpi':
|
||||||
|
finance_data = get_finance_data()
|
||||||
|
return finance_data['Inflation']
|
||||||
|
else:
|
||||||
|
match = re.match("flat-(\d+)", which )
|
||||||
|
if match:
|
||||||
|
return int(match.group(1))
|
||||||
|
else:
|
||||||
|
print( f"FAILED TO GET_GROWTH_VALUE --> which={which}" )
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@@ -405,7 +418,7 @@ def deal_with_future_car_bills( key_dates, future_car_bills, bill_info ):
|
|||||||
amt=fb['amount']
|
amt=fb['amount']
|
||||||
bt=fb['bill_type']
|
bt=fb['bill_type']
|
||||||
# factor in growth for next bill
|
# factor in growth for next bill
|
||||||
for yr in range( int(car_yr), END_YEAR ):
|
for yr in range( int(car_yr), END_YEAR+1 ):
|
||||||
new_date=f"{yr}-{car_mmdd}"
|
new_date=f"{yr}-{car_mmdd}"
|
||||||
# if we dont already have an annual bill for this year (all car bills are annual)
|
# if we dont already have an annual bill for this year (all car bills are annual)
|
||||||
if yr not in bill_info[bt]['year']:
|
if yr not in bill_info[bt]['year']:
|
||||||
@@ -428,7 +441,7 @@ def deal_with_future_D_quit_bills( key_dates, future_D_quit_bills, bill_info ):
|
|||||||
bt=fb['bill_type']
|
bt=fb['bill_type']
|
||||||
if bill_info[bt]['num_ann_bills'] == 1:
|
if bill_info[bt]['num_ann_bills'] == 1:
|
||||||
# factor in growth for next bill
|
# factor in growth for next bill
|
||||||
for yr in range( int(D_quit_yr), END_YEAR ):
|
for yr in range( int(D_quit_yr), END_YEAR+1 ):
|
||||||
new_date=f"{yr}-{dq_mm}-{dq_dd}"
|
new_date=f"{yr}-{dq_mm}-{dq_dd}"
|
||||||
# if we dont already have an annual bill for this year
|
# if we dont already have an annual bill for this year
|
||||||
if not find_this_bill( bt, bill_info, new_date ):
|
if not find_this_bill( bt, bill_info, new_date ):
|
||||||
@@ -440,7 +453,7 @@ def deal_with_future_D_quit_bills( key_dates, future_D_quit_bills, bill_info ):
|
|||||||
new_date=f"{D_quit_yr}-{m:02d}-{dq_dd}"
|
new_date=f"{D_quit_yr}-{m:02d}-{dq_dd}"
|
||||||
if not find_this_bill( bt, bill_info, new_date ):
|
if not find_this_bill( bt, bill_info, new_date ):
|
||||||
new_estimated_bill( bill_info, yr, bt, amt, new_date )
|
new_estimated_bill( bill_info, yr, bt, amt, new_date )
|
||||||
for yr in range( int(D_quit_yr)+1, END_YEAR ):
|
for yr in range( int(D_quit_yr)+1, END_YEAR+1 ):
|
||||||
amt += amt * bill_info[bt]['growth']/100
|
amt += amt * bill_info[bt]['growth']/100
|
||||||
for m in range( 1, 13):
|
for m in range( 1, 13):
|
||||||
new_date=f"{yr}-{m:02d}-{dq_dd}"
|
new_date=f"{yr}-{m:02d}-{dq_dd}"
|
||||||
@@ -614,7 +627,6 @@ def recalcFutureBills():
|
|||||||
print("Recalculating future bills as we changed a key date" )
|
print("Recalculating future bills as we changed a key date" )
|
||||||
finance_data = get_finance_data()
|
finance_data = get_finance_data()
|
||||||
key_dates = calc_key_dates( finance_data )
|
key_dates = calc_key_dates( finance_data )
|
||||||
finance_data = get_finance_data()
|
|
||||||
bill_data = get_bill_data("order_by_date_only")
|
bill_data = get_bill_data("order_by_date_only")
|
||||||
bill_types = get_bill_types()
|
bill_types = get_bill_types()
|
||||||
bill_freqs = get_bill_freqs()
|
bill_freqs = get_bill_freqs()
|
||||||
@@ -623,7 +635,6 @@ def recalcFutureBills():
|
|||||||
# this maps freq to bills per annum (e.g. id=2 to 4 bills per annum)
|
# this maps freq to bills per annum (e.g. id=2 to 4 bills per annum)
|
||||||
bf_id_num = {row["id"]: row["num_bills_per_annum"] for row in bill_freqs}
|
bf_id_num = {row["id"]: row["num_bills_per_annum"] for row in bill_freqs}
|
||||||
|
|
||||||
|
|
||||||
getFutureBills(bill_data, bill_types, future_car_bills, future_D_quit_bills)
|
getFutureBills(bill_data, bill_types, future_car_bills, future_D_quit_bills)
|
||||||
deleteFutureEstimates()
|
deleteFutureEstimates()
|
||||||
# deal with future car bills
|
# deal with future car bills
|
||||||
@@ -635,7 +646,7 @@ def recalcFutureBills():
|
|||||||
# only can use simple growth as its a future bill
|
# only can use simple growth as its a future bill
|
||||||
growth=bill_types[bt]['ann_growth_simple']
|
growth=bill_types[bt]['ann_growth_simple']
|
||||||
# factor in growth for next bills
|
# factor in growth for next bills
|
||||||
for yr in range( int(car_yr), END_YEAR ):
|
for yr in range( int(car_yr), END_YEAR+1 ):
|
||||||
new_date=f"{yr}-{car_mmdd}"
|
new_date=f"{yr}-{car_mmdd}"
|
||||||
new_bill( fb['bill_type'], amt, new_date, 1 )
|
new_bill( fb['bill_type'], amt, new_date, 1 )
|
||||||
amt += amt * growth/100
|
amt += amt * growth/100
|
||||||
@@ -654,7 +665,7 @@ def recalcFutureBills():
|
|||||||
num_ann_bills= bf_id_num[bt_id_freq[bt]]
|
num_ann_bills= bf_id_num[bt_id_freq[bt]]
|
||||||
if num_ann_bills == 1:
|
if num_ann_bills == 1:
|
||||||
# factor in growth for next bill
|
# factor in growth for next bill
|
||||||
for yr in range( int(D_quit_yr), END_YEAR ):
|
for yr in range( int(D_quit_yr), END_YEAR+1 ):
|
||||||
new_date=f"{yr}-{dq_mm}-{dq_dd}"
|
new_date=f"{yr}-{dq_mm}-{dq_dd}"
|
||||||
# if we dont already have an annual bill for this year
|
# if we dont already have an annual bill for this year
|
||||||
new_bill( fb['bill_type'], amt, new_date, 1 )
|
new_bill( fb['bill_type'], amt, new_date, 1 )
|
||||||
@@ -664,7 +675,7 @@ def recalcFutureBills():
|
|||||||
for m in range( int(dq_mm), 13):
|
for m in range( int(dq_mm), 13):
|
||||||
new_date=f"{D_quit_yr}-{m:02d}-{dq_dd}"
|
new_date=f"{D_quit_yr}-{m:02d}-{dq_dd}"
|
||||||
new_bill( fb['bill_type'], amt, new_date, 1 )
|
new_bill( fb['bill_type'], amt, new_date, 1 )
|
||||||
for yr in range( int(D_quit_yr)+1, END_YEAR ):
|
for yr in range( int(D_quit_yr)+1, END_YEAR+1 ):
|
||||||
amt += amt * growth/100
|
amt += amt * growth/100
|
||||||
for m in range( 1, 13):
|
for m in range( 1, 13):
|
||||||
new_date=f"{yr}-{m:02d}-{dq_dd}"
|
new_date=f"{yr}-{m:02d}-{dq_dd}"
|
||||||
|
|||||||
67
db.py
67
db.py
@@ -84,6 +84,12 @@ def init_db():
|
|||||||
FOREIGN KEY(comparison_set_id) REFERENCES comparison_set(id)
|
FOREIGN KEY(comparison_set_id) REFERENCES comparison_set(id)
|
||||||
)''')
|
)''')
|
||||||
|
|
||||||
|
cur.execute('''CREATE TABLE IF NOT EXISTS bill_freq (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name STRING,
|
||||||
|
num_bills_per_annum INTEGER
|
||||||
|
)''')
|
||||||
|
|
||||||
cur.execute('''CREATE TABLE IF NOT EXISTS bill_type (
|
cur.execute('''CREATE TABLE IF NOT EXISTS bill_type (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
freq INTEGER,
|
freq INTEGER,
|
||||||
@@ -95,12 +101,6 @@ def init_db():
|
|||||||
FOREIGN KEY(freq) REFERENCES bill_freq(id)
|
FOREIGN KEY(freq) REFERENCES bill_freq(id)
|
||||||
)''')
|
)''')
|
||||||
|
|
||||||
cur.execute('''CREATE TABLE IF NOT EXISTS bill_freq (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
name STRING,
|
|
||||||
num_bills_per_annum INTEGER
|
|
||||||
)''')
|
|
||||||
|
|
||||||
cur.execute('''CREATE TABLE IF NOT EXISTS bill_data (
|
cur.execute('''CREATE TABLE IF NOT EXISTS bill_data (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
bill_type INTEGER,
|
bill_type INTEGER,
|
||||||
@@ -116,19 +116,56 @@ def init_db():
|
|||||||
show_estimated INTEGER
|
show_estimated INTEGER
|
||||||
)''')
|
)''')
|
||||||
|
|
||||||
# Check if table is empty, if so insert default values
|
cur.execute('''CREATE TABLE IF NOT EXISTS bill_growth_types (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name string,
|
||||||
|
value INTEGER
|
||||||
|
)''')
|
||||||
|
|
||||||
|
# Check if finance table is empty, if so insert default values
|
||||||
cur.execute('SELECT COUNT(*) FROM finance')
|
cur.execute('SELECT COUNT(*) FROM finance')
|
||||||
if cur.fetchone()[0] == 0:
|
if cur.fetchone()[0] == 0:
|
||||||
cur.execute('''INSERT INTO finance (D_Salary, D_Num_fortnights_pay, School_Fees, Car_loan_via_pay, Car_loan, Car_balloon, Car_buyout, 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, Car_buyout, 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, Car_buyout_date, Sell_shares, compare_to, Ioniq6_future)
|
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, Car_buyout_date, Sell_shares, compare_to, Ioniq6_future)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
|
||||||
(4762.29, 10, 24000, 620, 2412, 45824.68, 83738.74, 80000, 424875.26, 4.75, 2.4, 10000, 50000, 10000, 76.85, 1000, 750, 1111, 4.52, 163.32, '2025-06-01', '2025-09-01', '2025-02-20', 4, 0, 0))
|
(4762.29, 10, 24000, 620, 2412, 45824.68, 83738.74, 80000, 424875.26, 4.75, 2.4, 10000, 50000, 10000, 76.85, 1000, 750, 1111, 4.52, 163.32, '2025-06-01', '2025-09-01', '2025-02-20', 4, 0, 0))
|
||||||
|
|
||||||
|
# Check if bill_freq table is empty, if so insert default values
|
||||||
|
cur.execute('SELECT COUNT(*) FROM bill_freq')
|
||||||
|
if cur.fetchone()[0] == 0:
|
||||||
cur.execute( "INSERT INTO bill_freq values ( 1, 'Annual', 1 )" )
|
cur.execute( "INSERT INTO bill_freq values ( 1, 'Annual', 1 )" )
|
||||||
cur.execute( "INSERT INTO bill_freq values ( 2, 'Quarterly', 4 )" )
|
cur.execute( "INSERT INTO bill_freq values ( 2, 'Quarterly', 4 )" )
|
||||||
cur.execute( "INSERT INTO bill_freq values ( 3, 'Quarterly (forced)', 4 )" )
|
cur.execute( "INSERT INTO bill_freq values ( 3, 'Quarterly (forced)', 4 )" )
|
||||||
cur.execute( "INSERT INTO bill_freq values ( 4, 'Monthly', 12 )" )
|
cur.execute( "INSERT INTO bill_freq values ( 4, 'Monthly', 12 )" )
|
||||||
# start with no specific Tab/bill_type to show, and dont show_estimated
|
# start with no specific Tab/bill_type to show, and dont show_estimated
|
||||||
|
|
||||||
|
# Check if bill_ui table is empty, if so insert default values
|
||||||
|
cur.execute('SELECT COUNT(*) FROM bill_ui')
|
||||||
|
if cur.fetchone()[0] == 0:
|
||||||
cur.execute( "INSERT INTO bill_ui values ( 1, null, 0 )" )
|
cur.execute( "INSERT INTO bill_ui values ( 1, null, 0 )" )
|
||||||
|
|
||||||
|
# Check if bill_growth_types table is empty, if so insert default values
|
||||||
|
cur.execute('SELECT COUNT(*) FROM bill_growth_types')
|
||||||
|
if cur.fetchone()[0] == 0:
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Min', 0 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Avg', 0 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Max', 0 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Simple', 0 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'CPI', 0 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 0', 0 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 1', 1 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 2', 2 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 3', 3 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 4', 4 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 5', 5 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 6', 6 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 7', 7 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 8', 8 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 9', 9 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 10', 10 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 12', 12 )" )
|
||||||
|
cur.execute( "INSERT INTO bill_growth_types ( name, value ) values ( 'Flat 15', 15 )" )
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
@@ -367,6 +404,14 @@ def set_bill_type_growth( id, min_g, avg_g, max_g, simple_g ):
|
|||||||
conn.close()
|
conn.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def get_bill_growth_types():
|
||||||
|
conn = connect_db(True)
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute('SELECT * FROM bill_growth_types')
|
||||||
|
growth = cur.fetchall()
|
||||||
|
conn.close()
|
||||||
|
return growth
|
||||||
|
|
||||||
def get_bill_ui():
|
def get_bill_ui():
|
||||||
conn = connect_db(True)
|
conn = connect_db(True)
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
@@ -404,6 +449,14 @@ def delete_estimated_bills():
|
|||||||
conn.close()
|
conn.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def delete_estimated_bills_for(bt_id):
|
||||||
|
conn = connect_db(False)
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute( f"delete from bill_data where estimated=1 and bill_type = {bt_id}" )
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
return
|
||||||
|
|
||||||
def delete_cset(id):
|
def delete_cset(id):
|
||||||
conn = connect_db(False)
|
conn = connect_db(False)
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
|
|||||||
28
main.py
28
main.py
@@ -1,9 +1,11 @@
|
|||||||
# main.py
|
# main.py
|
||||||
from flask import Flask, render_template, request, redirect, url_for, Response, jsonify
|
from flask import Flask, render_template, request, redirect, url_for, Response, jsonify
|
||||||
from calc import calculate_savings_depletion, calc_key_dates
|
from calc import calculate_savings_depletion, calc_key_dates
|
||||||
from db import init_db, get_finance_data, update_finance, get_budget_data, insert_cset, get_comp_set_data, get_comp_set_options, get_bill_freqs
|
from db import init_db, get_finance_data, update_finance, get_budget_data
|
||||||
from db import get_bill_data, new_bill, update_bill_data, delete_bill, delete_estimated_bills
|
from db import insert_cset, get_comp_set_data, get_comp_set_options, delete_cset
|
||||||
from db import get_bill_ui, save_ui, delete_cset
|
from db import get_bill_freqs, get_bill_growth_types
|
||||||
|
from db import get_bill_data, new_bill, update_bill_data, delete_bill, delete_estimated_bills, delete_estimated_bills_for
|
||||||
|
from db import get_bill_ui, save_ui
|
||||||
from db import get_bill_types, insert_bill_type, update_bill_type, delete_bill_type, use_growth
|
from db import get_bill_types, insert_bill_type, update_bill_type, delete_bill_type, use_growth
|
||||||
from bills import process_bill_data, calc_future_totals, set_bill_type_growth, recalcFutureBills
|
from bills import process_bill_data, calc_future_totals, set_bill_type_growth, recalcFutureBills
|
||||||
from defines import END_YEAR
|
from defines import END_YEAR
|
||||||
@@ -11,6 +13,7 @@ from collections import defaultdict, Counter
|
|||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
import csv
|
import csv
|
||||||
import io
|
import io
|
||||||
|
import requests
|
||||||
from disp import FP_VAR
|
from disp import FP_VAR
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@@ -148,6 +151,21 @@ def update():
|
|||||||
# changed Ioniq6_future, Car_buyout_date or D_Num_fortnights_pay, so lets force recalc key_dates, and therefore estimated bills
|
# changed Ioniq6_future, Car_buyout_date or D_Num_fortnights_pay, so lets force recalc key_dates, and therefore estimated bills
|
||||||
if old_finance_data['D_Num_fortnights_pay'] != new_finance_data['D_Num_fortnights_pay'] or old_finance_data['Ioniq6_future'] != new_finance_data['Ioniq6_future'] or old_finance_data['Car_buyout_date'] != new_finance_data['Car_buyout_date']:
|
if old_finance_data['D_Num_fortnights_pay'] != new_finance_data['D_Num_fortnights_pay'] or old_finance_data['Ioniq6_future'] != new_finance_data['Ioniq6_future'] or old_finance_data['Car_buyout_date'] != new_finance_data['Car_buyout_date']:
|
||||||
recalcFutureBills()
|
recalcFutureBills()
|
||||||
|
if old_finance_data['Inflation'] != new_finance_data['Inflation']:
|
||||||
|
# need to check if any bill type is using CPI, if so, force those future bills to be recalculated
|
||||||
|
bill_types = get_bill_types()
|
||||||
|
for bt in bill_types:
|
||||||
|
if bt['which_growth'] == 'cpi':
|
||||||
|
print( f"OK, changed inflation and need to redo bills for bt_id={bt['id']}" )
|
||||||
|
delete_estimated_bills_for( bt['id'] )
|
||||||
|
#recalc_estimated_bills_for( bt['id'] )
|
||||||
|
# okay, now go through code to recalc bills...
|
||||||
|
base=request.url_root
|
||||||
|
response = requests.get(f"{base}/bills")
|
||||||
|
if response.status_code == 200:
|
||||||
|
print("ALL GOOD")
|
||||||
|
else:
|
||||||
|
print("FFS")
|
||||||
|
|
||||||
return redirect(url_for('index'))
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
@@ -160,13 +178,14 @@ def DisplayBillData():
|
|||||||
bill_types = get_bill_types()
|
bill_types = get_bill_types()
|
||||||
bill_freqs = get_bill_freqs()
|
bill_freqs = get_bill_freqs()
|
||||||
bill_ui = get_bill_ui()
|
bill_ui = get_bill_ui()
|
||||||
|
bill_growth_types = get_bill_growth_types()
|
||||||
# take bill data, AND work out estimated future bills - process this into the bill_info array,
|
# take bill data, AND work out estimated future bills - process this into the bill_info array,
|
||||||
bill_info=process_bill_data(bill_data, bill_types, bill_freqs, key_dates)
|
bill_info=process_bill_data(bill_data, bill_types, bill_freqs, key_dates)
|
||||||
# get an array of the total costs of bills each year - purely cosmetic (using bill_info)
|
# get an array of the total costs of bills each year - purely cosmetic (using bill_info)
|
||||||
total=calc_future_totals(bill_info, bill_types)
|
total=calc_future_totals(bill_info, bill_types)
|
||||||
# update/re-get bill_data now that new estimated bills have been added
|
# update/re-get bill_data now that new estimated bills have been added
|
||||||
bill_data = get_bill_data("order_by_bill_type_then_date")
|
bill_data = get_bill_data("order_by_bill_type_then_date")
|
||||||
return render_template('bills.html', bill_data=bill_data, bill_types=bill_types, bill_freqs=bill_freqs, bill_ui=bill_ui, this_year=datetime.today().year, END_YEAR=END_YEAR, total=total, key_dates=key_dates )
|
return render_template('bills.html', bill_data=bill_data, bill_types=bill_types, bill_freqs=bill_freqs, bill_ui=bill_ui, this_year=datetime.today().year, END_YEAR=END_YEAR, total=total, key_dates=key_dates, growth=bill_growth_types, cpi=finance_data['Inflation'] )
|
||||||
|
|
||||||
@app.route('/newbilltype', methods=['POST'])
|
@app.route('/newbilltype', methods=['POST'])
|
||||||
def InsertBillType():
|
def InsertBillType():
|
||||||
@@ -224,6 +243,7 @@ def SaveUI():
|
|||||||
@app.route('/force_recalc_bills', methods=['POST'])
|
@app.route('/force_recalc_bills', methods=['POST'])
|
||||||
def force_recalc_bills():
|
def force_recalc_bills():
|
||||||
delete_estimated_bills()
|
delete_estimated_bills()
|
||||||
|
recalcFutureBills()
|
||||||
return "200"
|
return "200"
|
||||||
|
|
||||||
@app.route('/cset')
|
@app.route('/cset')
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
#}
|
#}
|
||||||
<div class="col-7">
|
<div class="col-8">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-2 form-control-inline d-none new-bill-type-class">Bill Type</div>
|
<div class="col-2 form-control-inline d-none new-bill-type-class">Bill Type</div>
|
||||||
<div class="col-2 form-control-inline d-none new-bill-type-class">Frequency</div>
|
<div class="col-2 form-control-inline d-none new-bill-type-class">Frequency</div>
|
||||||
@@ -55,66 +55,92 @@
|
|||||||
<button id="recalc-bills" class="mt-4 col-2 offset-3 btn btn-warning bg-warning-subtle text-warning" onClick="ForceRecalcBills()"><span class="bi bi-repeat"> Recalculate</span></button>
|
<button id="recalc-bills" class="mt-4 col-2 offset-3 btn btn-warning bg-warning-subtle text-warning" onClick="ForceRecalcBills()"><span class="bi bi-repeat"> Recalculate</span></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Name</ ></div>
|
<div class="px-0 col"><label class="form-control d-flex
|
||||||
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Frequency</ ></div>
|
align-items-end justify-content-center h-100 border-0 fw-bold bg-body-tertiary rounded-0">Name</ ></div>
|
||||||
<div class="px-0 col-4"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Annual Growth Est (min/avg/max/simple)</ ></div>
|
<div class="px-0 col"><label class="form-control d-flex
|
||||||
<div class="px-0 col-1"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">{{this_year}} Total</ ></div>
|
align-items-end justify-content-center h-100 border-0 fw-bold bg-body-tertiary rounded-0">Frequency</ ></div>
|
||||||
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Actions</ ></div>
|
<div class="px-0 col"><label class="form-control d-flex
|
||||||
|
align-items-end justify-content-center h-100 border-0 fw-bold
|
||||||
|
bg-body-tertiary rounded-0">Annual Growth</ ></div>
|
||||||
|
{% for yr in range( 2025, 2032 ) %}
|
||||||
|
<div class="px-0 col"><label class="form-control d-flex
|
||||||
|
align-items-end justify-content-center h-100 border-0
|
||||||
|
fw-bold bg-body-tertiary rounded-0">{{yr}} Total</ ></div>
|
||||||
|
{% endfor %}
|
||||||
|
<div class="px-0 col"><label class="form-control d-flex
|
||||||
|
align-items-end justify-content-center h-100 border-0 fw-bold bg-body-tertiary rounded-0">Actions</ ></div>
|
||||||
|
{# spacer to get header line right now we don't use forced col widths #}
|
||||||
|
<div class="px-0 col"><label class="form-control d-flex
|
||||||
|
align-items-end justify-content-center h-100 border-0 fw-bold bg-body-tertiary rounded-0"> </ ></div>
|
||||||
</div>
|
</div>
|
||||||
{% for bt in bill_types %}
|
{% for bt in bill_types %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="px-0 col-2"><input type="text" class="bill-type-{{bt.id}} form-control text-center" id="bill-type-name-{{bt.id}}" value="{{ bt.name }}" disabled> </div>
|
<div class="px-0 col-1"><input type="text" class="bill-type-{{bt.id}} form-control text-center" id="bill-type-name-{{bt.id}}" value="{{ bt.name }}" disabled> </div>
|
||||||
<!-- bind Enter to save this bill-type -->
|
<!-- bind Enter to save this bill-type -->
|
||||||
<script>$("#bill-type-name-{{bt.id}}").keyup(function(event){ if(event.which == 13){ $('#bill-type-save-{{bt.id}}').click(); } event.preventDefault(); });</script>
|
<script>$("#bill-type-name-{{bt.id}}").keyup(function(event){ if(event.which == 13){ $('#bill-type-save-{{bt.id}}').click(); } event.preventDefault(); });</script>
|
||||||
<div class="px-0 col-2"><select id="bill-type-freq-{{bt.id}}" class="bill-type-{{bt.id}} form-select text-center" disabled>
|
<div class="px-0 col-1"><select id="bill-type-freq-{{bt.id}}" class="bill-type-{{bt.id}} form-select text-center" disabled>
|
||||||
{% for bf in bill_freqs %}
|
{% for bf in bill_freqs %}
|
||||||
<option value={{bf.id}}>{{bf.name}}</option>
|
<option value={{bf.id}}>{{bf.name}}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<script>$('#bill-type-freq-{{bt.id}}').val( {{bt.freq}} );</script>
|
<script>$('#bill-type-freq-{{bt.id}}').val( {{bt.freq}} );</script>
|
||||||
<div class="px-0 col-4">
|
<div class="px-0 col">
|
||||||
<div class="btn-group w-100" role="group">
|
<div class="btn-group w-100" role="group">
|
||||||
<input type="radio" class="btn-check" name="growth-{{bt.id}}" id="min-{{bt.id}}" autocomplete="off"
|
<select id="{{bt.id}}_growth" class="form-select col" onChange="UseGrowth({{bt.id}})">
|
||||||
onChange="UseGrowth({{bt.id}}, 'min')" {% if bt.which_growth == 'min' %}checked{% endif %}>
|
{% for gt in growth %}
|
||||||
<label class="btn btn-outline-secondary font-monospace d-inline-block text-end" for="min-{{bt.id}}" style="width: 6ch;">
|
{% if gt.name == 'Min' %}
|
||||||
{% if bt.ann_growth_min> 0 and bt.ann_growth_min < 10 %} {% endif %}
|
<option value='min'
|
||||||
{{'%.2f'|format(bt.ann_growth_min)}}
|
{% if bt.which_growth == 'min' %}selected{% endif %}
|
||||||
</label>
|
>{{'%.2f'|format(bt.ann_growth_min)}}% {{gt.name}}</option>
|
||||||
<input type="radio" class="btn-check" name="growth-{{bt.id}}" id="avg-{{bt.id}}" autocomplete="off"
|
{% elif gt.name == 'Avg' %}
|
||||||
onChange="UseGrowth({{bt.id}}, 'avg')" {% if bt.which_growth == 'avg' %}checked{% endif %}>
|
<option value='avg'
|
||||||
<label class="btn btn-outline-secondary font-monospace d-inline-block text-end" for="avg-{{bt.id}}" style="width: 6ch;">
|
{% if bt.which_growth == 'avg' %}selected{% endif %}
|
||||||
{% if bt.ann_growth_avg < 10 %} {% endif %}
|
>{{'%.2f'|format(bt.ann_growth_avg)}}% {{gt.name}}</option>
|
||||||
{{'%.2f'|format(bt.ann_growth_avg)}}
|
{% elif gt.name == 'Max' %}
|
||||||
</label>
|
<option value='max'
|
||||||
<input type="radio" class="btn-check" name="growth-{{bt.id}}" id="max-{{bt.id}}" autocomplete="off"
|
{% if bt.which_growth == 'max' %}selected{% endif %}
|
||||||
onChange="UseGrowth({{bt.id}}, 'max')" {% if bt.which_growth == 'max' %}checked{% endif %}>
|
>{{'%.2f'|format(bt.ann_growth_max)}}% {{gt.name}}</option>
|
||||||
<label class="btn btn-outline-secondary font-monospace d-inline-block text-end" for="max-{{bt.id}}" style="width: 6ch;">
|
{% elif gt.name == 'Simple' %}
|
||||||
{% if bt.ann_growth_max < 10 %} {% endif %}
|
<option value='simple'
|
||||||
{{'%.2f'|format(bt.ann_growth_max)}}
|
{% if bt.which_growth == 'simple' %}selected{% endif %}
|
||||||
</label>
|
>{{'%.2f'|format(bt.ann_growth_simple)}}% {{gt.name}}</option>
|
||||||
<input type="radio" class="btn-check" name="growth-{{bt.id}}" id="simple-{{bt.id}}" autocomplete="off"
|
{% elif gt.name == 'CPI' %}
|
||||||
onChange="UseGrowth({{bt.id}}, 'simple')" {% if bt.which_growth == 'simple' %}checked{% endif %}>
|
<option value='cpi'
|
||||||
<label class="btn btn-outline-secondary font-monospace d-inline-block text-end" for="simple-{{bt.id}}" style="width: 6ch;">
|
{% if bt.which_growth == 'cpi' %}selected{% endif %}
|
||||||
{% if bt.ann_growth_simple < 10 %} {% endif %}
|
>{{'%.2f'|format(cpi)}}% {{gt.name}}</option>
|
||||||
{{'%.2f'|format(bt.ann_growth_simple)}}
|
{% else %}
|
||||||
</label>
|
<option value='flat-{{gt.value}}'
|
||||||
|
{% if bt.which_growth == 'flat-'+gt.value|string %}selected{% endif %}
|
||||||
|
>{{'%.2f'|format(gt.value)}}% {{gt.name}}
|
||||||
|
</option>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="px-0 col-1"><input type="text" class="bill-type-total-{{bt.id}} form-control text-center" id="bill-type-total-{{bt.id}}" value="${{'%.2f'|format(total[bt.id][this_year])}}" disabled> </div>
|
{% for yr in range( 2025, 2032 ) %}
|
||||||
<button id="bill-type-chg-{{bt.id}}" class="px-0 col-1 btn btn-success bg-success-subtle text-success" onClick="StartUpdateBillType( {{bt.id}} )"><span class="bi bi-pencil-square"> Change</button>
|
<div class="px-0 col"><input type="text" class="bill-type-total-{{bt.id}} form-control text-center" id="bill-type-total-{{bt.id}}" value="${{'%.2f'|format(total[bt.id][yr])}}" disabled> </div>
|
||||||
<button id="bill-type-del-{{bt.id}}" class="px-0 col-1 btn btn-danger bg-danger-subtle text-danger" onClick="DelBillType({{bt.id}})"><span class="bi bi-trash3"> Delete</button>
|
{% endfor %}
|
||||||
<button id="bill-type-save-{{bt.id}}" class="px-0 col-1 btn btn-success bg-success-subtle text-success d-none" onClick="UpdateBillType( {{bt.id}} )"><spam class="bi bi-floppy"> Save</button>
|
<button id="bill-type-chg-{{bt.id}}" class="px-0 col btn btn-success bg-success-subtle text-success" onClick="StartUpdateBillType( {{bt.id}} )"><span class="bi bi-pencil-square"> Change</button>
|
||||||
<button id="bill-type-canc-{{bt.id}}" class="px-0 col-1 btn btn-danger bg-danger-subtle text-danger d-none" onClick="CancelUpdateBillType({{bt.id}}, '{{bt.name}}')"><span class="bi bi-x"> Cancel</button>
|
<button id="bill-type-del-{{bt.id}}" class="px-0 col btn btn-danger bg-danger-subtle text-danger" onClick="DelBillType({{bt.id}})"><span class="bi bi-trash3"> Delete</button>
|
||||||
|
<button id="bill-type-save-{{bt.id}}" class="px-0 col btn btn-success bg-success-subtle text-success d-none" onClick="UpdateBillType( {{bt.id}} )"><spam class="bi bi-floppy"> Save</button>
|
||||||
|
<button id="bill-type-canc-{{bt.id}}" class="px-0 col btn btn-danger bg-danger-subtle text-danger d-none" onClick="CancelUpdateBillType({{bt.id}}, '{{bt.name}}')"><span class="bi bi-x"> Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for yr in range( this_year, END_YEAR) %}
|
<div class="row">
|
||||||
|
<div class="px-0 col"></div>
|
||||||
|
<div class="px-0 col"></div>
|
||||||
|
<div class="px-0 col"><input type="text" class="form-control text-end text-primary fs-5" value="TOTAL:"></div>
|
||||||
|
{% for yr in range( this_year, END_YEAR+1) %}
|
||||||
{% set tot=namespace( sum=0 ) %}
|
{% set tot=namespace( sum=0 ) %}
|
||||||
{% for bt in bill_types %}
|
{% for bt in bill_types %}
|
||||||
{% if bt.id in total %}
|
{% if bt.id in total %}
|
||||||
{% set tot.sum = tot.sum + total[bt.id][yr] %}
|
{% set tot.sum = tot.sum + total[bt.id][yr] %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<div class="px-0 col"><input type="text" class="form-control text-center text-primary bg-dark fs-5" value="${{'%.2f'|format(tot.sum)}}" disabled></div>
|
||||||
|
{#
|
||||||
{% set markup="h5" %}
|
{% set markup="h5" %}
|
||||||
{% if yr == this_year %}
|
{% if yr == this_year %}
|
||||||
{% set markup="h4 pt-4" %}
|
{% set markup="h4 pt-4" %}
|
||||||
@@ -127,12 +153,16 @@
|
|||||||
${{'%.2f'|format(tot.sum)}}
|
${{'%.2f'|format(tot.sum)}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
#}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<div class="px-0 col"></div>
|
||||||
|
<div class="px-0 col"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- right-hand-side, bill types (e.g. gas, phone, etc.) -->
|
<!-- right-hand-side, bill types (e.g. gas, phone, etc.) -->
|
||||||
|
|
||||||
<div class="col-5">
|
<div class="col-4">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-2 form-control-inline d-none new-bill-data-class">Bill Type</div>
|
<div class="col-2 form-control-inline d-none new-bill-data-class">Bill Type</div>
|
||||||
<div id="new-bill-data-date-label" class="col-4 form-control-inline d-none new-bill-data-class">Date</div>
|
<div id="new-bill-data-date-label" class="col-4 form-control-inline d-none new-bill-data-class">Date</div>
|
||||||
@@ -186,8 +216,9 @@
|
|||||||
<div class="row pt-2">
|
<div class="row pt-2">
|
||||||
<div class="p-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Name</ ></div>
|
<div class="p-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Name</ ></div>
|
||||||
<div class="p-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Date</ ></div>
|
<div class="p-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Date</ ></div>
|
||||||
<div class="p-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Amount</ ></div>
|
<div class="p-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Amount</ ></div>
|
||||||
<div class="px-0 col-4"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Actions</ ></div>
|
<div class="px-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Actions</ ></div>
|
||||||
|
<div class="px-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0 h-100"></ ></div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if bd.bill_type == bt.id %}
|
{% if bd.bill_type == bt.id %}
|
||||||
@@ -203,15 +234,24 @@
|
|||||||
<div class="px-0 col-2"> <input type="text" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
|
<div class="px-0 col-2"> <input type="text" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="px-0 col-2"> <input type="date" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
|
<div class="px-0 col-2"> <input type="date" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
|
||||||
|
<script>
|
||||||
|
if( typeof future_id !== 'undefined' && future_id>0) {
|
||||||
|
first_col_id={{bd.id}}
|
||||||
|
future_id=0
|
||||||
|
}
|
||||||
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="px-0 col-2"> <input type="number" class="{{classes}}" id="bill-data-amount-{{bd.id}}" value="{{ bd.amount }}" disabled> </div>
|
<div class="px-0 col"> <input type="number" class="{{classes}}" id="bill-data-amount-{{bd.id}}" value="{{ bd.amount }}" disabled> </div>
|
||||||
{% if bd.estimated == 0 %}
|
{% if bd.estimated == 0 %}
|
||||||
<button id="bill-data-chg-{{bd.id}}" class="px-0 col-2 btn btn-success bg-success-subtle text-success" onClick="StartUpdateBill( {{bd.id}} )"><span class="bi bi-pencil-square"> Change</button>
|
<button id="bill-data-chg-{{bd.id}}" class="px-0 col btn btn-success bg-success-subtle text-success" onClick="StartUpdateBill( {{bd.id}} )"><span class="bi bi-pencil-square"> Change</button>
|
||||||
<button id="bill-data-del-{{bd.id}}" class="px-0 col-2 btn btn-danger bg-danger-subtle text-danger" onClick="DeleteBill( {{bd.id }} )"><span class="bi bi-trash3"> Delete
|
<button id="bill-data-del-{{bd.id}}" class="px-0 col btn btn-danger bg-danger-subtle text-danger" onClick="DeleteBill( {{bd.id }} )"><span class="bi bi-trash3"> Delete
|
||||||
<button id="bill-data-save-{{bd.id}}" class="px-0 col-2 btn btn-success bg-success-subtle text-success d-none" onClick="UpdateBill( {{bd.id}} )"><span class="bi bi-floppy"> Save</button>
|
<button id="bill-data-save-{{bd.id}}" class="px-0 col btn btn-success bg-success-subtle text-success d-none" onClick="UpdateBill( {{bd.id}} )"><span class="bi bi-floppy"> Save</button>
|
||||||
<button id="bill-data-canc-{{bd.id}}" class="px-0 col-2 btn btn-danger bg-danger-subtle text-danger d-none"
|
<button id="bill-data-canc-{{bd.id}}" class="px-0 col btn btn-danger bg-danger-subtle text-danger d-none"
|
||||||
onClick="CancelUpdateBill({{bd.id}}, '{{bd.name}}', '{{bd.bill_date}}', '{{bd.amount}}')"> <span class="bi bi-x"> Cancel</button>
|
onClick="CancelUpdateBill({{bd.id}}, '{{bd.name}}', '{{bd.bill_date}}', '{{bd.amount}}')"> <span class="bi bi-x"> Cancel</button>
|
||||||
</button>
|
</button>
|
||||||
|
{% else %}
|
||||||
|
<div class="px-0 col"></div>
|
||||||
|
<div class="px-0 col"></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -403,10 +443,11 @@
|
|||||||
data: JSON.stringify( { 'id': id } ), success: function() { window.location='bills' } } )
|
data: JSON.stringify( { 'id': id } ), success: function() { window.location='bills' } } )
|
||||||
}
|
}
|
||||||
|
|
||||||
function UseGrowth( bt, which )
|
function UseGrowth( bt_id )
|
||||||
{
|
{
|
||||||
|
which = $('#'+bt_id+ '_growth option:selected').val()
|
||||||
$.ajax( { type: 'POST', url: '/usegrowth', contentType: 'application/json',
|
$.ajax( { type: 'POST', url: '/usegrowth', contentType: 'application/json',
|
||||||
data: JSON.stringify( { 'bill_type': bt, 'which_growth': which } ), success: function() { window.location='bills' } } )
|
data: JSON.stringify( { 'bill_type': bt_id, 'which_growth': which } ), success: function() { window.location='bills' } } )
|
||||||
}
|
}
|
||||||
|
|
||||||
function SaveTab( last_tab )
|
function SaveTab( last_tab )
|
||||||
@@ -472,6 +513,13 @@
|
|||||||
$.ajax( { type: 'POST', url: '/force_recalc_bills', contentType: 'application/json', success: function() { window.location='bills' } } )
|
$.ajax( { type: 'POST', url: '/force_recalc_bills', contentType: 'application/json', success: function() { window.location='bills' } } )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
$(document.ready() {
|
||||||
|
for( bt in future_ids ) {
|
||||||
|
$('#bill-data-date-'+future_ids[bt]).width( $('#bill-data-date-'+first_col_id[bt]).width() )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>Savings (<a href='https://online.macquarie.com.au/personal/#/login'>Macquarie</a>
|
<li>Savings (<a href='https://online.macquarie.com.au/personal/#/login'>Macquarie</a>
|
||||||
+<a href='https://ib.mebank.com.au/authR5/ib/login.jsp'>ME bank</a>
|
+<a href='https://ib.mebank.com.au/authR5/ib/login.jsp'>ME bank</a>
|
||||||
+<a href='https://ib.nab.com.au/login'>NAB</a>) -- noting ME bank is: $2001.19</li>
|
+<a href='https://ib.nab.com.au/login'>NAB</a>) -- noting ME bank is: $955.83</li>
|
||||||
<li><a href='https://www.google.com/search?q=asx+tls'>TLS</a>/<a href='https://www.google.com/search?q=asx+cba'>CBA</a> prices</li>
|
<li><a href='https://www.google.com/search?q=asx+tls'>TLS</a>/<a href='https://www.google.com/search?q=asx+cba'>CBA</a> prices</li>
|
||||||
<li>Macq <a href='https://www.macquarie.com.au/everyday-banking/savings-account.html'>Interest rate</a></li>
|
<li>Macq <a href='https://www.macquarie.com.au/everyday-banking/savings-account.html'>Interest rate</a></li>
|
||||||
<li><a href='https://deakinpeople.deakin.edu.au/psc/HCMP/EMPLOYEE/HRMS/c/NUI_FRAMEWORK.PT_AGSTARTPAGE_NUI.GBL?CONTEXTIDPARAMS=TEMPLATE_ID%3aPTPPNAVCOL&scname=ADMN_LEAVE&PTPPB_GROUPLET_ID=DU_LEAVE&CRefName=ADMN_NAVCOLL_3'>D_leave_owed_in_days</a> by: {{key_dates['D_quit_date']}}</li>
|
<li><a href='https://deakinpeople.deakin.edu.au/psc/HCMP/EMPLOYEE/HRMS/c/NUI_FRAMEWORK.PT_AGSTARTPAGE_NUI.GBL?CONTEXTIDPARAMS=TEMPLATE_ID%3aPTPPNAVCOL&scname=ADMN_LEAVE&PTPPB_GROUPLET_ID=DU_LEAVE&CRefName=ADMN_NAVCOLL_3'>D_leave_owed_in_days</a> by: {{key_dates['D_quit_date']}}</li>
|
||||||
|
|||||||
Reference in New Issue
Block a user