fixed a few bugs, annual growth was just broken, dont add another estimate bill when we have one for that year or in that quarter, removed lots of debugs, fixed a few bugs where the first data point in a new year/qtr would not have arrays initialised properly first, apportion quarterly data in future real bills - it happens with Rates
This commit is contained in:
76
bills.py
76
bills.py
@@ -1,4 +1,4 @@
|
|||||||
from db import get_bill_data, get_bill_types, get_bill_freqs, set_bill_type_growth, new_bill
|
from db import set_bill_type_growth, new_bill
|
||||||
from defines import END_YEAR
|
from defines import END_YEAR
|
||||||
import datetime
|
import datetime
|
||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
@@ -51,6 +51,8 @@ def allocate_by_quarter( bill_info, bill_type, yr, prev_bill, bill):
|
|||||||
bill_info[bill_type]['qtr'][q_start.year] = {}
|
bill_info[bill_type]['qtr'][q_start.year] = {}
|
||||||
for i in range(1,5):
|
for i in range(1,5):
|
||||||
bill_info[bill_type]['qtr'][q_start.year][i]=0
|
bill_info[bill_type]['qtr'][q_start.year][i]=0
|
||||||
|
if q not in bill_info[bill_type]['qtr'][q_start.year]:
|
||||||
|
bill_info[bill_type]['qtr'][q_start.year][q]=0
|
||||||
bill_info[bill_type]['qtr'][q_start.year][q] += days*cost_per_day
|
bill_info[bill_type]['qtr'][q_start.year][q] += days*cost_per_day
|
||||||
# next quarter
|
# next quarter
|
||||||
cur = q_end + timedelta(days=1)
|
cur = q_end + timedelta(days=1)
|
||||||
@@ -139,14 +141,17 @@ def new_estimated_bill( bill_info, yr, bill_type, amt, new_date ):
|
|||||||
|
|
||||||
if bill_info[bill_type]['num_ann_bills'] == 4:
|
if bill_info[bill_type]['num_ann_bills'] == 4:
|
||||||
q = qtr( new_date )
|
q = qtr( new_date )
|
||||||
|
# new bill in this qtr of this year, so set arrays up
|
||||||
if yr not in bill_info[bill_type]['qtr']:
|
if yr not in bill_info[bill_type]['qtr']:
|
||||||
bill_info[bill_type]['qtr'][yr]={}
|
bill_info[bill_type]['qtr'][yr]={}
|
||||||
pb = find_previous_bill( bill_type, bill_info, new_date )
|
pb = find_previous_bill( bill_type, bill_info, new_date )
|
||||||
if pb['estimated'] == 0:
|
if pb['estimated'] == 0:
|
||||||
print( f" FIXFIXFIX - have a prev real bill={pb['bill_date']} & this is first est - likely need to better apportion this bill into the quarters" )
|
|
||||||
allocate_by_quarter( bill_info, bill_type, yr, pb, bill )
|
allocate_by_quarter( bill_info, bill_type, yr, pb, bill )
|
||||||
|
else:
|
||||||
bill_info[bill_type]['qtr'][yr][q]=amt
|
if not q in bill_info[bill_type]['qtr'][yr]:
|
||||||
|
# first in this year, just init it...
|
||||||
|
bill_info[bill_type]['qtr'][yr][q]=0
|
||||||
|
bill_info[bill_type]['qtr'][yr][q]+=amt
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -155,12 +160,16 @@ def new_estimated_bill( bill_info, yr, bill_type, amt, new_date ):
|
|||||||
# NOTE: only ever called when there is a need to add a new bill
|
# NOTE: only ever called when there is a need to add a new bill
|
||||||
def add_missing_annual_bill_in_yr( bill_type, bill_info, yr ):
|
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:]
|
||||||
amt = bill_info[bill_type]['last_bill']['amount']
|
new_date= f'{yr}-{mm_dd}'
|
||||||
|
pb=find_previous_bill( bill_type, bill_info, new_date )
|
||||||
|
if pb:
|
||||||
|
amt = pb['amount']
|
||||||
|
else:
|
||||||
|
amt = bill_info[bill_type]['last_bill']['amount']
|
||||||
# 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 ):
|
amt += amt * bill_info[bill_type]['growth']/100
|
||||||
amt += amt * bill_info[bill_type]['growth']/100
|
|
||||||
|
|
||||||
new_estimated_bill( bill_info, yr, bill_type, amt, f'{yr}-{mm_dd}' )
|
new_estimated_bill( bill_info, yr, bill_type, amt, new_date )
|
||||||
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
|
||||||
@@ -248,6 +257,8 @@ def get_growth_value( bt, bill_type ):
|
|||||||
return el['ann_growth_avg']
|
return el['ann_growth_avg']
|
||||||
elif which == 'min':
|
elif which == 'min':
|
||||||
return el['ann_growth_min']
|
return el['ann_growth_min']
|
||||||
|
elif which == 'simple':
|
||||||
|
return el['ann_growth_simple']
|
||||||
else:
|
else:
|
||||||
return el['ann_growth_max']
|
return el['ann_growth_max']
|
||||||
|
|
||||||
@@ -313,7 +324,8 @@ 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 ):
|
||||||
# we have all the bills needed for yr - but dont be cute with qtrly, gas bills suck can have missing with 4 bills
|
# we have all the bills needed for yr - but dont be cute with qtrly, gas bills suck can have missing with 4 bills
|
||||||
if yr in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr]) == bill_info[bill_type]['num_ann_bills'] and bill_info[bill_type]['num_ann_bills'] !=4:
|
# > can occur when we add a real bill "on top of" an estimate.
|
||||||
|
if yr in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr]) >= bill_info[bill_type]['num_ann_bills'] and bill_info[bill_type]['num_ann_bills'] !=4:
|
||||||
continue
|
continue
|
||||||
add_missing_bills_for_yr( bill_type, bill_info, yr )
|
add_missing_bills_for_yr( bill_type, bill_info, yr )
|
||||||
derive_ann_growth( bill_type, bill_info )
|
derive_ann_growth( bill_type, bill_info )
|
||||||
@@ -333,7 +345,7 @@ def add_missing_bills_for_yr( bill_type, bill_info, yr ):
|
|||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Takes qtrly bills and start from 2nd year of bills (so we can estimate growth)
|
# Takes qtrly bills and start from 2nd year of bills (so we can estimate growth)
|
||||||
# and go through each bill allocating hte proportion of each bill to each
|
# and go through each bill allocating the proportion of each bill to each
|
||||||
# relevant quarter - to build more accurate totals. Would be mostly marginal
|
# relevant quarter - to build more accurate totals. Would be mostly marginal
|
||||||
# accept when Gas qtrly bills have 6 per year, and we need to guess say qtr4 in
|
# accept when Gas qtrly bills have 6 per year, and we need to guess say qtr4 in
|
||||||
# the future, we can't easily find corresponding bill form previous year, so
|
# the future, we can't easily find corresponding bill form previous year, so
|
||||||
@@ -344,12 +356,13 @@ def ProportionQtrlyData( bill_type, bill_info ):
|
|||||||
now_yr = datetime.date.today().year
|
now_yr = datetime.date.today().year
|
||||||
# FIX UP CRAPPY QUARTERLY BILLING PROPORTIONS (only useful as some gas bills are 6 / year!)
|
# FIX UP CRAPPY QUARTERLY BILLING PROPORTIONS (only useful as some gas bills are 6 / year!)
|
||||||
if bill_info[bill_type]['num_ann_bills']==4:
|
if bill_info[bill_type]['num_ann_bills']==4:
|
||||||
for yr in range( bill_info[bill_type]['first_bill_year'], now_yr+1):
|
for yr in range( bill_info[bill_type]['first_bill_year'], END_YEAR+1):
|
||||||
for b in bill_info[bill_type]['year'][yr]:
|
if yr in bill_info[bill_type]['year']:
|
||||||
pb = find_previous_bill( bill_type, bill_info, b['bill_date'] )
|
for b in bill_info[bill_type]['year'][yr]:
|
||||||
if not pb:
|
pb = find_previous_bill( bill_type, bill_info, b['bill_date'] )
|
||||||
continue
|
if not pb:
|
||||||
allocate_by_quarter( bill_info, bill_type, yr, pb, b )
|
continue
|
||||||
|
allocate_by_quarter( bill_info, bill_type, yr, pb, b )
|
||||||
return
|
return
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@@ -368,7 +381,7 @@ def derive_ann_growth( bill_type, bill_info ):
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
# just going to make sure we dont use estimated data in the last year of real data - can skew growths
|
# just going to make sure we dont use estimated data in the last year of real data - can skew growths
|
||||||
if yr == bill_info[bill_type]['last_real_bill_year']:
|
if yr == bill_info[bill_type]['last_real_bill_year'] or bill_info[bill_type]['num_ann_bills'] ==1:
|
||||||
skip_yr=False
|
skip_yr=False
|
||||||
for b in bill_info[bill_type]['year'][yr]:
|
for b in bill_info[bill_type]['year'][yr]:
|
||||||
if b['estimated']:
|
if b['estimated']:
|
||||||
@@ -397,24 +410,37 @@ def derive_ann_growth( bill_type, bill_info ):
|
|||||||
avg_growth = 0
|
avg_growth = 0
|
||||||
max_growth = 0
|
max_growth = 0
|
||||||
count = 0
|
count = 0
|
||||||
|
simple_first_yr=0
|
||||||
|
simple_last_yr=0
|
||||||
# start from year after first bill, so we can see annual growth from the following year onwards
|
# start from year after first bill, so we can see annual growth from the following year onwards
|
||||||
for yr in range( bill_info[bill_type]['first_bill_year']+1, now_yr+1):
|
for yr in range( bill_info[bill_type]['first_bill_year']+1, now_yr+1):
|
||||||
# if full data sets for consecutive years, work out annual growth stats
|
# if 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:
|
||||||
|
if simple_first_yr==0:
|
||||||
|
simple_first_yr=yr
|
||||||
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
|
||||||
count += 1
|
count += 1
|
||||||
|
simple_last_yr=yr
|
||||||
if growth < min_growth:
|
if growth < min_growth:
|
||||||
min_growth = growth
|
min_growth = growth
|
||||||
if growth > max_growth:
|
if growth > max_growth:
|
||||||
max_growth = growth
|
max_growth = growth
|
||||||
|
# data to work with
|
||||||
if count:
|
if count:
|
||||||
## print( f"Before sanity check, min={min_growth}, avg={avg_growth/count}, max_growth={max_growth}" )
|
if simple_first_yr != simple_last_yr:
|
||||||
# HACK FOR SANITY SAKE NOW - bills wont decrease normally, and 10% is unlikely for sustained growth
|
# calculate a simple growth with full year consecutive totals -> last - first / years
|
||||||
if min_growth< 0: min_growth=0
|
simple_growth=( ((total[simple_last_yr]-total[simple_first_yr])/(simple_last_yr-simple_first_yr)) / total[simple_first_yr] )*100.0
|
||||||
if avg_growth< 0 or avg_growth > 10: avg_growth = 3*count
|
else:
|
||||||
if max_growth>10 : max_growth = 9.99
|
# calculate a simple growth based on last - first / years - only 1 consecutive year I guess, so can't use it, use real first/last
|
||||||
set_bill_type_growth( bill_type, min_growth, avg_growth/count, max_growth )
|
if bill_info[bill_type]['first_bill_year'] != bill_info[bill_type]['last_real_bill_year']:
|
||||||
|
simple_growth=( ((total[bill_info[bill_type]['last_real_bill_year']]-total[bill_info[bill_type]['first_bill_year']])/(bill_info[bill_type]['last_real_bill_year']-bill_info[bill_type]['first_bill_year'])) / total[bill_info[bill_type]['first_bill_year']] )*100.0
|
||||||
|
set_bill_type_growth( bill_type, min_growth, avg_growth/count, max_growth, simple_growth )
|
||||||
else:
|
else:
|
||||||
# failsafe (just in case fill bills failed to add enough bills to average out)
|
# okay use last - first / years to get a simple_growth, just need bills from different years
|
||||||
print( f"{bill_type}: Unable to calculate growth!" )
|
if bill_info[bill_type]['first_bill_year'] != bill_info[bill_type]['last_real_bill_year']:
|
||||||
|
simple_growth=( ((total[bill_info[bill_type]['last_real_bill_year']]-total[bill_info[bill_type]['first_bill_year']])/(bill_info[bill_type]['last_real_bill_year']-bill_info[bill_type]['first_bill_year'])) / total[bill_info[bill_type]['first_bill_year']] )*100.0
|
||||||
|
set_bill_type_growth( bill_type, 0, 0, 0, simple_growth )
|
||||||
|
else:
|
||||||
|
# failsafe (just in case fill bills failed to add enough bills to average out)
|
||||||
|
print( f"{bill_type}: Unable to calculate growth!" )
|
||||||
|
|||||||
Reference in New Issue
Block a user