Compare commits
6 Commits
676e9ab95f
...
3d95cd1d2e
| Author | SHA1 | Date | |
|---|---|---|---|
| 3d95cd1d2e | |||
| d7320e8aa8 | |||
| 5556b0ef15 | |||
| 9cd14505bf | |||
| b43b472e4b | |||
| 5ebd623d88 |
119
bills.py
119
bills.py
@@ -1,7 +1,6 @@
|
|||||||
from db import get_bill_data, get_bill_types, get_bill_freqs, set_bill_type_growth
|
from db import get_bill_data, get_bill_types, get_bill_freqs, set_bill_type_growth, new_bill
|
||||||
from defines import END_YEAR
|
from defines import END_YEAR
|
||||||
|
|
||||||
|
|
||||||
# give a bill dat in format YYYY-MM-DD, return quarter (1-4)
|
# give a bill dat in format YYYY-MM-DD, return quarter (1-4)
|
||||||
def qtr(d):
|
def qtr(d):
|
||||||
m = int(d[5:7])
|
m = int(d[5:7])
|
||||||
@@ -9,27 +8,60 @@ def qtr(d):
|
|||||||
|
|
||||||
# missing annual bill, find date based on MM-DD and add new year - given we start with first_bill anyway, will only be used for future bill predictions
|
# missing annual bill, find date based on MM-DD and add new year - given we start with first_bill anyway, will only be used for future bill predictions
|
||||||
# future only, so add ann_growth (based on drop-down) for each future year
|
# future only, so add ann_growth (based on drop-down) for each future year
|
||||||
def add_missing_annual_bill_in_yr( bill_type, bill_info, num, yr ):
|
# NOTE: only ever called when there is a need to add a new bill
|
||||||
# print( f"{bill_type}: Seems we are missing an annual bill in {yr}, use first_bill={bill_info[bill_type]['first_bill']['bill_date']} to add one" )
|
def add_missing_annual_bill_in_yr( bill_type, bill_info, yr ):
|
||||||
mm_dd = bill_info[bill_type]['last_bill']['bill_date'][5:]
|
mm_dd = bill_info[bill_type]['last_bill']['bill_date'][5:]
|
||||||
l_amt = bill_info[bill_type]['last_bill']['amount']
|
amt = bill_info[bill_type]['last_bill']['amount']
|
||||||
# print( f"{bill_type}: Should fake a bill into date={yr}-{mm_dd} of adjusted amount from base of {l_amt}" )
|
|
||||||
# okay the missing bill is before the first bill...
|
# okay the missing bill is before the first bill...
|
||||||
for i in range( bill_info[bill_type]['last_bill_year'], yr ):
|
for i in range( bill_info[bill_type]['last_bill_year'], yr ):
|
||||||
l_amt += l_amt * 5.26/100
|
amt += amt * bill_info[bill_type]['growth']/100
|
||||||
print( f"{bill_type}: So should insert bill as: ${l_amt:.02f} on '{yr}-{mm_dd}'")
|
|
||||||
|
# last param is estimated (and this is an estimate for a future bill / not real)
|
||||||
|
new_bill( bill_type, amt, f'{yr}-{mm_dd}', 1 )
|
||||||
return
|
return
|
||||||
|
|
||||||
# missing quarterly bill, find date based on MM-DD and ??? - can have missing bilsl in first year
|
# missing quarterly bill, find date based on MM-DD and ??? - can have missing bilsl in first year
|
||||||
# add growth (based on drop-down) for each future year
|
# add growth (based on drop-down) for each future year
|
||||||
def add_missing_quarter_bills_in_yr( bill_type, bill_info, num, yr ):
|
def add_missing_quarter_bills_in_yr( bill_type, bill_info, yr ):
|
||||||
# print( f"{bill_type}: Seems we are missing a quarterly bill in {yr}, use first_bill={bill_info[bill_type]['first_bill']['bill_date']} to add one" )
|
print( f"*** add_missing_quarter_bills_in_yr( {bill_type}, bill_info, {yr} ): NOT YET" )
|
||||||
return
|
return
|
||||||
|
|
||||||
# missing monthly bills, find date based on DD and put in each missing month
|
# missing monthly bills, find date based on DD and put in each missing month
|
||||||
# add growth (based on drop-down) for each future year
|
# add growth (based on drop-down) for each future year
|
||||||
def add_missing_monthly_bills_in_yr( bill_type, bill_info, num, yr ):
|
# NOTE: ALWAYS called for first year - don't always add bills/see below
|
||||||
# print( f"{bill_type}: Seems we are missing a monthly bill in {yr}, use first_bill={bill_info[bill_type]['first_bill']['bill_date']} to add one" )
|
def add_missing_monthly_bills_in_yr( bill_type, bill_info, yr ):
|
||||||
|
|
||||||
|
# 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
|
||||||
|
dd = bill_info[bill_type]['first_bill']['bill_date'][8:]
|
||||||
|
mm = bill_info[bill_type]['first_bill']['bill_date'][5:7]
|
||||||
|
|
||||||
|
# choose last bill from last amount to grow from as its most relevant
|
||||||
|
amt = bill_info[bill_type]['last_bill']['amount']
|
||||||
|
|
||||||
|
growth=0
|
||||||
|
#okay add monthly bills for the rest of this year if its the first year
|
||||||
|
if bill_info[bill_type]['first_bill_year'] == yr:
|
||||||
|
start_m=int(mm)
|
||||||
|
else:
|
||||||
|
start_m=0
|
||||||
|
|
||||||
|
# fill in rest of this year
|
||||||
|
for i in range( start_m+1, 13 ):
|
||||||
|
bill_found=False
|
||||||
|
new_date = f'{yr}-{i:02d}-{dd}'
|
||||||
|
if yr in bill_info[bill_type]['year']:
|
||||||
|
for b in bill_info[bill_type]['year'][yr]:
|
||||||
|
# this bill exists, skip adding it (this occurs when called to
|
||||||
|
# add bills as there are < 12 bills in first_year, BUT, we
|
||||||
|
# don't fill before first_bill so the < 12 ALWAYS triggers
|
||||||
|
if str(b['bill_date']) == new_date:
|
||||||
|
bill_found=True
|
||||||
|
break
|
||||||
|
if not bill_found:
|
||||||
|
amt += amt * growth/100
|
||||||
|
# last param is estimated (and this is an estimate for a future bill / not real)
|
||||||
|
new_bill( bill_type, amt, new_date, 1 )
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -40,6 +72,7 @@ def add_missing_monthly_bills_in_yr( bill_type, bill_info, num, yr ):
|
|||||||
def process_bill_data(bd, bt, bf):
|
def process_bill_data(bd, bt, bf):
|
||||||
# this maps a bill id to a freq id (e.g. bill #34 - has a frequency of #2 (which might be quarterly)
|
# this maps a bill id to a freq id (e.g. bill #34 - has a frequency of #2 (which might be quarterly)
|
||||||
bt_id_freq = {row["id"]: row["freq"] for row in bt}
|
bt_id_freq = {row["id"]: row["freq"] for row in bt}
|
||||||
|
bt_id_ann_growth_avg = {row["id"]: row["ann_growth_avg"] for row in bt}
|
||||||
|
|
||||||
# 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 bf}
|
bf_id_num = {row["id"]: row["num_bills_per_annum"] for row in bf}
|
||||||
@@ -54,20 +87,26 @@ def process_bill_data(bd, bt, bf):
|
|||||||
# new bill type
|
# new bill type
|
||||||
if not bill_type in bill_info:
|
if not bill_type in bill_info:
|
||||||
bill_info[bill_type]={}
|
bill_info[bill_type]={}
|
||||||
|
bill_info[bill_type]['growth'] = bt_id_ann_growth_avg[bill_type]
|
||||||
|
bill_info[bill_type]['num_ann_bills'] = bf_id_num[bt_id_freq[bill_type]]
|
||||||
bill_info[bill_type]['first_bill']={}
|
bill_info[bill_type]['first_bill']={}
|
||||||
bill_info[bill_type]['last_bill']={}
|
bill_info[bill_type]['last_bill']={}
|
||||||
# due to sql sorting, this first instance is the last bill
|
# due to sql sorting, this first instance is the last bill
|
||||||
bill_info[bill_type]['last_bill']=bill
|
bill_info[bill_type]['last_bill']=bill
|
||||||
bill_info[bill_type]['last_bill_year']=int(bill['bill_date'][:4])
|
bill_info[bill_type]['last_bill_year']=int(bill['bill_date'][:4])
|
||||||
bill_info[bill_type]['year']={}
|
bill_info[bill_type]['year']={}
|
||||||
|
bill_info[bill_type]['year_real']={}
|
||||||
if not yr in bill_info[bill_type]['year']:
|
if not yr in bill_info[bill_type]['year']:
|
||||||
bill_info[bill_type]['year'][yr]=[]
|
bill_info[bill_type]['year'][yr]=[]
|
||||||
|
bill_info[bill_type]['year_real'][yr]=[]
|
||||||
|
|
||||||
# keep updating last to this matching bill
|
# keep updating last to this matching bill
|
||||||
bill_info[bill_type]['first_bill']=bill
|
bill_info[bill_type]['first_bill']=bill
|
||||||
bill_info[bill_type]['first_bill_year']=int(bill['bill_date'][:4])
|
bill_info[bill_type]['first_bill_year']=int(bill['bill_date'][:4])
|
||||||
# add this bill to list for this year
|
# add this bill to list for this year
|
||||||
bill_info[bill_type]['year'][yr].append(bill)
|
bill_info[bill_type]['year'][yr].append(bill)
|
||||||
|
if not bill['estimated']:
|
||||||
|
bill_info[bill_type]['year_real'][yr].append(bill)
|
||||||
|
|
||||||
# now process the bill_info from yr of first bill to yr of last bill
|
# now process the bill_info from yr of first bill to yr of last bill
|
||||||
for bill_type in bill_info:
|
for bill_type in bill_info:
|
||||||
@@ -82,40 +121,39 @@ def process_bill_data(bd, bt, bf):
|
|||||||
|
|
||||||
# go from first_bill year until reach end year
|
# go from first_bill year until reach end year
|
||||||
for yr in range( yr_min, END_YEAR+1 ):
|
for yr in range( yr_min, END_YEAR+1 ):
|
||||||
if yr in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr]) == num:
|
# we have all the bills needed for yr
|
||||||
# print(f"{bill_type}: need {num} annual bills and found then for {yr}" )
|
if yr in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr]) == bill_info[bill_type]['num_ann_bills']:
|
||||||
continue
|
continue
|
||||||
# if yr not in bill_info[bill_type]['year']:
|
add_missing_bills_for_yr( bill_type, bill_info, yr )
|
||||||
# print(f"{bill_type}: need {num} annual bills and 0 found for {yr}" )
|
derive_ann_growth( bill_type, bill_info )
|
||||||
# else:
|
|
||||||
# print(f"{bill_type}: need {num} annual bills and only {len(bill_info[bill_type]['year'][yr])} found for {yr}" )
|
|
||||||
add_missing_bills_for_yr( bill_type, bill_info, num, yr )
|
|
||||||
# now should have missing bills, calculate ann growth properly
|
|
||||||
derive_ann_growth( bill_type, bill_info, num )
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# add_missing_bills_for_yr -- wrapper to call right func based on bill freq
|
# add_missing_bills_for_yr -- wrapper to call right func based on bill freq
|
||||||
################################################################################
|
################################################################################
|
||||||
def add_missing_bills_for_yr( bill_type, bill_info, num, yr ):
|
def add_missing_bills_for_yr( bill_type, bill_info, yr ):
|
||||||
|
print(f"{bill_type}: add_missing_bills_for_yr( {bill_type}, bill_info, {yr} )")
|
||||||
|
num = bill_info[bill_type]['num_ann_bills']
|
||||||
if num == 1:
|
if num == 1:
|
||||||
add_missing_annual_bill_in_yr( bill_type, bill_info, num, yr )
|
add_missing_annual_bill_in_yr( bill_type, bill_info, yr )
|
||||||
elif num == 4:
|
elif num == 4:
|
||||||
add_missing_quarter_bills_in_yr( bill_type, bill_info, num, yr )
|
add_missing_quarter_bills_in_yr( bill_type, bill_info, yr )
|
||||||
elif num == 12:
|
elif num == 12:
|
||||||
add_missing_monthly_bills_in_yr( bill_type, bill_info, num, yr )
|
add_missing_monthly_bills_in_yr( bill_type, bill_info, yr )
|
||||||
return
|
return
|
||||||
|
|
||||||
def derive_ann_growth( bill_type, bill_info, num ):
|
def derive_ann_growth( bill_type, bill_info ):
|
||||||
print(f"Derive annual growth on bill_type: {bill_type} " )
|
print(f"{bill_type}: Derive annual growth on bill_type: {bill_type} " )
|
||||||
# DDP: rewrite loop below to use bill_info more cleverly, start with type, then year, then use the data in there rather than in bd
|
|
||||||
|
|
||||||
total={}
|
total={}
|
||||||
for yr in range( bill_info[bill_type]['first_bill_year'], bill_info[bill_type]['last_bill_year']+1):
|
for yr in range( bill_info[bill_type]['first_bill_year'], bill_info[bill_type]['last_bill_year']+1):
|
||||||
|
if len(bill_info[bill_type]['year_real'][yr]) != bill_info[bill_type]['num_ann_bills']:
|
||||||
|
continue
|
||||||
total[yr] = 0
|
total[yr] = 0
|
||||||
for b in bill_info[bill_type]['year'][yr]:
|
for b in bill_info[bill_type]['year'][yr]:
|
||||||
|
# ignore estimated bills, only use real bills to calc growth stats
|
||||||
|
if b['estimated']:
|
||||||
|
continue
|
||||||
total[yr] += b['amount']
|
total[yr] += b['amount']
|
||||||
# print( f"{yr} => {b['bill_date']} -- {b['amount']}" )
|
|
||||||
# print( f"total for {bill_type} in {yr} is {total[yr]}" )
|
|
||||||
|
|
||||||
# once we have all yr totals:
|
# once we have all yr totals:
|
||||||
growth = {}
|
growth = {}
|
||||||
@@ -124,12 +162,14 @@ def derive_ann_growth( bill_type, bill_info, num ):
|
|||||||
max_growth = 0
|
max_growth = 0
|
||||||
count = 0
|
count = 0
|
||||||
for yr in range( bill_info[bill_type]['first_bill_year'], bill_info[bill_type]['last_bill_year']+1):
|
for yr in range( bill_info[bill_type]['first_bill_year'], bill_info[bill_type]['last_bill_year']+1):
|
||||||
if yr-1 in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr-1]) != num:
|
# less than {num_ann_bills} bills in yr: {yr-1}, so can't use data
|
||||||
# print(f"less than {num} bills in yr: {yr-1}, so can't use data" )
|
if yr-1 in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr-1]) != bill_info[bill_type]['num_ann_bills']:
|
||||||
continue
|
continue
|
||||||
if yr in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr]) != num:
|
# less than {num_ann_bills} bills in yr: {yr-1}, so can't use data
|
||||||
# print(f"less than {num} bills in yr: {yr-1}, so can't use data" )
|
if yr in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr]) != bill_info[bill_type]['num_ann_bills']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# we full data sets for consecutive years, work out annual growth stats
|
||||||
if yr-1 in total and yr in total:
|
if yr-1 in total and yr in total:
|
||||||
growth = (total[yr] - total[yr-1]) / total[yr-1] * 100
|
growth = (total[yr] - total[yr-1]) / total[yr-1] * 100
|
||||||
avg_growth += growth
|
avg_growth += growth
|
||||||
@@ -138,12 +178,11 @@ def derive_ann_growth( bill_type, bill_info, num ):
|
|||||||
min_growth = growth
|
min_growth = growth
|
||||||
if growth > max_growth:
|
if growth > max_growth:
|
||||||
max_growth = growth
|
max_growth = growth
|
||||||
# print( f"growth from {yr} to {yr-1} = {growth}%")
|
|
||||||
if count:
|
if count:
|
||||||
print( f"Min growth was: {min_growth}" )
|
print( f"{bill_type}: Min growth was: {min_growth}" )
|
||||||
print( f"Avg growth is: {avg_growth/count}" )
|
print( f"{bill_type}: Avg growth is: {avg_growth/count}" )
|
||||||
print( f"Max growth was: {max_growth}" )
|
print( f"{bill_type}: Max growth was: {max_growth}" )
|
||||||
set_bill_type_growth( bill_type, avg_growth/count )
|
set_bill_type_growth( bill_type, min_growth, avg_growth/count, max_growth )
|
||||||
else:
|
else:
|
||||||
# failsafe (just in case fill bills failed to add enough bills to average out)
|
# failsafe (just in case fill bills failed to add enough bills to average out)
|
||||||
print( f"Unable to calculate growth!" )
|
print( f"{bill_type}: Unable to calculate growth!" )
|
||||||
|
|||||||
19
db.py
19
db.py
@@ -88,7 +88,9 @@ def init_db():
|
|||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
freq INTEGER,
|
freq INTEGER,
|
||||||
name STRING,
|
name STRING,
|
||||||
ann_growth REAL,
|
ann_growth_min REAL,
|
||||||
|
ann_growth_avg REAL,
|
||||||
|
ann_growth_max REAL,
|
||||||
FOREIGN KEY(freq) REFERENCES bill_freq(id)
|
FOREIGN KEY(freq) REFERENCES bill_freq(id)
|
||||||
)''')
|
)''')
|
||||||
|
|
||||||
@@ -103,6 +105,7 @@ def init_db():
|
|||||||
bill_type INTEGER,
|
bill_type INTEGER,
|
||||||
amount INTEGER,
|
amount INTEGER,
|
||||||
bill_date DATE,
|
bill_date DATE,
|
||||||
|
estimated INTEGER,
|
||||||
FOREIGN KEY(bill_type) REFERENCES bill_type(id)
|
FOREIGN KEY(bill_type) REFERENCES bill_type(id)
|
||||||
)''')
|
)''')
|
||||||
|
|
||||||
@@ -260,7 +263,9 @@ def get_comp_set_options(finance):
|
|||||||
def get_bill_data():
|
def get_bill_data():
|
||||||
conn = connect_db(True)
|
conn = connect_db(True)
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
cur.execute('SELECT bd.id, bt.id as bill_type_id, bt.name, bd.amount, bd.bill_date FROM bill_type bt, bill_data bd where bt.id = bd.bill_type order by bt.name, bd.bill_date desc')
|
cur.execute('''SELECT bd.id, bt.id as bill_type_id, bt.name, bd.amount, bd.bill_date, bd.estimated
|
||||||
|
FROM bill_type bt, bill_data bd
|
||||||
|
where bt.id = bd.bill_type order by bt.name, bd.bill_date desc''')
|
||||||
bd = cur.fetchall()
|
bd = cur.fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
return bd
|
return bd
|
||||||
@@ -282,10 +287,10 @@ def get_bill_freqs():
|
|||||||
return bf
|
return bf
|
||||||
|
|
||||||
|
|
||||||
def new_bill( name, amount, bill_date ):
|
def new_bill( bill_type, amount, bill_date, estimated ):
|
||||||
conn = connect_db(False)
|
conn = connect_db(False)
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
cur.execute( f"insert into bill_data ( 'bill_type', 'amount', 'bill_date' ) values ( '{name}', '{amount}', '{bill_date}' )" )
|
cur.execute( f"insert into bill_data ( 'bill_type', 'amount', 'bill_date', 'estimated' ) values ( '{bill_type}', '{amount}', '{bill_date}', {estimated} )" )
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return
|
return
|
||||||
@@ -302,7 +307,7 @@ def insert_bill_type( bt, fq ):
|
|||||||
conn = connect_db(False)
|
conn = connect_db(False)
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print( f"fq={fq}" )
|
print( f"fq={fq}" )
|
||||||
cur.execute( f"insert into bill_type ( 'name', 'freq', 'ann_growth' ) values ( '{bt}', {fq}, 0 )" )
|
cur.execute( f"insert into bill_type ( 'name', 'freq', 'ann_growth_min', 'ann_growth_avg', 'ann_growth_max' ) values ( '{bt}', {fq}, 0, 0, 0 )" )
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return
|
return
|
||||||
@@ -331,10 +336,10 @@ def delete_bill_type( id ):
|
|||||||
conn.close()
|
conn.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
def set_bill_type_growth( id, g ):
|
def set_bill_type_growth( id, min_g, avg_g, max_g ):
|
||||||
conn = connect_db(False)
|
conn = connect_db(False)
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
cur.execute( f"update bill_type set ann_growth ='{g}' where id = {id}" )
|
cur.execute( f"update bill_type set ann_growth_min='{min_g}', ann_growth_avg ='{avg_g}', ann_growth_max='{max_g}' where id = {id}" )
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return
|
return
|
||||||
|
|||||||
4
main.py
4
main.py
@@ -145,6 +145,7 @@ def DisplayBillData():
|
|||||||
bill_types = get_bill_types()
|
bill_types = get_bill_types()
|
||||||
bill_freqs = get_bill_freqs()
|
bill_freqs = get_bill_freqs()
|
||||||
process_bill_data(bill_data, bill_types, bill_freqs)
|
process_bill_data(bill_data, bill_types, bill_freqs)
|
||||||
|
bill_data = get_bill_data()
|
||||||
return render_template('bills.html', bill_data=bill_data, bill_types=bill_types, bill_freqs=bill_freqs )
|
return render_template('bills.html', bill_data=bill_data, bill_types=bill_types, bill_freqs=bill_freqs )
|
||||||
|
|
||||||
@app.route('/newbilltype', methods=['POST'])
|
@app.route('/newbilltype', methods=['POST'])
|
||||||
@@ -162,7 +163,8 @@ def UpdateBillType():
|
|||||||
@app.route('/newbill', methods=['POST'])
|
@app.route('/newbill', methods=['POST'])
|
||||||
def InsertBill():
|
def InsertBill():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
new_bill( data['name'], data['amount'], data['bill_date'] )
|
# last param is estimated - e.g. anything via GUI is not an estimate, but is a real bill
|
||||||
|
new_bill( data['name'], data['amount'], data['bill_date'], 0 )
|
||||||
return "200"
|
return "200"
|
||||||
|
|
||||||
@app.route('/updatebill', methods=['POST'])
|
@app.route('/updatebill', methods=['POST'])
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<div class="mt-4 col-6">
|
<div class="mt-4 col-6">
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<button id="new-bill-type-button" class="mb-3 px-0 offset-2 col-2 btn btn-success" onCLick="StartNewBillType()"><span class="bi bi-plus-lg"> New Bill Type</span></button>
|
<button id="new-bill-type-button" class="mb-3 px-0 offset-4 col-2 btn btn-success" onCLick="StartNewBillType()"><span class="bi bi-plus-lg"> New Bill Type</span></button>
|
||||||
<div class="new-bill-type-class px-0 col-2 d-none"> <input type="text" class="form-control text-end float-end border border-primary" id="new-bill-type-name"></div>
|
<div class="new-bill-type-class px-0 col-2 d-none"> <input type="text" class="form-control text-end float-end border border-primary" id="new-bill-type-name"></div>
|
||||||
<div class="new-bill-type-class px-0 col-2 d-none"><select id="new-bill-type-freq" class="form-select text-center">
|
<div class="new-bill-type-class px-0 col-2 d-none"><select id="new-bill-type-freq" class="form-select text-center">
|
||||||
{% for bf in bill_freqs %}
|
{% for bf in bill_freqs %}
|
||||||
@@ -35,10 +35,10 @@
|
|||||||
<button id="canc-bill-type" class="new-bill-type-class px-0 col-1 btn btn-danger d-none" onClick="CancelNewBillType()"><span class="bi bi-trash3"> Cancel</span></button>
|
<button id="canc-bill-type" class="new-bill-type-class px-0 col-1 btn btn-danger d-none" onClick="CancelNewBillType()"><span class="bi bi-trash3"> Cancel</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-light rounded-0">Name</ ></div>
|
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-light rounded-0 h-100"><br>Name</ ></div>
|
||||||
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-light rounded-0">Frequency</ ></div>
|
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-light rounded-0 h-100"><br>Frequency</ ></div>
|
||||||
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-light rounded-0">Annual Growth Est</ ></div>
|
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-light rounded-0">Annual Growth Est (min/avg/max)</ ></div>
|
||||||
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-light rounded-0">Actions</ ></div>
|
<div class="px-0 col-2"><label class="form-control text-center border-0 fw-bold bg-light rounded-0 h-100"><br>Actions</ ></div>
|
||||||
</div>
|
</div>
|
||||||
{% for bt in bill_types %}
|
{% for bt in bill_types %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -52,7 +52,9 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<script>console.log( 'set freq to {{bt.freq}}' ); $('#bill-type-freq-{{bt.id}}').val( {{bt.freq}} );</script>
|
<script>console.log( 'set freq to {{bt.freq}}' ); $('#bill-type-freq-{{bt.id}}').val( {{bt.freq}} );</script>
|
||||||
<div class="px-0 col-2"><input type="text" class="form-control text-center" id="bill-type-grow-{{bt.id}}" value="{{'%.2f'|format(bt.ann_growth)}}%" disabled> </div>
|
<div class="px-0 col-2"><input type="text" class="form-control text-center" id="bill-type-grow-{{bt.id}}"
|
||||||
|
value="{{'%.2f'|format(bt.ann_growth_min)}} / {{'%.2f'|format(bt.ann_growth_avg)}} / {{'%.2f'|format(bt.ann_growth_max)}}%"
|
||||||
|
disabled> </div>
|
||||||
<button id="bill-type-chg-{{bt.id}}" class="px-0 col-1 btn btn-success" onClick="StartUpdateBillType( {{bt.id}} )">Change</button>
|
<button id="bill-type-chg-{{bt.id}}" class="px-0 col-1 btn btn-success" onClick="StartUpdateBillType( {{bt.id}} )">Change</button>
|
||||||
<button id="bill-type-del-{{bt.id}}" class="px-0 col-1 btn btn-danger" onClick="DelBillType({{bt.id}})"><span class="bi bi-trash3"> Delete</button>
|
<button id="bill-type-del-{{bt.id}}" class="px-0 col-1 btn btn-danger" onClick="DelBillType({{bt.id}})"><span class="bi bi-trash3"> Delete</button>
|
||||||
<button id="bill-type-save-{{bt.id}}" class="px-0 col-1 btn btn-success d-none" onClick="UpdateBillType( {{bt.id}} )">Save</button>
|
<button id="bill-type-save-{{bt.id}}" class="px-0 col-1 btn btn-success d-none" onClick="UpdateBillType( {{bt.id}} )">Save</button>
|
||||||
@@ -87,6 +89,10 @@
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
|
<div class="col-2 form-check form-switch form-check-inline">
|
||||||
|
<input class="form-check-input" type="checkbox" value="" id="showEstimated" onChange="ToggleEstimated()">
|
||||||
|
<label class="form-check-label" for="flexCheckDefault">Show Estimates</label>
|
||||||
|
</div>
|
||||||
{% for bt in bill_types %}
|
{% for bt in bill_types %}
|
||||||
{% if loop.first %}
|
{% if loop.first %}
|
||||||
<div id="tab-{{bt.id}}" class="tab-pane active">
|
<div id="tab-{{bt.id}}" class="tab-pane active">
|
||||||
@@ -103,16 +109,24 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if bd.bill_type_id == bt.id %}
|
{% if bd.bill_type_id == bt.id %}
|
||||||
|
{% if bd.estimated == 1 %}
|
||||||
|
<div class="row est d-none fst-italic">
|
||||||
|
{% set classes="fst-italic form-control text-center bg-white" %}
|
||||||
|
{% else %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="px-0 col-2"> <input type="text" class="form-control text-center bg-white" id="bill-data-type-{{bd.id}}" value="{{ bd.name }}" disabled> </div>
|
{% set classes="form-control text-center bg-white" %}
|
||||||
<div class="px-0 col-2"> <input type="date" class="form-control text-center bg-white" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
|
{% endif %}
|
||||||
<div class="px-0 col-2"> <input type="number" class="form-control text-center bg-white" id="bill-data-amount-{{bd.id}}" value="{{ bd.amount }}" disabled> </div>
|
<div class="px-0 col-2"> <input type="text" class="{{classes}}" id="bill-data-type-{{bd.id}}" value="{{ bd.name }}" 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>
|
||||||
|
<div class="px-0 col-2"> <input type="number" class="{{classes}}" id="bill-data-amount-{{bd.id}}" value="{{ bd.amount }}" disabled> </div>
|
||||||
|
{% if bd.estimated == 0 %}
|
||||||
<button id="bill-data-chg-{{bd.id}}" class="px-0 col-1 btn btn-success" onClick="StartUpdateBill( {{bd.id}} )">Change</button>
|
<button id="bill-data-chg-{{bd.id}}" class="px-0 col-1 btn btn-success" onClick="StartUpdateBill( {{bd.id}} )">Change</button>
|
||||||
<button id="bill-data-del-{{bd.id}}" class="px-0 col-1 btn btn-danger" onClick="DeleteBill( {{bd.id }} )"><span class="bi bi-trash3"> Delete
|
<button id="bill-data-del-{{bd.id}}" class="px-0 col-1 btn btn-danger" onClick="DeleteBill( {{bd.id }} )"><span class="bi bi-trash3"> Delete
|
||||||
<button id="bill-data-save-{{bd.id}}" class="px-0 col-1 btn btn-success d-none" onClick="UpdateBill( {{bd.id}} )">Save</button>
|
<button id="bill-data-save-{{bd.id}}" class="px-0 col-1 btn btn-success d-none" onClick="UpdateBill( {{bd.id}} )">Save</button>
|
||||||
<button id="bill-data-canc-{{bd.id}}" class="px-0 col-1 btn btn-danger d-none"
|
<button id="bill-data-canc-{{bd.id}}" class="px-0 col-1 btn btn-danger d-none"
|
||||||
onClick="CancelUpdateBill({{bd.id}}, '{{bd.name}}', '{{bd.bill_date}}', '{{bd.amount}}')"> <span class="bi bi-trash3"> Cancel</button>
|
onClick="CancelUpdateBill({{bd.id}}, '{{bd.name}}', '{{bd.bill_date}}', '{{bd.amount}}')"> <span class="bi bi-trash3"> Cancel</button>
|
||||||
</button>
|
</button>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -121,6 +135,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
function ToggleEstimated()
|
||||||
|
{
|
||||||
|
if( $("#showEstimated").is(":checked") )
|
||||||
|
$('.est').removeClass('d-none')
|
||||||
|
else
|
||||||
|
$('.est').addClass('d-none')
|
||||||
|
}
|
||||||
|
|
||||||
function StartNewBillData()
|
function StartNewBillData()
|
||||||
{
|
{
|
||||||
$('.new-bill-data-class').removeClass('d-none')
|
$('.new-bill-data-class').removeClass('d-none')
|
||||||
|
|||||||
Reference in New Issue
Block a user