def test_make_val(): v = {0, "hello"} make_val(v)
def content(start_date, finish_date, g_contract_id, user): report_context = {} sess = None try: sess = Session() running_name, finished_name = chellow.dloads.make_names( "gas_virtual_bills.csv", user ) f = open(running_name, mode="w", newline="") writer = csv.writer(f, lineterminator="\n") g_contract = GContract.get_by_id(sess, g_contract_id) forecast_dt = forecast_date() month_start = utc_datetime(start_date.year, start_date.month, 1) month_finish = month_start + relativedelta(months=1) - HH bill_titles = contract_func(report_context, g_contract, "virtual_bill_titles")() writer.writerow( ["MPRN", "Site Code", "Site Name", "Account", "From", "To"] + bill_titles ) while not month_start > finish_date: period_start = hh_max(start_date, month_start) period_finish = hh_min(finish_date, month_finish) for g_era in ( sess.query(GEra) .distinct() .filter( GEra.g_contract == g_contract, GEra.start_date <= period_finish, or_(GEra.finish_date == null(), GEra.finish_date >= period_start), ) ): chunk_start = hh_max(g_era.start_date, period_start) chunk_finish = hh_min(g_era.finish_date, period_finish) data_source = GDataSource( sess, chunk_start, chunk_finish, forecast_dt, g_era, report_context, None, ) site = ( sess.query(Site) .join(SiteGEra) .filter(SiteGEra.g_era == g_era, SiteGEra.is_physical == true()) .one() ) vals = [ data_source.mprn, site.code, site.name, data_source.account, hh_format(data_source.start_date), hh_format(data_source.finish_date), ] contract_func(report_context, g_contract, "virtual_bill")(data_source) bill = data_source.bill for title in bill_titles: if title in bill: val = make_val(bill[title]) del bill[title] else: val = "" vals.append(val) for k in sorted(bill.keys()): vals.append(k) vals.append(str(bill[k])) writer.writerow(vals) month_start += relativedelta(months=1) month_finish = month_start + relativedelta(months=1) - HH except BadRequest as e: writer.writerow(["Problem: " + e.description]) except BaseException: msg = traceback.format_exc() sys.stderr.write(msg) writer.writerow([msg]) finally: if sess is not None: sess.close() if f is not None: f.close() os.rename(running_name, finished_name)
def _process_site( sess, report_context, forecast_from, start_date, finish_date, site, site_deltas, supply_id, era_maps, now, summary_titles, title_dict, era_rows, site_rows, ): calcs, displaced_era, site_gen_types = _make_calcs( sess, site, start_date, finish_date, supply_id, site_deltas, forecast_from, report_context, era_maps, ) site_month_data = defaultdict(int) site_ds = chellow.computer.SiteSource( sess, site, start_date, finish_date, forecast_from, report_context, displaced_era, deltas=site_deltas, ) bill_ids = set() if displaced_era is not None and supply_id is None: month_data = {} for sname in ( "import-net", "export-net", "import-gen", "export-gen", "import-3rd-party", "export-3rd-party", "msp", "used", "used-3rd-party", "billed-import-net", ): for xname in ("kwh", "gbp"): month_data[sname + "-" + xname] = 0 month_data["billed-supplier-import-net-gbp"] = None month_data["billed-dc-import-net-gbp"] = None month_data["billed-mop-import-net-gbp"] = None month_data["used-kwh"] = month_data["displaced-kwh"] = sum( hh["msp-kwh"] for hh in site_ds.hh_data) disp_supplier_contract = displaced_era.imp_supplier_contract disp_vb_function = chellow.computer.contract_func( report_context, disp_supplier_contract, "displaced_virtual_bill") if disp_vb_function is None: raise BadRequest( f"The supplier contract {disp_supplier_contract.name} " f" doesn't have the displaced_virtual_bill() function.") disp_vb_function(site_ds) disp_supplier_bill = site_ds.supplier_bill try: gbp = disp_supplier_bill["net-gbp"] except KeyError: disp_supplier_bill["problem"] += ( f"For the supply {site_ds.mpan_core} the virtual bill " f"{disp_supplier_bill} from the contract {disp_supplier_contract.name} " f" does not contain the net-gbp key.") month_data["used-gbp"] = month_data["displaced-gbp"] = gbp out = ([ now, None, disp_supplier_contract.name, None, None, displaced_era.meter_category, "displaced", None, None, None, None, site.code, site.name, "", finish_date, ] + [month_data[t] for t in summary_titles] + [None] + [None] * len(title_dict["mop"]) + [None] + [None] * len(title_dict["dc"]) + [None] + make_bill_row(title_dict["imp-supplier"], disp_supplier_bill)) era_rows.append([make_val(v) for v in out]) for k, v in month_data.items(): if v is not None: site_month_data[k] += v site_category = None site_sources = set() normal_reads = set() for i, (order, imp_mpan_core, exp_mpan_core, imp_ss, exp_ss) in enumerate(sorted(calcs, key=str)): if imp_ss is None: source_code = exp_ss.source_code supply = exp_ss.supply else: source_code = imp_ss.source_code supply = imp_ss.supply site_sources.add(source_code) month_data = {} for name in ( "import-net", "export-net", "import-gen", "export-gen", "import-3rd-party", "export-3rd-party", "displaced", "used", "used-3rd-party", "billed-import-net", ): for sname in ("kwh", "gbp"): month_data[name + "-" + sname] = 0 month_data["billed-supplier-import-net-gbp"] = 0 month_data["billed-dc-import-net-gbp"] = 0 month_data["billed-mop-import-net-gbp"] = 0 if imp_ss is not None: imp_supplier_contract = imp_ss.supplier_contract if imp_supplier_contract is not None: import_vb_function = contract_func(report_context, imp_supplier_contract, "virtual_bill") if import_vb_function is None: raise BadRequest( f"The supplier contract {imp_supplier_contract.name} " " doesn't have the virtual_bill() function.") import_vb_function(imp_ss) kwh = sum(hh["msp-kwh"] for hh in imp_ss.hh_data) imp_supplier_bill = imp_ss.supplier_bill try: gbp = imp_supplier_bill["net-gbp"] except KeyError: gbp = 0 imp_supplier_bill["problem"] += ( f"For the supply {imp_ss.mpan_core} the virtual bill " + f"{imp_supplier_bill} from the contract " + f"{imp_supplier_contract.name} does not contain the " + "net-gbp key.") if source_code in ("net", "gen-net"): month_data["import-net-gbp"] += gbp month_data["import-net-kwh"] += kwh month_data["used-gbp"] += gbp month_data["used-kwh"] += kwh if source_code == "gen-net": month_data["export-gen-kwh"] += kwh elif source_code == "3rd-party": month_data["import-3rd-party-gbp"] += gbp month_data["import-3rd-party-kwh"] += kwh month_data["used-3rd-party-gbp"] += gbp month_data["used-3rd-party-kwh"] += kwh month_data["used-gbp"] += gbp month_data["used-kwh"] += kwh elif source_code == "3rd-party-reverse": month_data["export-3rd-party-gbp"] += gbp month_data["export-3rd-party-kwh"] += kwh month_data["used-3rd-party-gbp"] -= gbp month_data["used-3rd-party-kwh"] -= kwh month_data["used-gbp"] -= gbp month_data["used-kwh"] -= kwh elif source_code == "gen": month_data["import-gen-kwh"] += kwh if exp_ss is not None: exp_supplier_contract = exp_ss.supplier_contract if exp_supplier_contract is not None: export_vb_function = contract_func(report_context, exp_supplier_contract, "virtual_bill") export_vb_function(exp_ss) kwh = sum(hh["msp-kwh"] for hh in exp_ss.hh_data) exp_supplier_bill = exp_ss.supplier_bill try: gbp = exp_supplier_bill["net-gbp"] except KeyError: exp_supplier_bill["problem"] += ( "For the supply " + imp_ss.mpan_core + " the virtual bill " + str(imp_supplier_bill) + " from the contract " + imp_supplier_contract.name + " does not contain the net-gbp key.") if source_code in ("net", "gen-net"): month_data["export-net-gbp"] += gbp month_data["export-net-kwh"] += kwh if source_code == "gen-net": month_data["import-gen-kwh"] += kwh elif source_code == "3rd-party": month_data["export-3rd-party-gbp"] += gbp month_data["export-3rd-party-kwh"] += kwh month_data["used-3rd-party-gbp"] -= gbp month_data["used-3rd-party-kwh"] -= kwh month_data["used-gbp"] -= gbp month_data["used-kwh"] -= kwh elif source_code == "3rd-party-reverse": month_data["import-3rd-party-gbp"] += gbp month_data["import-3rd-party-kwh"] += kwh month_data["used-3rd-party-gbp"] += gbp month_data["used-3rd-party-kwh"] += kwh month_data["used-gbp"] += gbp month_data["used-kwh"] += kwh elif source_code == "gen": month_data["export-gen-kwh"] += kwh sss = exp_ss if imp_ss is None else imp_ss dc_contract = sss.dc_contract if dc_contract is not None: sss.contract_func(dc_contract, "virtual_bill")(sss) dc_bill = sss.dc_bill gbp = dc_bill["net-gbp"] mop_contract = sss.mop_contract if mop_contract is not None: mop_bill_function = sss.contract_func(mop_contract, "virtual_bill") mop_bill_function(sss) mop_bill = sss.mop_bill gbp += mop_bill["net-gbp"] if source_code in ("3rd-party", "3rd-party-reverse"): month_data["import-3rd-party-gbp"] += gbp month_data["used-3rd-party-gbp"] += gbp else: month_data["import-net-gbp"] += gbp month_data["used-gbp"] += gbp generator_type = sss.generator_type_code if source_code in ("gen", "gen-net"): site_gen_types.add(generator_type) era_category = sss.measurement_type if CATEGORY_ORDER[site_category] < CATEGORY_ORDER[era_category]: site_category = era_category era_associates = set() if mop_contract is not None: era_associates.update( {s.site.code for s in sss.era.site_eras if not s.is_physical}) for bill in sess.query(Bill).filter( Bill.supply == supply, Bill.start_date <= finish_date, Bill.finish_date >= start_date, ): bill_ids.add(bill.id) bill_role_code = bill.batch.contract.market_role.code bill_start = bill.start_date bill_finish = bill.finish_date bill_duration = (bill_finish - bill_start).total_seconds() + (30 * 60) overlap_duration = (min(bill_finish, finish_date) - max( bill_start, start_date)).total_seconds() + (30 * 60) proportion = overlap_duration / bill_duration month_data["billed-import-net-kwh"] += proportion * float( bill.kwh) bill_prop_gbp = proportion * float(bill.net) month_data["billed-import-net-gbp"] += bill_prop_gbp if bill_role_code == "X": month_data[ "billed-supplier-import-net-gbp"] += bill_prop_gbp elif bill_role_code == "C": month_data["billed-dc-import-net-gbp"] += bill_prop_gbp elif bill_role_code == "M": month_data["billed-mop-import-net-gbp"] += bill_prop_gbp else: raise BadRequest("Role code not recognized.") if imp_ss is None: imp_supplier_contract_name = None pc_code = exp_ss.pc_code else: if imp_supplier_contract is None: imp_supplier_contract_name = "" else: imp_supplier_contract_name = imp_supplier_contract.name pc_code = imp_ss.pc_code if exp_ss is None: exp_supplier_contract_name = None else: if exp_supplier_contract is None: exp_supplier_contract_name = "" else: exp_supplier_contract_name = exp_supplier_contract.name out = ([ now, imp_mpan_core, imp_supplier_contract_name, exp_mpan_core, exp_supplier_contract_name, era_category, source_code, generator_type, sss.supply_name, sss.msn, pc_code, site.code, site.name, ",".join(sorted(list(era_associates))), finish_date, ] + [month_data[t] for t in summary_titles] + [None] + make_bill_row(title_dict["mop"], mop_bill) + [None] + make_bill_row(title_dict["dc"], dc_bill)) if imp_ss is None: out += [None] * (len(title_dict["imp-supplier"]) + 1) else: out += [None] + make_bill_row(title_dict["imp-supplier"], imp_supplier_bill) for n in imp_ss.normal_reads: normal_reads.add((imp_mpan_core, n)) if exp_ss is not None: out += [None] + make_bill_row(title_dict["exp-supplier"], exp_supplier_bill) for k, v in month_data.items(): site_month_data[k] += v era_rows.append([make_val(v) for v in out]) for bill in (sess.query(Bill).join(Supply).join( Supply.eras).join(SiteEra).filter( SiteEra.site == site, SiteEra.is_physical == true(), Bill.start_date <= finish_date, Bill.finish_date >= start_date, )): if bill.id in bill_ids: continue month_data = {} for name in ( "import-net", "export-net", "import-gen", "export-gen", "import-3rd-party", "export-3rd-party", "displaced", "used", "used-3rd-party", "billed-import-net", ): for sname in ("kwh", "gbp"): month_data[name + "-" + sname] = 0 month_data["billed-supplier-import-net-gbp"] = 0 month_data["billed-dc-import-net-gbp"] = 0 month_data["billed-mop-import-net-gbp"] = 0 for bill in sess.query(Bill).filter( Bill.supply == bill.supply, Bill.start_date <= finish_date, Bill.finish_date >= start_date, ): bill_ids.add(bill.id) bill_role_code = bill.batch.contract.market_role.code bill_start = bill.start_date bill_finish = bill.finish_date bill_duration = (bill_finish - bill_start).total_seconds() + (30 * 60) overlap_duration = (min(bill_finish, finish_date) - max( bill_start, start_date)).total_seconds() + (30 * 60) proportion = overlap_duration / bill_duration month_data["billed-import-net-kwh"] += proportion * float(bill.kwh) bill_prop_gbp = proportion * float(bill.net) month_data["billed-import-net-gbp"] += bill_prop_gbp if bill_role_code == "X": month_data["billed-supplier-import-net-gbp"] += bill_prop_gbp site_month_data[ "billed-supplier-import-net-gbp"] += bill_prop_gbp elif bill_role_code == "C": month_data["billed-dc-import-net-gbp"] += bill_prop_gbp site_month_data["billed-dc-import-net-gbp"] += bill_prop_gbp elif bill_role_code == "M": month_data["billed-mop-import-net-gbp"] += bill_prop_gbp site_month_data["billed-mop-import-net-gbp"] += bill_prop_gbp else: raise BadRequest("Role code not recognized.") era = sess.execute( select(Era).filter(Era.supply == bill.supply).order_by( Era.start_date.desc())).first()[0] imp_supplier_contract = era.imp_supplier_contract exp_supplier_contract = era.exp_supplier_contract out = [ now, era.imp_mpan_core, None if imp_supplier_contract is None else imp_supplier_contract.name, era.exp_mpan_core, None if exp_supplier_contract is None else exp_supplier_contract.name, era.meter_category, era.supply.source.code, None, era.supply.name, era.msn, era.pc.code, site.code, site.name, None, finish_date, ] + [month_data[t] for t in summary_titles] era_rows.append([make_val(v) for v in out]) site_row = [ now, site.code, site.name, ", ".join( s.code for s in site.find_linked_sites(sess, start_date, finish_date)), finish_date, site_category, ", ".join(sorted(list(site_sources))), ", ".join(sorted(list(site_gen_types))), ] + [site_month_data[k] for k in summary_titles] site_rows.append([make_val(v) for v in site_row]) sess.rollback() return normal_reads
def content(base_name, site_id, g_supply_id, user, compression, start_date, months): now = utc_datetime_now() report_context = {} sess = None try: sess = Session() base_name.append( hh_format(start_date).replace(' ', '_').replace(':', '').replace('-', '')) base_name.append('for') base_name.append(str(months)) base_name.append('months') finish_date = start_date + relativedelta(months=months) forecast_from = chellow.computer.forecast_date() sites = sess.query(Site).distinct().order_by(Site.code) if site_id is not None: site = Site.get_by_id(sess, site_id) sites = sites.filter(Site.id == site.id) base_name.append('site') base_name.append(site.code) if g_supply_id is not None: g_supply = GSupply.get_by_id(sess, g_supply_id) base_name.append('g_supply') base_name.append(str(g_supply.id)) sites = sites.join(SiteGEra).join(GEra).filter( GEra.g_supply == g_supply) running_name, finished_name = chellow.dloads.make_names( '_'.join(base_name) + '.ods', user) rf = open(running_name, "wb") site_rows = [] g_era_rows = [] era_header_titles = [ 'creation_date', 'mprn', 'supply_name', 'exit_zone', 'msn', 'unit', 'contract', 'site_id', 'site_name', 'associated_site_ids', 'month' ] site_header_titles = [ 'creation_date', 'site_id', 'site_name', 'associated_site_ids', 'month' ] summary_titles = ['kwh', 'gbp', 'billed_kwh', 'billed_gbp'] vb_titles = [] conts = sess.query(GContract).join(GEra).join(GSupply).filter( GEra.start_date <= finish_date, or_(GEra.finish_date == null(), GEra.finish_date >= start_date)).distinct().order_by( GContract.id) if g_supply_id is not None: conts = conts.filter(GEra.g_supply_id == g_supply_id) for cont in conts: title_func = chellow.computer.contract_func( report_context, cont, 'virtual_bill_titles') if title_func is None: raise Exception("For the contract " + cont.name + " there doesn't seem " + "to be a 'virtual_bill_titles' function.") for title in title_func(): if title not in vb_titles: vb_titles.append(title) g_era_rows.append(era_header_titles + summary_titles + vb_titles) site_rows.append(site_header_titles + summary_titles) sites = sites.all() month_start = start_date while month_start < finish_date: month_finish = month_start + relativedelta(months=1) - HH for site in sites: site_kwh = site_gbp = site_billed_kwh = site_billed_gbp = 0 for g_era in sess.query(GEra).join(SiteGEra).filter( SiteGEra.site == site, SiteGEra.is_physical == true(), GEra.start_date <= month_finish, or_(GEra.finish_date == null(), GEra.finish_date >= month_start)).options( joinedload(GEra.g_contract), joinedload(GEra.g_supply), joinedload(GEra.g_supply).joinedload( GSupply.g_exit_zone)).order_by(GEra.id): g_supply = g_era.g_supply if g_supply_id is not None and g_supply.id != g_supply_id: continue ss_start = hh_max(g_era.start_date, month_start) ss_finish = hh_min(g_era.finish_date, month_finish) ss = GDataSource(sess, ss_start, ss_finish, forecast_from, g_era, report_context, None) contract = g_era.g_contract vb_function = contract_func(report_context, contract, 'virtual_bill') if vb_function is None: raise BadRequest( "The contract " + contract.name + " doesn't have the virtual_bill() function.") vb_function(ss) bill = ss.bill try: gbp = bill['net_gbp'] except KeyError: gbp = 0 bill['problem'] += 'For the supply ' + ss.mprn + \ ' the virtual bill ' + str(bill) + \ ' from the contract ' + contract.name + \ ' does not contain the net_gbp key.' try: kwh = bill['kwh'] except KeyError: kwh = 0 bill['problem'] += "For the supply " + ss.mprn + \ " the virtual bill " + str(bill) + \ " from the contract " + contract.name + \ " does not contain the 'kwh' key." billed_kwh = billed_gbp = 0 g_era_associates = { s.site.code for s in g_era.site_g_eras if not s.is_physical } for g_bill in sess.query(GBill).filter( GBill.g_supply == g_supply, GBill.start_date <= ss_finish, GBill.finish_date >= ss_start): bill_start = g_bill.start_date bill_finish = g_bill.finish_date bill_duration = ( bill_finish - bill_start).total_seconds() + \ (30 * 60) overlap_duration = (min(bill_finish, ss_finish) - max( bill_start, ss_start)).total_seconds() + (30 * 60) overlap_proportion = overlap_duration / bill_duration billed_kwh += overlap_proportion * float(g_bill.kwh) billed_gbp += overlap_proportion * float(g_bill.net) associated_site_ids = ','.join(sorted(g_era_associates)) g_era_rows.append([ now, g_supply.mprn, g_supply.name, g_supply.g_exit_zone .code, g_era.msn, g_era.g_unit.code, contract.name, site.code, site.name, associated_site_ids, month_finish, kwh, gbp, billed_kwh, billed_gbp ] + [make_val(bill.get(t)) for t in vb_titles]) site_kwh += kwh site_gbp += gbp site_billed_kwh += billed_kwh site_billed_gbp += billed_gbp linked_sites = ', '.join(s.code for s in site.find_linked_sites( sess, month_start, month_finish)) site_rows.append([ now, site.code, site.name, linked_sites, month_finish, site_kwh, site_gbp, site_billed_kwh, site_billed_gbp ]) sess.rollback() write_spreadsheet(rf, compression, site_rows, g_era_rows) month_start += relativedelta(months=1) except BadRequest as e: msg = e.description + traceback.format_exc() sys.stderr.write(msg + '\n') site_rows.append(["Problem " + msg]) write_spreadsheet(rf, compression, site_rows, g_era_rows) except BaseException: msg = traceback.format_exc() sys.stderr.write(msg + '\n') site_rows.append(["Problem " + msg]) write_spreadsheet(rf, compression, site_rows, g_era_rows) finally: if sess is not None: sess.close() try: rf.close() os.rename(running_name, finished_name) except BaseException: msg = traceback.format_exc() r_name, f_name = chellow.dloads.make_names('error.txt', user) ef = open(r_name, "w") ef.write(msg + '\n') ef.close()
def content(site_id, g_supply_id, user, compression, finish_year, finish_month, months, now=None): if now is None: now = ct_datetime_now() report_context = {} sess = None month_list = list( c_months_u(finish_year=finish_year, finish_month=finish_month, months=months)) start_date, finish_date = month_list[0][0], month_list[-1][-1] try: sess = Session() base_name = [ "g_monthly_duration", hh_format(start_date).replace(" ", "_").replace(":", "").replace("-", ""), "for", str(months), "months", ] forecast_from = chellow.computer.forecast_date() sites = (sess.query(Site).join(SiteGEra).join(GEra).filter( SiteGEra.is_physical == true()).distinct().order_by(Site.code)) if site_id is not None: site = Site.get_by_id(sess, site_id) sites = sites.filter(Site.id == site.id) base_name.append("site") base_name.append(site.code) if g_supply_id is not None: g_supply = GSupply.get_by_id(sess, g_supply_id) base_name.append("g_supply") base_name.append(str(g_supply.id)) sites = sites.filter(GEra.g_supply == g_supply) running_name, finished_name = chellow.dloads.make_names( "_".join(base_name) + ".ods", user) rf = open(running_name, "wb") site_rows = [] g_era_rows = [] era_header_titles = [ "creation_date", "mprn", "supply_name", "exit_zone", "msn", "unit", "contract", "site_id", "site_name", "associated_site_ids", "month", ] site_header_titles = [ "creation_date", "site_id", "site_name", "associated_site_ids", "month", ] summary_titles = ["kwh", "gbp", "billed_kwh", "billed_gbp"] vb_titles = [] conts = (sess.query(GContract).join(GEra).join(GSupply).filter( GEra.start_date <= finish_date, or_(GEra.finish_date == null(), GEra.finish_date >= start_date), ).distinct().order_by(GContract.id)) if g_supply_id is not None: conts = conts.filter(GEra.g_supply_id == g_supply_id) for cont in conts: title_func = chellow.computer.contract_func( report_context, cont, "virtual_bill_titles") if title_func is None: raise Exception("For the contract " + cont.name + " there doesn't seem " + "to be a 'virtual_bill_titles' function.") for title in title_func(): if title not in vb_titles: vb_titles.append(title) g_era_rows.append(era_header_titles + summary_titles + vb_titles) site_rows.append(site_header_titles + summary_titles) for month_start, month_finish in month_list: for site in sites.filter( GEra.start_date <= month_finish, or_(GEra.finish_date == null(), GEra.finish_date >= month_start), ): site_kwh = site_gbp = site_billed_kwh = site_billed_gbp = 0 for g_era in (sess.query(GEra).join(SiteGEra).filter( SiteGEra.site == site, SiteGEra.is_physical == true(), GEra.start_date <= month_finish, or_(GEra.finish_date == null(), GEra.finish_date >= month_start), ).options( joinedload(GEra.g_contract), joinedload(GEra.g_supply), joinedload(GEra.g_supply).joinedload( GSupply.g_exit_zone), ).order_by(GEra.id)): g_supply = g_era.g_supply if g_supply_id is not None and g_supply.id != g_supply_id: continue ss_start = hh_max(g_era.start_date, month_start) ss_finish = hh_min(g_era.finish_date, month_finish) ss = GDataSource( sess, ss_start, ss_finish, forecast_from, g_era, report_context, None, ) contract = g_era.g_contract vb_function = contract_func(report_context, contract, "virtual_bill") if vb_function is None: raise BadRequest( "The contract " + contract.name + " doesn't have the virtual_bill() function.") vb_function(ss) bill = ss.bill try: gbp = bill["net_gbp"] except KeyError: gbp = 0 bill["problem"] += ( "For the supply " + ss.mprn + " the virtual bill " + str(bill) + " from the contract " + contract.name + " does not contain the net_gbp key.") try: kwh = bill["kwh"] except KeyError: kwh = 0 bill["problem"] += ("For the supply " + ss.mprn + " the virtual bill " + str(bill) + " from the contract " + contract.name + " does not contain the 'kwh' key.") billed_kwh = billed_gbp = 0 g_era_associates = { s.site.code for s in g_era.site_g_eras if not s.is_physical } for g_bill in sess.query(GBill).filter( GBill.g_supply == g_supply, GBill.start_date <= ss_finish, GBill.finish_date >= ss_start, ): bill_start = g_bill.start_date bill_finish = g_bill.finish_date bill_duration = (bill_finish - bill_start ).total_seconds() + (30 * 60) overlap_duration = (min(bill_finish, ss_finish) - max( bill_start, ss_start)).total_seconds() + (30 * 60) overlap_proportion = overlap_duration / bill_duration billed_kwh += overlap_proportion * float(g_bill.kwh) billed_gbp += overlap_proportion * float(g_bill.net) associated_site_ids = ",".join(sorted(g_era_associates)) g_era_rows.append([ make_val(v) for v in [ now, g_supply.mprn, g_supply.name, g_supply.g_exit_zone.code, g_era.msn, g_era.g_unit.code, contract.name, site.code, site.name, associated_site_ids, month_finish, kwh, gbp, billed_kwh, billed_gbp, ] ] + [make_val(bill.get(t)) for t in vb_titles]) site_kwh += kwh site_gbp += gbp site_billed_kwh += billed_kwh site_billed_gbp += billed_gbp linked_sites = ", ".join(s.code for s in site.find_linked_sites( sess, month_start, month_finish)) site_rows.append([ make_val(v) for v in [ now, site.code, site.name, linked_sites, month_finish, site_kwh, site_gbp, site_billed_kwh, site_billed_gbp, ] ]) sess.rollback() write_spreadsheet(rf, compression, site_rows, g_era_rows) except BadRequest as e: site_rows.append(["Problem " + e.description]) write_spreadsheet(rf, compression, site_rows, g_era_rows) except BaseException: msg = traceback.format_exc() sys.stderr.write(msg + "\n") site_rows.append(["Problem " + msg]) write_spreadsheet(rf, compression, site_rows, g_era_rows) finally: if sess is not None: sess.close() try: rf.close() os.rename(running_name, finished_name) except BaseException: msg = traceback.format_exc() r_name, f_name = chellow.dloads.make_names("error.txt", user) ef = open(r_name, "w") ef.write(msg + "\n") ef.close()
def make_bill_row(titles, bill): return [make_val(bill.get(t)) for t in titles]