def test_Supply_get_by_MPAN_core(sess): mpan_core = "22 1737 1873 221" with pytest.raises( BadRequest, match=f"The MPAN core {mpan_core} is not set up in Chellow."): Supply.get_by_mpan_core(sess, mpan_core)
def _process_MTR(elements, headers): if headers["message_type"] != "UTLBIL": return sess = headers["sess"] try: mpan_core = headers["mpan_core"] except KeyError: raise BadRequest("The mpan_core can't be found for this bill.") start_date = headers["start_date"] reads = headers["reads"] supply = Supply.get_by_mpan_core(sess, mpan_core) era = supply.find_era_at(sess, start_date) bill_elements = [] if era is None: era = supply.find_last_era(sess) if era is None: imp_mpan_core = "" ssc = Ssc.get_by_code(sess, "0393") else: imp_mpan_core = era.imp_mpan_core ssc = Ssc.get_by_code(sess, "0393") if era.ssc is None else era.ssc try: ssc_lookup = imp_mpan_core tpr_map = SSC_MAP[ssc_lookup] except KeyError: ssc_lookup = ssc.code try: tpr_map = SSC_MAP[ssc_lookup] except KeyError: raise BadRequest(f"The SSC {ssc_lookup} isn't in the SSC_MAP.") for read in reads: desc = read["tpr_code"] try: read["tpr_code"] = tpr_map[desc] except KeyError: raise BadRequest(f"The description {desc} isn't in the SSC_MAP " f"for the SSC {ssc_lookup}.") for el in headers["bill_elements"]: if el.desc == "Energy Charges": # If it's an unmetered supply there is only one charge # line in the EDI, no mater how many TPRs there are. # Therefore we split the charge evenly between the # TPRs. mrs = ssc.measurement_requirements num_mrs = len(mrs) gbp = el.gbp / num_mrs cons = el.cons / num_mrs for mr in mrs: tpr_code = mr.tpr.code titles = (tpr_code + "-gbp", tpr_code + "-rate", tpr_code + "-kwh") bill_elements.append( BillElement(gbp=gbp, rate=el.rate, cons=cons, titles=titles, desc=None)) else: if el.titles is None: try: tpr = tpr_map[el.desc] except KeyError: raise BadRequest( f"The billing element description {el.desc} " f"isn't in the SSC_MAP for the SSC {ssc_lookup}.") titles = (tpr + "-gbp", tpr + "-rate", tpr + "-kwh") else: titles = el.titles bill_elements.append( BillElement(gbp=el.gbp, titles=titles, rate=el.rate, cons=el.cons, desc=None)) breakdown = headers["breakdown"] for bill_el in bill_elements: eln_gbp, eln_rate, eln_cons = bill_el.titles try: breakdown[eln_gbp] += bill_el.gbp except KeyError: breakdown[eln_gbp] = bill_el.gbp rate = bill_el.rate if eln_rate is not None and rate is not None: try: rates = breakdown[eln_rate] except KeyError: rates = breakdown[eln_rate] = set() rates.add(rate) cons = bill_el.cons if eln_cons is not None and cons is not None: try: breakdown[eln_cons] += cons except KeyError: breakdown[eln_cons] = cons return { "kwh": headers["kwh"], "reference": headers["reference"], "mpan_core": mpan_core, "issue_date": headers["issue_date"], "account": headers["account"], "start_date": start_date, "finish_date": headers["finish_date"], "net": headers["net"], "vat": headers["vat"], "gross": headers["gross"], "breakdown": breakdown, "reads": reads, "bill_type_code": headers["bill_type_code"], }
def run(self): sess = None try: sess = Session() batch = Batch.get_by_id(sess, self.batch_id) bill_types = keydefaultdict( lambda k: BillType.get_by_code(sess, k)) tprs = keydefaultdict(lambda k: None if k is None else Tpr.get_by_code(sess, k)) read_types = keydefaultdict( lambda k: ReadType.get_by_code(sess, k)) for bf in (sess.query(BatchFile).filter( BatchFile.batch == batch).order_by( BatchFile.upload_timestamp)): self.parser = _process_batch_file(sess, bf, self._log) for self.bill_num, raw_bill in enumerate( self.parser.make_raw_bills()): if "error" in raw_bill: self.failed_bills.append(raw_bill) else: try: mpan_core = raw_bill["mpan_core"] supply = Supply.get_by_mpan_core(sess, mpan_core) with sess.begin_nested(): bill = batch.insert_bill( sess, raw_bill["account"], raw_bill["reference"], raw_bill["issue_date"], raw_bill["start_date"], raw_bill["finish_date"], raw_bill["kwh"], raw_bill["net"], raw_bill["vat"], raw_bill["gross"], bill_types[raw_bill["bill_type_code"]], raw_bill["breakdown"], supply, ) for raw_read in raw_bill["reads"]: bill.insert_read( sess, tprs[raw_read["tpr_code"]], raw_read["coefficient"], raw_read["units"], raw_read["msn"], raw_read["mpan"], raw_read["prev_date"], raw_read["prev_value"], read_types[raw_read["prev_type_code"]], raw_read["pres_date"], raw_read["pres_value"], read_types[raw_read["pres_type_code"]], ) self.successful_bills.append(raw_bill) except KeyError as e: err = raw_bill.get("error", "") raw_bill["error"] = err + " " + str(e) self.failed_bills.append(raw_bill) except BadRequest as e: raw_bill["error"] = str(e.description) self.failed_bills.append(raw_bill) if len(self.failed_bills) == 0: sess.commit() self._log( "All the bills have been successfully loaded and attached " "to the batch.") else: sess.rollback() self._log(f"The import has finished, but there were " f"{len(self.failed_bills)} failures, and so the " f"whole import has been rolled back.") except BadRequest as e: sess.rollback() self._log(f"Problem: {e.description}") except BaseException: sess.rollback() self._log(f"I've encountered a problem: {traceback.format_exc()}") finally: if sess is not None: sess.close()
def _process( sess, ecoes_lines, exclude_mpan_cores, ignore_mpan_cores_msn, f, show_ignored, report_run, ): writer = csv.writer(f, lineterminator="\n") mpans = [] for exp in (Era.imp_mpan_core, Era.exp_mpan_core): for (v,) in sess.execute( select(exp) .join(Supply) .join(Source) .join(Supply.dno) .filter( Party.dno_code.notin_(("88", "99")), Era.finish_date == null(), Source.code != "3rd-party", exp.notin_(exclude_mpan_cores), exp != null(), ) .distinct() .order_by(exp) ): mpans.append(v) ecoes_mpans = {} parser = iter(csv.reader(ecoes_lines)) next(parser) # Skip titles for values in parser: ecoes_titles = [ "mpan-core", "address-line-1", "address-line-2", "address-line-3", "address-line-4", "address-line-5", "address-line-6", "address-line-7", "address-line-8", "address-line-9", "post-code", "supplier", "registration-from", "mtc", "mtc-date", "llfc", "llfc-from", "pc", "ssc", "measurement-class", "energisation-status", "da", "dc", "mop", "mop-appoint-date", "gsp-group", "gsp-effective-from", "dno", "msn", "meter-install-date", "meter-type", "map-id", ] ecoes_row = dict(zip(ecoes_titles, map(str.strip, values))) mpan_core = ecoes_row["mpan-core"] mpan_spaces = " ".join( ( mpan_core[:2], mpan_core[2:6], mpan_core[6:10], mpan_core[-3:], ) ) if mpan_spaces in exclude_mpan_cores: continue ecoes_row["mpan_spaces"] = mpan_spaces if mpan_spaces in ecoes_mpans: prev_row = ecoes_mpans[mpan_spaces] prev_row["meter_count"] += 1 else: ecoes_row["meter_count"] = 1 ecoes_mpans[mpan_spaces] = ecoes_row titles = ( "mpan_core", "mpan_core_no_spaces", "ecoes_pc", "chellow_pc", "ecoes_mtc", "chellow_mtc", "ecoes_llfc", "chellow_llfc", "ecoes_ssc", "chellow_ssc", "ecoes_es", "chellow_es", "ecoes_supplier", "chellow_supplier", "chellow_supplier_contract_name", "ecoes_dc", "chellow_dc", "ecoes_mop", "chellow_mop", "ecoes_gsp_group", "chellow_gsp_group", "ecoes_msn", "chellow_msn", "ecoes_msn_install_date", "ecoes_meter_type", "chellow_meter_type", "ignored", "problem", ) writer.writerow(titles) for mpan_spaces, ecoes in sorted(ecoes_mpans.items()): problem = "" ignore = True diffs = [] try: ecoes_es = ecoes["energisation-status"] except KeyError as e: raise e ecoes_disconnected = ecoes_es == "" current_chell = mpan_spaces in mpans if ecoes["meter_count"] > 1: problem += ( f"There are {ecoes['meter_count']} meters associated with this MPAN " f"core in ECOES, but Chellow only supports one meter per supply at the " f"moment. If there really should be multiple meters for this supply, " f"let me know and I'll add support for it in Chellow." ) ignore = False if ecoes_disconnected and current_chell: problem += "Disconnected in ECOES, but current in Chellow. " ignore = False elif not ecoes_disconnected and not current_chell: problem += f"In ECOES (as {ecoes_es}) but disconnected in Chellow. " ignore = False if current_chell: mpans.remove(mpan_spaces) era = sess.execute( select(Era) .filter( Era.finish_date == null(), or_( Era.imp_mpan_core == mpan_spaces, Era.exp_mpan_core == mpan_spaces, ), ) .options( joinedload(Era.supply).joinedload(Supply.gsp_group), joinedload(Era.mop_contract) .joinedload(Contract.party) .joinedload(Party.participant), joinedload(Era.dc_contract) .joinedload(Contract.party) .joinedload(Party.participant), joinedload(Era.imp_supplier_contract) .joinedload(Contract.party) .joinedload(Party.participant), joinedload(Era.exp_supplier_contract) .joinedload(Contract.party) .joinedload(Party.participant), joinedload(Era.pc), joinedload(Era.imp_llfc), joinedload(Era.exp_llfc), joinedload(Era.mtc).joinedload(Mtc.meter_type), joinedload(Era.ssc), joinedload(Era.energisation_status), joinedload(Era.channels), ) ).scalar() chellow_supply_id = era.supply.id chellow_era_id = era.id chellow_es = era.energisation_status.code if ecoes_es != chellow_es: problem += "The energisation statuses don't match. " ignore = False diffs.append("es") if not (ecoes_es == "D" and chellow_es == "D"): if era.imp_mpan_core == mpan_spaces: supplier_contract = era.imp_supplier_contract llfc = era.imp_llfc else: supplier_contract = era.exp_supplier_contract llfc = era.exp_llfc chellow_pc = era.pc.code try: if int(ecoes["pc"]) != int(chellow_pc): problem += "The PCs don't match. " ignore = False diffs.append("pc") except ValueError: problem += "Can't parse the PC. " ignore = False chellow_mtc = era.mtc.code try: if int(ecoes["mtc"]) != int(chellow_mtc): problem += "The MTCs don't match. " ignore = False diffs.append("mtc") except ValueError: problem += "Can't parse the MTC. " ignore = False chellow_llfc = llfc.code if ecoes["llfc"].zfill(3) != chellow_llfc: problem += "The LLFCs don't match. " ignore = False diffs.append("llfc") chellow_ssc = era.ssc if chellow_ssc is None: chellow_ssc = "" chellow_ssc_int = None else: chellow_ssc = chellow_ssc.code chellow_ssc_int = int(chellow_ssc) if len(ecoes["ssc"]) > 0: ecoes_ssc_int = int(ecoes["ssc"]) else: ecoes_ssc_int = None if ecoes_ssc_int != chellow_ssc_int and not ( ecoes_ssc_int is None and chellow_ssc_int is None ): problem += "The SSCs don't match. " ignore = False diffs.append("ssc") chellow_supplier = supplier_contract.party.participant.code chellow_supplier_contract_name = supplier_contract.name chellow_supplier_contract_id = supplier_contract.id if chellow_supplier != ecoes["supplier"]: problem += "The supplier codes don't match. " ignore = False diffs.append("supplier") dc_contract = era.dc_contract if dc_contract is None: chellow_dc = "" else: chellow_dc = dc_contract.party.participant.code if chellow_dc != ecoes["dc"]: problem += "The DC codes don't match. " ignore = False diffs.append("dc") mop_contract = era.mop_contract if mop_contract is None: chellow_mop = "" else: chellow_mop = mop_contract.party.participant.code if chellow_mop != ecoes["mop"]: problem += "The MOP codes don't match. " ignore = False diffs.append("mop") chellow_gsp_group = era.supply.gsp_group.code if chellow_gsp_group != ecoes["gsp-group"]: problem += "The GSP group codes don't match. " ignore = False diffs.append("gsp_group") chellow_msn = era.msn if chellow_msn is None: chellow_msn = "" if chellow_msn != ecoes["msn"]: problem += "The meter serial numbers don't match. " diffs.append("msn") if mpan_spaces not in ignore_mpan_cores_msn: ignore = False elif mpan_spaces in ignore_mpan_cores_msn: problem += ( "This MPAN core is in mpan_cores_ignore and yet the meter " "serial numbers do match. " ) chellow_meter_type = _meter_type(era) if chellow_meter_type != ecoes["meter-type"]: problem += ( "The meter types don't match. See " "https://dtc.mrasco.com/DataItem.aspx?ItemCounter=0483 " ) ignore = False diffs.append("meter_type") else: chellow_pc = "" chellow_mtc = "" chellow_llfc = "" chellow_ssc = "" chellow_es = "" chellow_supplier = "" chellow_supplier_contract_name = "" chellow_supplier_contract_id = None chellow_dc = "" chellow_mop = "" chellow_gsp_group = "" chellow_msn = "" chellow_meter_type = "" chellow_supply_id = None chellow_era_id = None if len(problem) > 0 and not (not show_ignored and ignore): values = { "mpan_core": mpan_spaces, "mpan_core_no_spaces": ecoes["mpan-core"], "ecoes_pc": ecoes["pc"], "chellow_pc": chellow_pc, "ecoes_mtc": ecoes["mtc"], "chellow_mtc": chellow_mtc, "chellow_mtc_date": ecoes["mtc-date"], "ecoes_llfc": ecoes["llfc"], "ecoes_llfc_from": ecoes["llfc-from"], "chellow_llfc": chellow_llfc, "ecoes_ssc": ecoes["ssc"], "chellow_ssc": chellow_ssc, "ecoes_es": ecoes["energisation-status"], "chellow_es": chellow_es, "ecoes_supplier": ecoes["supplier"], "ecoes_supplier_registration_from": ecoes["registration-from"], "chellow_supplier": chellow_supplier, "chellow_supplier_contract_name": chellow_supplier_contract_name, "ecoes_dc": ecoes["dc"], "chellow_dc": chellow_dc, "ecoes_mop": ecoes["mop"], "ecoes_mop_appoint_date": ecoes["mop-appoint-date"], "chellow_mop": chellow_mop, "ecoes_gsp_group": ecoes["gsp-group"], "ecoes_gsp_effective_from": ecoes["gsp-effective-from"], "chellow_gsp_group": chellow_gsp_group, "ecoes_msn": ecoes["msn"], "chellow_msn": chellow_msn, "ecoes_msn_install_date": ecoes["meter-install-date"], "ecoes_meter_type": ecoes["meter-type"], "chellow_meter_type": chellow_meter_type, "ignored": ignore, "problem": problem, } writer.writerow(values[t] for t in titles) values["chellow_supplier_contract_id"] = chellow_supplier_contract_id values["chellow_supply_id"] = chellow_supply_id values["diffs"] = diffs values["chellow_era_id"] = chellow_era_id report_run.insert_row(sess, "", titles, values, {}) sess.commit() sess.expunge_all() for mpan_core in mpans: supply = Supply.get_by_mpan_core(sess, mpan_core) era = supply.find_era_at(sess, None) if era.imp_mpan_core == mpan_core: supplier_contract = era.imp_supplier_contract llfc = era.imp_llfc else: supplier_contract = era.exp_supplier_contract llfc = era.exp_llfc ssc = "" if era.ssc is None else era.ssc.code es = era.energisation_status.code dc_contract = era.dc_contract dc = "" if dc_contract is None else dc_contract.party.participant.code mop_contract = era.mop_contract mop = "" if mop_contract is None else mop_contract.party.participant.code msn = "" if era.msn is None else era.msn meter_type = _meter_type(era) values = { "mpan_core": mpan_core, "mpan_core_no_spaces": mpan_core.replace(" ", ""), "ecoes_pc": "", "chellow_pc": era.pc.code, "ecoes_mtc": "", "chellow_mtc": era.mtc.code, "ecoes_llfc": "", "chellow_llfc": llfc.code, "ecoes_ssc": "", "chellow_ssc": ssc, "ecoes_es": "", "chellow_es": es, "ecoes_supplier": "", "chellow_supplier": supplier_contract.party.participant.code, "chellow_supplier_contract_name": supplier_contract.name, "ecoes_dc": "", "chellow_dc": dc, "ecoes_mop": "", "chellow_mop": mop, "ecoes_gsp_group": "", "chellow_gsp_group": supply.gsp_group.code, "ecoes_msn": "", "chellow_msn": msn, "ecoes_msn_install_date": "", "ecoes_meter_type": "", "chellow_meter_type": meter_type, "ignored": False, "problem": "In Chellow, but not in ECOES.", } writer.writerow(values[t] for t in titles) values["chellow_supplier_contract_id"] = supplier_contract.id values["chellow_supply_id"] = era.supply.id values["diffs"] = [] values["chellow_era_id"] = era.id report_run.insert_row(sess, "", titles, values, {})
def content(user): sess = None try: sess = Session() running_name, finished_name = chellow.dloads.make_names( "ecoes_comparison.csv", user) f = open(running_name, mode="w", newline="") writer = csv.writer(f, lineterminator="\n") props = Contract.get_non_core_by_name( sess, "configuration").make_properties() ECOES_KEY = "ecoes" try: ecoes_props = props[ECOES_KEY] except KeyError: raise BadRequest( f"The property {ECOES_KEY} cannot be found in the configuration " f"properties.") for key in ("user_name", "password", "prefix", "ignore_mpan_cores"): try: ecoes_props[key] except KeyError: raise BadRequest( f"The property {key} cannot be found in the 'ecoes' section of " f"the configuration properties.") ignore_mpan_cores = ecoes_props["ignore_mpan_cores"] proxies = props.get("proxies", {}) s = requests.Session() s.verify = False r = s.get(ecoes_props["prefix"], proxies=proxies) r = s.post( ecoes_props["prefix"], data={ "Username": ecoes_props["user_name"], "Password": ecoes_props["password"], }, allow_redirects=False, ) imp_mpans = [ v.imp_mpan_core for (v, ) in sess.execute( select(Era).join(Supply).join(Source).join(Supply.dno).filter( Party.dno_code.notin_(("88", "99")), Era.finish_date == null(), Source.code != "3rd-party", Era.imp_mpan_core.notin_(ignore_mpan_cores), Era.imp_mpan_core != null(), ).distinct().order_by(Era.imp_mpan_core)) ] exp_mpans = [ v.exp_mpan_core for (v, ) in sess.execute( select(Era).join(Supply).join(Source).join(Supply.dno).filter( Party.dno_code.notin_(("88", "99")), Era.finish_date == null(), Source.code != "3rd-party", Era.exp_mpan_core != null(), Era.exp_mpan_core.notin_(ignore_mpan_cores), ).distinct().order_by(Era.exp_mpan_core)) ] mpans = imp_mpans + exp_mpans r = s.get( ecoes_props["prefix"] + "NonDomesticCustomer/ExportPortfolioMPANs?fileType=csv", proxies=proxies, ) titles = ( "MPAN Core", "MPAN Core No Spaces", "ECOES PC", "Chellow PC", "ECOES MTC", "Chellow MTC", "ECOES LLFC", "Chellow LLFC", "ECOES SSC", "Chellow SSC", "ECOES Energisation Status", "Chellow Energisation Status", "ECOES Supplier", "Chellow Supplier", "ECOES DC", "Chellow DC", "ECOES MOP", "Chellow MOP", "ECOES GSP Group", "Chellow GSP Group", "ECOES MSN", "Chellow MSN", "ECOES Meter Type", "Chellow Meter Type", "Problem", ) writer.writerow(titles) parser = iter(csv.reader(r.text.splitlines(True))) next(parser) # Skip titles for values in parser: problem = "" ecoes_titles = [ "mpan-core", "address-line-1", "address-line-2", "address-line-3", "address-line-4", "address-line-5", "address-line-6", "address-line-7", "address-line-8", "address-line-9", "post-code", "supplier", "registration-from", "mtc", "mtc-date", "llfc", "llfc-from", "pc", "ssc", "measurement-class", "energisation-status", "da", "dc", "mop", "mop-appoint-date", "gsp-group", "gsp-effective-from", "dno", "msn", "meter-install-date", "meter-type", "map-id", ] ecoes = dict(zip(ecoes_titles, map(str.strip, values))) mpan_spaces = " ".join(( ecoes["mpan-core"][:2], ecoes["mpan-core"][2:6], ecoes["mpan-core"][6:10], ecoes["mpan-core"][-3:], )) if mpan_spaces in ignore_mpan_cores: continue try: ecoes_es = ecoes["energisation-status"] except KeyError as e: print(r.text) raise e ecoes_disconnected = ecoes_es == "" current_chell = mpan_spaces in mpans if ecoes_disconnected and current_chell: problem += "Disconnected in ECOES, but current in Chellow. " elif not ecoes_disconnected and not current_chell: problem += f"In ECOES (as {ecoes_es}) but disconnected in Chellow. " if current_chell: mpans.remove(mpan_spaces) era = sess.execute( select(Era).filter( Era.finish_date == null(), or_( Era.imp_mpan_core == mpan_spaces, Era.exp_mpan_core == mpan_spaces, ), ).options( joinedload(Era.supply).joinedload(Supply.gsp_group), joinedload(Era.mop_contract).joinedload( Contract.party).joinedload(Party.participant), joinedload(Era.dc_contract).joinedload( Contract.party).joinedload(Party.participant), joinedload(Era.imp_supplier_contract).joinedload( Contract.party).joinedload(Party.participant), joinedload(Era.exp_supplier_contract).joinedload( Contract.party).joinedload(Party.participant), joinedload(Era.pc), joinedload(Era.imp_llfc), joinedload(Era.exp_llfc), joinedload(Era.mtc).joinedload(Mtc.meter_type), joinedload(Era.ssc), joinedload(Era.energisation_status), joinedload(Era.channels), )).scalar() if era.imp_mpan_core == mpan_spaces: supplier_contract = era.imp_supplier_contract llfc = era.imp_llfc else: supplier_contract = era.exp_supplier_contract llfc = era.exp_llfc chellow_pc = era.pc.code try: if int(ecoes["pc"]) != int(chellow_pc): problem += "The PCs don't match. " except ValueError: problem += "Can't parse the PC. " chellow_mtc = era.mtc.code try: if int(ecoes["mtc"]) != int(chellow_mtc): problem += "The MTCs don't match. " except ValueError: problem += "Can't parse the MTC. " chellow_llfc = llfc.code if ecoes["llfc"].zfill(3) != chellow_llfc: problem += "The LLFCs don't match. " chellow_ssc = era.ssc if chellow_ssc is None: chellow_ssc = "" chellow_ssc_int = None else: chellow_ssc = chellow_ssc.code chellow_ssc_int = int(chellow_ssc) if len(ecoes["ssc"]) > 0: ecoes_ssc_int = int(ecoes["ssc"]) else: ecoes_ssc_int = None if ecoes_ssc_int != chellow_ssc_int and not ( ecoes_ssc_int is None and chellow_ssc_int is None): problem += "The SSCs don't match. " chellow_es = era.energisation_status.code if ecoes_es != chellow_es: problem += "The energisation statuses don't match. " chellow_supplier = supplier_contract.party.participant.code if chellow_supplier != ecoes["supplier"]: problem += "The supplier codes don't match. " dc_contract = era.dc_contract if dc_contract is None: chellow_dc = "" else: chellow_dc = dc_contract.party.participant.code if chellow_dc != ecoes["dc"]: problem += "The DC codes don't match. " mop_contract = era.mop_contract if mop_contract is None: chellow_mop = "" else: chellow_mop = mop_contract.party.participant.code if chellow_mop != ecoes["mop"]: problem += "The MOP codes don't match. " chellow_gsp_group = era.supply.gsp_group.code if chellow_gsp_group != ecoes["gsp-group"]: problem += "The GSP group codes don't match. " chellow_msn = era.msn if chellow_msn is None: chellow_msn = "" if chellow_msn != ecoes["msn"]: problem += "The meter serial numbers don't match. " chellow_meter_type = _meter_type(era) if chellow_meter_type != ecoes["meter-type"]: problem += ( "The meter types don't match. See " "https://dtc.mrasco.com/DataItem.aspx?ItemCounter=0483 " ) else: chellow_pc = "" chellow_mtc = "" chellow_llfc = "" chellow_ssc = "" chellow_es = "" chellow_supplier = "" chellow_dc = "" chellow_mop = "" chellow_gsp_group = "" chellow_msn = "" chellow_meter_type = "" if len(problem) > 0: writer.writerow([ mpan_spaces, ecoes["mpan-core"], ecoes["pc"], chellow_pc, ecoes["mtc"], chellow_mtc, ecoes["llfc"], chellow_llfc, ecoes["ssc"], chellow_ssc, ecoes["energisation-status"], chellow_es, ecoes["supplier"], chellow_supplier, ecoes["dc"], chellow_dc, ecoes["mop"], chellow_mop, ecoes["gsp-group"], chellow_gsp_group, ecoes["msn"], chellow_msn, ecoes["meter-type"], chellow_meter_type, problem, ]) sess.expunge_all() for mpan_core in mpans: supply = Supply.get_by_mpan_core(sess, mpan_core) era = supply.find_era_at(sess, None) if era.imp_mpan_core == mpan_core: supplier_contract = era.imp_supplier_contract llfc = era.imp_llfc else: supplier_contract = era.exp_supplier_contract llfc = era.exp_llfc ssc = "" if era.ssc is None else era.ssc.code es = era.energisation_status.code dc_contract = era.dc_contract if dc_contract is None: dc = "" else: dc = dc_contract.party.participant.code mop_contract = era.mop_contract if mop_contract is None: mop = "" else: mop = mop_contract.party.participant.code msn = "" if era.msn is None else era.msn meter_type = _meter_type(era) writer.writerow([ mpan_core, mpan_core.replace(" ", ""), "", era.pc.code, "", era.mtc.code, "", llfc.code, "", ssc, "", es, "", supplier_contract.party.participant.code, "", dc, "", mop, "", supply.gsp_group.code, "", msn, "", meter_type, "In Chellow, but not in ECOES.", ]) 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_VAT(rows, headers): sess = headers["sess"] mpan_core = headers["mpan_core"] start_date = headers["start_date"] reads = headers["reads"] supply = Supply.get_by_mpan_core(sess, mpan_core) era = supply.find_era_at(sess, start_date) bill_elements = [] if era is None: era = supply.find_last_era(sess) if era is not None and era.ssc is not None: try: ssc_lookup = era.imp_mpan_core tpr_map = SSC_MAP[ssc_lookup] except KeyError: ssc_lookup = era.ssc.code try: tpr_map = SSC_MAP[ssc_lookup] except KeyError: raise BadRequest("The SSC " + ssc_lookup + " isn't in the SSC_MAP.") for read in reads: desc = read["tpr_code"] try: read["tpr_code"] = tpr_map[desc] except KeyError: raise BadRequest("The description " + desc + " isn't in the SSC_MAP " "for the SSC " + ssc_lookup + ".") for el in headers["bill_elements"]: if el.titles is None: try: tpr = tpr_map[el.desc] except KeyError: raise BadRequest( f"The billing element description {el.desc} isn't in " f"the SSC_MAP for the SSC {ssc_lookup}.") titles = (tpr + "-gbp", tpr + "-rate", tpr + "-kwh") else: titles = el.titles bill_elements.append( BillElement(gbp=el.gbp, titles=titles, rate=el.rate, cons=el.cons, desc=None)) else: for read in reads: read["tpr_code"] = "00001" for el in headers["bill_elements"]: if el.titles is None: des = el.desc titles = (des + "-kwh", des + "-rate", des + "-gbp") else: titles = el.titles bill_elements.append( BillElement(gbp=el.gbp, titles=titles, rate=el.rate, cons=el.cons, desc=None)) breakdown = headers["breakdown"] for bill_el in bill_elements: eln_gbp, eln_rate, eln_cons = bill_el.titles breakdown[eln_gbp] = bill_el.gbp rate = bill_el.rate if eln_rate is not None and rate is not None: try: rates = breakdown[eln_rate] except KeyError: rates = breakdown[eln_rate] = set() rates.add(rate) cons = bill_el.cons if eln_cons is not None and cons is not None: breakdown[eln_cons] = cons return { "kwh": headers["kwh"], "reference": headers["reference"], "mpan_core": mpan_core, "issue_date": headers["issue_date"], "account": headers["account"], "start_date": start_date, "finish_date": headers["finish_date"], "net": headers["net"], "vat": headers["vat"], "gross": headers["gross"], "breakdown": breakdown, "reads": reads, "bill_type_code": headers["bill_type_code"], }