Change approach with Qtr bills, all are simple based on last qtr - when we have normal Qtr bills (freq 'Quarterly') we just use last qtrs data for growth much easier. For GAS, we have the 'Quaterly (forced)' freq. which uses the forced/calc. amount per qtr for growth, its good enough for Gas bills - which dont always have 4 bills a year
This commit is contained in:
50
bills.py
50
bills.py
@@ -140,7 +140,7 @@ def new_estimated_bill( bill_info, yr, bill_type, amt, new_date ):
|
||||
bill['bill_date']=new_date
|
||||
bill['amount']=amt
|
||||
bill['estimated']=1
|
||||
# need this for find_previous_bill to work but only need the above 3 fields
|
||||
# need to insert(0,) to add this "newest" bill to start of the data for {yr} so that find_previous_bill can work - only need the above 3 fields
|
||||
bill_info[bill_type]['year'][yr].insert(0,bill)
|
||||
|
||||
if bill_info[bill_type]['num_ann_bills'] == 4:
|
||||
@@ -190,16 +190,35 @@ def add_missing_quarter_bills_in_yr( bill_type, bill_info, yr ):
|
||||
else:
|
||||
r=range(1,5)
|
||||
for q in r:
|
||||
# amt is total of last year's qtr bill proportion
|
||||
amt = bill_info[bill_type]['qtr'][yr-1][q]*(1+bill_info[bill_type]['growth']/100)
|
||||
# just make new bills first of last month of a qtr (good as any date for GAS, they move anyway)
|
||||
new_date = f'{yr}-{q*3:02d}-01'
|
||||
# SANITY CHECK: we might be adding a bill estimate we already have (due to stupid gas bills /qtrly code)
|
||||
if yr in bill_info[bill_type]['year']:
|
||||
for b in bill_info[bill_type]['year'][yr]:
|
||||
if b['bill_date'] == new_date:
|
||||
return
|
||||
new_estimated_bill( bill_info, yr, bill_type, amt, new_date )
|
||||
if 'forced' in bill_info[bill_type]['freq']:
|
||||
actually_add_estimated_new_quarter_bill_forced(bill_type, bill_info, yr, q)
|
||||
else:
|
||||
actually_add_estimated_new_quarter_bill(bill_type, bill_info, yr, q)
|
||||
return
|
||||
|
||||
################################################################################
|
||||
# func take a qtr in a year, finds equiv from previous year, calcs new based on
|
||||
# it (same 'day' with amt * growth)
|
||||
################################################################################
|
||||
def actually_add_estimated_new_quarter_bill( bill_type, bill_info, yr, q ):
|
||||
|
||||
# amt is total of last year's qtr bill (NOTE: use 4-q, bills are in desc order)
|
||||
last_yrs_bill_in_this_q = bill_info[bill_type]['year'][yr-1][4-q]
|
||||
amt = last_yrs_bill_in_this_q['amount']*(1+bill_info[bill_type]['growth']/100)
|
||||
|
||||
# make new qtr bill same 'day' (mm-dd) as last year, just chg (yr)
|
||||
mmdd=last_yrs_bill_in_this_q['bill_date'][5:]
|
||||
new_date = f'{yr}-{mmdd}'
|
||||
new_estimated_bill( bill_info, yr, bill_type, amt, new_date )
|
||||
return
|
||||
|
||||
def actually_add_estimated_new_quarter_bill_forced( bill_type, bill_info, yr, q ):
|
||||
print( f"Being asked to add a FORCED qtr bill for {yr}-q{q} - likely a GAS bill, as its the only one, *sigh*" )
|
||||
last_yrs_qtr_amount = bill_info[bill_type]['qtr'][yr-1][q]
|
||||
print( f"amt is based on forced qtr amount for last year: {last_yrs_qtr_amount}" )
|
||||
amt=last_yrs_qtr_amount*(1+bill_info[bill_type]['growth']/100)
|
||||
new_date = f'{yr}-{q*3:02d}-01'
|
||||
new_estimated_bill( bill_info, yr, bill_type, amt, new_date )
|
||||
return
|
||||
|
||||
# missing monthly bills, find date based on DD and put in each missing month
|
||||
@@ -281,6 +300,8 @@ def process_bill_data(bd, bt, bf):
|
||||
|
||||
# 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}
|
||||
# and allows me a way to see if the bill is quarterly but also fixed or seasonal
|
||||
bf_id_name = {row["id"]: row["name"] for row in bf}
|
||||
|
||||
# want to proces all bill data into easier to maniuplate structure, so make
|
||||
# a bill_info[bill_id] with first_bill, last_bill, [yr] with matching bills to process
|
||||
@@ -292,6 +313,7 @@ def process_bill_data(bd, bt, bf):
|
||||
# new bill type
|
||||
if not bill_type in bill_info:
|
||||
bill_info[bill_type]={}
|
||||
bill_info[bill_type]['freq'] = bf_id_name[bt_id_freq[bill_type]]
|
||||
bill_info[bill_type]['growth'] = get_growth_value( bt, bill_type )
|
||||
bill_info[bill_type]['num_ann_bills'] = bf_id_num[bt_id_freq[bill_type]]
|
||||
bill_info[bill_type]['first_bill']={}
|
||||
@@ -310,7 +332,7 @@ def process_bill_data(bd, bt, bf):
|
||||
bill_info[bill_type]['first_bill_year']=int(bill['bill_date'][:4])
|
||||
if not 'last_real_bill_year' in bill_info[bill_type] and not bill['estimated']:
|
||||
bill_info[bill_type]['last_real_bill_year']=int(bill['bill_date'][:4])
|
||||
# add this bill to list for this year
|
||||
# append this bill to list for this year
|
||||
bill_info[bill_type]['year'][yr].append(bill)
|
||||
|
||||
# now process the bill_info from yr of first bill to yr of last bill
|
||||
@@ -464,8 +486,10 @@ def calc_future_totals(bill_info, bill_types):
|
||||
for bt in bill_types:
|
||||
total[bt['id']]={}
|
||||
for yr in range( now_yr, END_YEAR+1):
|
||||
total[bt['id']][yr]=0
|
||||
total[bt['id']][yr]=0.0
|
||||
if bt['id'] in bill_info and yr in bill_info[bt['id']]['year']:
|
||||
for b in bill_info[bt['id']]['year'][yr]:
|
||||
total[bt['id']][yr] += b['amount']
|
||||
# had to round to 2 decimal here to get sensible totals
|
||||
total[bt['id']][yr] = round( total[bt['id']][yr], 2 )
|
||||
return total
|
||||
|
||||
Reference in New Issue
Block a user