diff --git a/bpfin/financials/saving.py b/bpfin/financials/saving.py new file mode 100644 index 0000000000000000000000000000000000000000..2c8a5df5675ffc28a1fb458fe21b4fb1d670d061 --- /dev/null +++ b/bpfin/financials/saving.py @@ -0,0 +1,84 @@ +import datetime +from bpfin.utilbills.bill_lib import cal_last_day +from bpfin.utilbills.bill_lib import annualizing_projection + + +class Saving(): + """ + Calculate savings and project bills with commissioning date considered. + Attributes: + commissioning_date (date): the date that construction work finished, saving starts at NEXT month + proforma_date (list): list of dates, months of pro-forma time period + prior_saving_list (list): list of float, usage or charge without (prior to) savings + post_saving_list (list): list of float, usage or charge with (post to) savings + proforma_bill (list): monthly usage or charge, for pro-forma period + Data before commissioning date == historical + Data after commissioning date == post saving data + proforma_saving (list): monthly savings on usage or charge, for pro-forma period + Data before commissioning date == historical + Data after commissioning date == post saving data + first_year_saving (float): first year saving, usage or charge + """ + def __init__(self, commissioning_date, proforma_date, prior_saving_list, post_saving_list): + self.commissioning_date = commissioning_date + self.proforma_date = proforma_date + self.prior_saving_list = prior_saving_list + self.post_saving_list = post_saving_list + self.proforma_bill = [] + self.proforma_saving = [] + self.first_year_saving = None + + saving_start_date = datetime.date( + self.commissioning_date.year, + self.commissioning_date.month, + cal_last_day(self.commissioning_date.year, self.commissioning_date.month)) + saving_dict = {} + bill_dict = {} + first_year_saving = 0 + first_yr_count = 0 + for date, prior, post in zip(proforma_date, prior_saving_list, post_saving_list): + if date > saving_start_date: + saving_dict[date] = prior - post + bill_dict[date] = post + if first_yr_count <= 12: + first_year_saving += prior - post + first_yr_count += 1 + else: + saving_dict[date] = 0 + bill_dict[date] = prior + self.proforma_saving = list(saving_dict.values()) + self.proforma_bill = list(bill_dict.values()) + self.first_year_saving = first_year_saving + + def get_proforma_bill(self): + """ + Get proforma_bill + Return: + list: proforma_bill + """ + return self.proforma_bill + + def get_proforma_saving(self): + """ + Get proforma_saving + Return: + list: proforma_saving + """ + return self.proforma_saving + + def get_first_year_saving(self): + """ + Get first year saving + Return: + float: sum of first 12 months of savings + """ + return self.first_year_saving + + def get_annual_bill(self): + """ + Calculate and return annual pro-forma usage or charge + Return: + dictionary: dict of annual item, {year: annual usage or charge} + """ + annual_proforma_bill = annualizing_projection(self.proforma_date, self.proforma_bill) + return annual_proforma_bill diff --git a/bpfin/tests/test_financials/test_saving.py b/bpfin/tests/test_financials/test_saving.py new file mode 100644 index 0000000000000000000000000000000000000000..cf6be7b44d4e0d332bf4737bb201be7a6fa9d3df --- /dev/null +++ b/bpfin/tests/test_financials/test_saving.py @@ -0,0 +1,33 @@ +import datetime +from bpfin.financials.saving import Saving + + +def test_Saving(): + input_proforma_date = [ + datetime.date(2017, 1, 31), + datetime.date(2017, 2, 28), + datetime.date(2017, 3, 31), + datetime.date(2017, 4, 30), + datetime.date(2017, 5, 31), + datetime.date(2017, 6, 30), + datetime.date(2017, 7, 31), + datetime.date(2017, 8, 31), + datetime.date(2017, 9, 30), + datetime.date(2017, 10, 31), + datetime.date(2017, 11, 30), + datetime.date(2017, 12, 31), ] + input_commissioning_date = datetime.date(2017, 3, 14) + input_prior_list = [100] * 12 + input_post_list = [100, 90, 80, 70, 60, 50, 40, 30, 40, 50, 60, 70] + + output_saving = [0, 0, 0, 30, 40, 50, 60, 70, 60, 50, 40, 30] + output_bill = [100, 100, 100, 70, 60, 50, 40, 30, 40, 50, 60, 70] + elec_saving = Saving(input_commissioning_date, input_proforma_date, input_prior_list, input_post_list) + result_saving = elec_saving.get_proforma_saving() + result_bill = elec_saving.get_proforma_bill() + assert output_saving == result_saving + assert output_bill == result_bill + assert elec_saving.get_first_year_saving() == 430 + assert elec_saving.get_annual_bill() == {2017: 770} + # print('1st yr saving =', elec_saving.get_first_year_saving()) + # print('annual_bill =', elec_saving.get_annual_bill()) diff --git a/bpfin/utilbills/data_generation.py b/bpfin/utilbills/data_generation.py index d7219d8e2c0fc2fe1f8801489536159c4b77ca76..d4552bbbdbc1a3a48d8b2425d0f80e04fb5baa3d 100644 --- a/bpfin/utilbills/data_generation.py +++ b/bpfin/utilbills/data_generation.py @@ -1,6 +1,11 @@ +# import datetime +# import copy # from bpfin.utilbills.bill_month_normalize_rough import bill_month_normalize_rough # from bpfin.utilbills.bill_prior_proj_rough import bill_prior_proj_rough +# from bpfin.financials.saving import Saving +# from bpfin.lib import other as lib # from bpfin.utilbills import bill_lib as bl +# from bpfin.financials import financial_lib as fl # from bpfin.tests.testdata import sample_data as db @@ -11,3 +16,24 @@ # print(annual_bill_electricity) + +# prior_energy_bill = db.bill_overview_organized +# raw_income_input = db.raw_income_input + +# IS_prior = fl.Income_Statement_Table(raw_income_input, prior_energy_bill) +# IS_prior.project(-2.0, db.analysis_date, prior_energy_bill) + +# post_energy_bill = copy.deepcopy(db.bill_overview_organized) +# saving = Saving(datetime.date(2017, 11, 1), db.proforma_date_to, db.prior_proj_rough_charge, db.post_proj_rough_charge) +# # print(saving_list) + +# post_energy_bill['electricity'] = saving.get_annual_bill() + +# IS_post = fl.Income_Statement_Table(raw_income_input, post_energy_bill) +# IS_post.project(-2.0, db.analysis_date, post_energy_bill) + +# prior_noi = (IS_prior.get_noi_dict().values()) +# post_noi = (IS_post.get_noi_dict().values()) + +# print(lib.sublist(post_noi, prior_noi)) +# # print(bl.annualizing_projection(saving.proforma_date, saving.get_proforma_saving()))