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
|
||||
import datetime
|
||||
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] = {}
|
||||
for i in range(1,5):
|
||||
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
|
||||
# next quarter
|
||||
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:
|
||||
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']:
|
||||
bill_info[bill_type]['qtr'][yr]={}
|
||||
pb = find_previous_bill( bill_type, bill_info, new_date )
|
||||
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 )
|
||||
|
||||
bill_info[bill_type]['qtr'][yr][q]=amt
|
||||
else:
|
||||
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
|
||||
|
||||
|
||||
@@ -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
|
||||
def add_missing_annual_bill_in_yr( bill_type, bill_info, yr ):
|
||||
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...
|
||||
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
|
||||
|
||||
# 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']
|
||||
elif which == 'min':
|
||||
return el['ann_growth_min']
|
||||
elif which == 'simple':
|
||||
return el['ann_growth_simple']
|
||||
else:
|
||||
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
|
||||
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
|
||||
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
|
||||
add_missing_bills_for_yr( bill_type, bill_info, yr )
|
||||
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)
|
||||
# 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
|
||||
# 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
|
||||
@@ -344,12 +356,13 @@ def ProportionQtrlyData( bill_type, bill_info ):
|
||||
now_yr = datetime.date.today().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:
|
||||
for yr in range( bill_info[bill_type]['first_bill_year'], now_yr+1):
|
||||
for b in bill_info[bill_type]['year'][yr]:
|
||||
pb = find_previous_bill( bill_type, bill_info, b['bill_date'] )
|
||||
if not pb:
|
||||
continue
|
||||
allocate_by_quarter( bill_info, bill_type, yr, pb, b )
|
||||
for yr in range( bill_info[bill_type]['first_bill_year'], END_YEAR+1):
|
||||
if yr in bill_info[bill_type]['year']:
|
||||
for b in bill_info[bill_type]['year'][yr]:
|
||||
pb = find_previous_bill( bill_type, bill_info, b['bill_date'] )
|
||||
if not pb:
|
||||
continue
|
||||
allocate_by_quarter( bill_info, bill_type, yr, pb, b )
|
||||
return
|
||||
|
||||
################################################################################
|
||||
@@ -368,7 +381,7 @@ def derive_ann_growth( bill_type, bill_info ):
|
||||
continue;
|
||||
|
||||
# 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
|
||||
for b in bill_info[bill_type]['year'][yr]:
|
||||
if b['estimated']:
|
||||
@@ -397,24 +410,37 @@ def derive_ann_growth( bill_type, bill_info ):
|
||||
avg_growth = 0
|
||||
max_growth = 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
|
||||
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 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
|
||||
avg_growth += growth
|
||||
count += 1
|
||||
simple_last_yr=yr
|
||||
if growth < min_growth:
|
||||
min_growth = growth
|
||||
if growth > max_growth:
|
||||
max_growth = growth
|
||||
# data to work with
|
||||
if count:
|
||||
## print( f"Before sanity check, min={min_growth}, avg={avg_growth/count}, max_growth={max_growth}" )
|
||||
# HACK FOR SANITY SAKE NOW - bills wont decrease normally, and 10% is unlikely for sustained growth
|
||||
if min_growth< 0: min_growth=0
|
||||
if avg_growth< 0 or avg_growth > 10: avg_growth = 3*count
|
||||
if max_growth>10 : max_growth = 9.99
|
||||
set_bill_type_growth( bill_type, min_growth, avg_growth/count, max_growth )
|
||||
if simple_first_yr != simple_last_yr:
|
||||
# calculate a simple growth with full year consecutive totals -> last - first / years
|
||||
simple_growth=( ((total[simple_last_yr]-total[simple_first_yr])/(simple_last_yr-simple_first_yr)) / total[simple_first_yr] )*100.0
|
||||
else:
|
||||
# calculate a simple growth based on last - first / years - only 1 consecutive year I guess, so can't use it, use real first/last
|
||||
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:
|
||||
# failsafe (just in case fill bills failed to add enough bills to average out)
|
||||
print( f"{bill_type}: Unable to calculate growth!" )
|
||||
# okay use last - first / years to get a simple_growth, just need bills from different years
|
||||
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