From fc288e9565a62ec425ffdf25f5edd4e387ab1820 Mon Sep 17 00:00:00 2001 From: Tony Locke Date: Wed, 30 Aug 2023 15:59:42 +0100 Subject: [PATCH] Make adding an electriciy supply responsive --- chellow/e/views.py | 485 +++++++++++++++- chellow/templates/base.html | 519 ++++++------------ chellow/templates/e/site_add_e_supply.html | 52 ++ .../templates/e/site_add_e_supply_form.html | 174 ++++++ chellow/templates/macros.html | 179 ++++++ chellow/templates/site.html | 5 +- chellow/templates/site_edit.html | 159 ------ chellow/utils.py | 14 + chellow/views.py | 175 ------ test/e/test_e_views.py | 353 ++++++++++++ test/test_views.py | 425 +------------- 11 files changed, 1440 insertions(+), 1100 deletions(-) create mode 100644 chellow/templates/e/site_add_e_supply.html create mode 100644 chellow/templates/e/site_add_e_supply_form.html create mode 100644 chellow/templates/macros.html diff --git a/chellow/e/views.py b/chellow/e/views.py index 609b0b33b..17a9f9ed8 100644 --- a/chellow/e/views.py +++ b/chellow/e/views.py @@ -21,7 +21,7 @@ ) from sqlalchemy import Float, case, cast, false, func, null, or_, select, text, true -from sqlalchemy.orm import joinedload +from sqlalchemy.orm import aliased, joinedload from werkzeug.exceptions import BadRequest, NotFound @@ -95,6 +95,7 @@ req_file, req_hh_date, req_int, + req_int_none, req_str, req_zish, to_ct, @@ -3782,6 +3783,488 @@ def em_totals(site_id): ) +@e.route("/sites//add_e_supply") +def site_add_e_supply_get(site_id): + try: + site = Site.get_by_id(g.sess, site_id) + return render_template("site_add_e_supply.html", site=site) + except BadRequest as e: + g.sess.rollback() + flash(e.description) + return render_template("site_add_e_supply.html", site=site) + + +@e.route("/sites//add_e_supply/form") +def site_add_e_supply_form_get(site_id): + try: + ct_now = ct_datetime_now() + cops = g.sess.query(Cop).order_by(Cop.code) + comms = g.sess.execute(select(Comm).order_by(Comm.code)).scalars() + energisation_statuses = g.sess.query(EnergisationStatus).order_by( + EnergisationStatus.code + ) + default_energisation_status = EnergisationStatus.get_by_code(g.sess, "E") + + if "start_year" in request.values: + start_date = req_date("start") + else: + start_date = to_utc(ct_datetime(ct_now.year, ct_now.month, ct_now.day)) + + site = Site.get_by_id(g.sess, site_id) + sources = g.sess.scalars(select(Source).order_by(Source.code)) + source_id = req_int_none("source_id") + if source_id is None: + source = Source.get_by_code(g.sess, "net") + else: + source = Source.get_by_id(g.sess, source_id) + generator_types = g.sess.query(GeneratorType).order_by(GeneratorType.code) + gsp_groups = g.sess.query(GspGroup).order_by(GspGroup.code) + eras = ( + g.sess.query(Era) + .join(SiteEra) + .filter(SiteEra.site == site) + .order_by(Era.start_date.desc()) + ) + RateScriptAliasStart = aliased(RateScript) + RateScriptAliasFinish = aliased(RateScript) + mop_contracts = g.sess.scalars( + select(Contract) + .join(MarketRole) + .join( + RateScriptAliasStart, + Contract.start_rate_script_id == RateScriptAliasStart.id, + ) + .join( + RateScriptAliasFinish, + Contract.finish_rate_script_id == RateScriptAliasFinish.id, + ) + .where( + MarketRole.code == "M", + start_date >= RateScriptAliasStart.start_date, + RateScriptAliasFinish.finish_date == null(), + ) + .order_by(Contract.name) + ) + dc_contracts = g.sess.scalars( + select(Contract) + .join(MarketRole) + .join( + RateScriptAliasStart, + Contract.start_rate_script_id == RateScriptAliasStart.id, + ) + .join( + RateScriptAliasFinish, + Contract.finish_rate_script_id == RateScriptAliasFinish.id, + ) + .where( + MarketRole.code.in_(("C", "D")), + start_date >= RateScriptAliasStart.start_date, + RateScriptAliasFinish.finish_date == null(), + ) + .order_by(Contract.name) + ) + supplier_contracts = g.sess.scalars( + select(Contract) + .join(MarketRole) + .join( + RateScriptAliasStart, + Contract.start_rate_script_id == RateScriptAliasStart.id, + ) + .join( + RateScriptAliasFinish, + Contract.finish_rate_script_id == RateScriptAliasFinish.id, + ) + .where( + MarketRole.code == "X", + start_date >= RateScriptAliasStart.start_date, + RateScriptAliasFinish.finish_date == null(), + ) + .order_by(Contract.name) + ) + pcs = g.sess.query(Pc).order_by(Pc.code) + pc_id = req_int_none("pc_id") + if pc_id is None: + pc = Pc.get_by_code(g.sess, "00") + else: + pc = Pc.get_by_id(g.sess, pc_id) + + dnos = g.sess.scalars( + select(Party) + .join(MarketRole) + .where(MarketRole.code == "R") + .order_by(Party.dno_code) + ).all() + dno_id = req_int_none("dno_id") + if dno_id is None: + dno = dnos[0] + else: + dno = Party.get_by_id(g.sess, dno_id) + + participant = dno.participant + + if pc.code == "00": + sscs = [{"id": "", "code": "None", "description": ""}] + ssc = None + else: + sscs = g.sess.scalars( + select(Ssc) + .select_from(MtcSsc) + .join(Ssc, MtcSsc.ssc_id == Ssc.id) + .join(MtcLlfcSsc, MtcLlfcSsc.mtc_ssc_id == MtcSsc.id) + .join(MtcLlfcSscPc) + .join(MtcParticipant) + .where( + MtcParticipant.participant == participant, + MtcLlfcSscPc.pc == pc, + start_date >= MtcLlfcSscPc.valid_from, + MtcLlfcSscPc.valid_to == null(), + ) + .distinct() + .order_by(Ssc.code, Ssc.valid_from.desc()) + ).all() + ssc_id = req_int_none("ssc_id") + if ssc_id in {s.id for s in sscs}: + ssc = Ssc.get_by_id(g.sess, ssc_id) + else: + ssc = sscs[0] + + if pc.code == "00": + mtc_participants = [ + mtc_participant + for mtc_participant, mtc in g.sess.execute( + select(MtcParticipant, Mtc) + .join(Mtc) + .join(MtcLlfc) + .where(MtcParticipant.participant == participant) + .order_by(Mtc.code, MtcParticipant.valid_from.desc()) + .distinct() + ) + ] + else: + mtc_participants = [ + mtc_participant + for mtc_participant, mtc in g.sess.execute( + select(MtcParticipant, Mtc) + .select_from(MtcLlfcSscPc) + .join(MtcLlfcSsc) + .join(MtcSsc) + .join(MtcParticipant) + .join(Mtc) + .where( + MtcParticipant.participant == participant, + MtcLlfcSscPc.pc == pc, + MtcSsc.ssc == ssc, + start_date >= MtcLlfcSscPc.valid_from, + MtcLlfcSscPc.valid_to == null(), + ) + .distinct() + .order_by(Mtc.code, MtcParticipant.valid_from.desc()) + ) + ] + + mtc_participant_id = req_int_none("mtc_participant_id") + if mtc_participant_id is None: + if len(mtc_participants) > 0: + mtc_participant = mtc_participants[0] + else: + mtc_participant = None + else: + mtc_participant = MtcParticipant.get_by_id(g.sess, mtc_participant_id) + + if pc.code == "00": + imp_llfcs = g.sess.scalars( + select(Llfc) + .join(MtcLlfc) + .where( + MtcLlfc.mtc_participant == mtc_participant, + start_date >= Llfc.valid_from, + Llfc.valid_to == null(), + Llfc.is_import == true(), + ) + .order_by(Llfc.code, Llfc.valid_from.desc()) + .distinct() + ) + else: + imp_llfcs = g.sess.scalars( + select(Llfc) + .select_from(MtcLlfcSsc) + .join(Llfc, Llfc.id == MtcLlfcSsc.llfc_id) + .join(MtcLlfcSscPc) + .join(MtcSsc, MtcSsc.id == MtcLlfcSsc.mtc_ssc_id) + .where( + MtcSsc.mtc_participant == mtc_participant, + MtcLlfcSscPc.pc == pc, + MtcSsc.ssc == ssc, + start_date >= MtcLlfcSscPc.valid_from, + MtcLlfcSscPc.valid_to == null(), + Llfc.is_import == true(), + ) + .distinct() + .order_by(Llfc.code, Llfc.valid_from.desc()) + ) + + if pc.code == "00": + exp_llfcs = g.sess.scalars( + select(Llfc) + .join(MtcLlfc) + .where( + MtcLlfc.mtc_participant == mtc_participant, + start_date >= Llfc.valid_from, + Llfc.valid_to == null(), + Llfc.is_import == false(), + ) + .order_by(Llfc.code, Llfc.valid_from.desc()) + .distinct() + ) + else: + exp_llfcs = g.sess.scalars( + select(Llfc) + .select_from(MtcLlfcSsc) + .join(Llfc, Llfc.id == MtcLlfcSsc.llfc_id) + .join(MtcLlfcSscPc) + .join(MtcSsc, MtcSsc.id == MtcLlfcSsc.mtc_ssc_id) + .where( + MtcSsc.mtc_participant == mtc_participant, + MtcLlfcSscPc.pc == pc, + MtcSsc.ssc == ssc, + start_date >= MtcLlfcSscPc.valid_from, + MtcLlfcSscPc.valid_to == null(), + Llfc.is_import == false(), + ) + .distinct() + .order_by(Llfc.code, Llfc.valid_from.desc()) + ) + + return render_template( + "site_add_e_supply_form.html", + site=site, + dnos=dnos, + dno=dno, + sources=sources, + source=source, + generator_types=generator_types, + gsp_groups=gsp_groups, + eras=eras, + energisation_statuses=energisation_statuses, + default_energisation_status=default_energisation_status, + mop_contracts=mop_contracts, + dc_contracts=dc_contracts, + supplier_contracts=supplier_contracts, + pcs=pcs, + pc=pc, + cops=cops, + comms=comms, + sscs=sscs, + mtc_participants=mtc_participants, + mtc_participant=mtc_participant, + start_date=start_date, + imp_llfcs=imp_llfcs, + exp_llfcs=exp_llfcs, + ) + except BadRequest as e: + g.sess.rollback() + flash(e.description) + return render_template( + "site_add_e_supply_form.html", + site=site, + dnos=dnos, + sources=sources, + source=source, + generator_types=generator_types, + gsp_groups=gsp_groups, + eras=eras, + mop_contracts=mop_contracts, + dc_contracts=dc_contracts, + supplier_contracts=supplier_contracts, + pcs=pcs, + pc=pc, + cops=cops, + comms=comms, + sscs=sscs, + mtc_participants=mtc_participants, + mtc_participant=mtc_participant, + ) + + +@e.route("/sites//add_e_supply", methods=["POST"]) +def site_add_e_supply_form_post(site_id): + try: + site = Site.get_by_id(g.sess, site_id) + start_date = req_date("start") + name = req_str("name") + source_id = req_int("source_id") + source = Source.get_by_id(g.sess, source_id) + gsp_group_id = req_int("gsp_group_id") + gsp_group = GspGroup.get_by_id(g.sess, gsp_group_id) + mop_contract_id = req_int("mop_contract_id") + mop_contract = Contract.get_mop_by_id(g.sess, mop_contract_id) + mop_account = req_str("mop_account") + dc_contract_id = req_int("dc_contract_id") + dc_contract = Contract.get_dc_by_id(g.sess, dc_contract_id) + dc_account = req_str("dc_account") + msn = req_str("msn") + pc_id = req_int("pc_id") + pc = Pc.get_by_id(g.sess, pc_id) + mtc_participant_id = req_int("mtc_participant_id") + mtc_participant = MtcParticipant.get_by_id(g.sess, mtc_participant_id) + cop_id = req_int("cop_id") + cop = Cop.get_by_id(g.sess, cop_id) + comm_id = req_int("comm_id") + comm = Comm.get_by_id(g.sess, comm_id) + ssc_id = req_int_none("ssc_id") + ssc = None if ssc_id is None else Ssc.get_by_id(g.sess, ssc_id) + energisation_status_id = req_int("energisation_status_id") + energisation_status = EnergisationStatus.get_by_id( + g.sess, energisation_status_id + ) + properties = req_zish("properties") + if "generator_type_id" in request.form: + generator_type_id = req_int("generator_type_id") + generator_type = GeneratorType.get_by_id(g.sess, generator_type_id) + else: + generator_type = None + + if "imp_mpan_core" in request.form: + imp_mpan_core_raw = req_str("imp_mpan_core") + if len(imp_mpan_core_raw) == 0: + imp_mpan_core = None + else: + imp_mpan_core = parse_mpan_core(imp_mpan_core_raw) + else: + imp_mpan_core = None + + if imp_mpan_core is None: + imp_supplier_contract = None + imp_supplier_account = None + imp_sc = None + imp_llfc_code = None + else: + imp_supplier_contract_id = req_int("imp_supplier_contract_id") + imp_supplier_contract = Contract.get_supplier_by_id( + g.sess, imp_supplier_contract_id + ) + imp_supplier_account = req_str("imp_supplier_account") + imp_sc = req_int("imp_sc") + imp_llfc_id = req_int("imp_llfc_id") + imp_llfc = Llfc.get_by_id(g.sess, imp_llfc_id) + imp_llfc_code = imp_llfc.code + + if "exp_mpan_core" in request.form: + exp_mpan_core_raw = req_str("exp_mpan_core") + if len(exp_mpan_core_raw) == 0: + exp_mpan_core = None + else: + exp_mpan_core = parse_mpan_core(exp_mpan_core_raw) + else: + exp_mpan_core = None + + if exp_mpan_core is None: + exp_supplier_contract = None + exp_supplier_account = None + exp_sc = None + exp_llfc_code = None + else: + exp_supplier_contract_id = req_int("exp_supplier_contract_id") + exp_supplier_contract = Contract.get_supplier_by_id( + g.sess, exp_supplier_contract_id + ) + exp_supplier_account = req_str("exp_supplier_account") + exp_sc = req_int("exp_sc") + exp_llfc_id = req_int("exp_llfc_id") + exp_llfc = Llfc.get_by_id(g.sess, exp_llfc_id) + exp_llfc_code = exp_llfc.code + + supply = site.insert_e_supply( + g.sess, + source, + generator_type, + name, + start_date, + None, + gsp_group, + mop_contract, + mop_account, + dc_contract, + dc_account, + msn, + pc, + mtc_participant.mtc.code, + cop, + comm, + ssc, + energisation_status, + properties, + imp_mpan_core, + imp_llfc_code, + imp_supplier_contract, + imp_supplier_account, + imp_sc, + exp_mpan_core, + exp_llfc_code, + exp_supplier_contract, + exp_supplier_account, + exp_sc, + ) + g.sess.commit() + return chellow_redirect(f"/supplies/{supply.id}", 303) + except BadRequest as e: + g.sess.rollback() + flash(e.description) + sources = g.sess.query(Source).order_by(Source.code) + generator_types = g.sess.query(GeneratorType).order_by(GeneratorType.code) + gsp_groups = g.sess.query(GspGroup).order_by(GspGroup.code) + energisation_statuses = g.sess.query(EnergisationStatus).order_by( + EnergisationStatus.code + ) + default_energisation_status = EnergisationStatus.get_by_code(g.sess, "E") + eras = ( + g.sess.query(Era) + .join(SiteEra) + .filter(SiteEra.site == site) + .order_by(Era.start_date.desc()) + ) + mop_contracts = ( + g.sess.query(Contract) + .join(MarketRole) + .filter(MarketRole.code == "M") + .order_by(Contract.name) + ) + dc_contracts = ( + g.sess.query(Contract) + .join(MarketRole) + .filter(MarketRole.code.in_(("C", "D"))) + .order_by(Contract.name) + ) + supplier_contracts = ( + g.sess.query(Contract) + .join(MarketRole) + .filter(MarketRole.code == "X") + .order_by(Contract.name) + ) + pcs = g.sess.query(Pc).order_by(Pc.code) + cops = g.sess.query(Cop).order_by(Cop.code) + comms = g.sess.execute(select(Comm).order_by(Comm.code)).scalars() + return make_response( + render_template( + "site_add_e_supply.html", + site=site, + sources=sources, + generator_types=generator_types, + gsp_groups=gsp_groups, + energisation_statuses=energisation_statuses, + default_energisation_status=default_energisation_status, + eras=eras, + mop_contracts=mop_contracts, + dc_contracts=dc_contracts, + supplier_contracts=supplier_contracts, + pcs=pcs, + cops=cops, + comms=comms, + ), + 400, + ) + + @e.route("/sources") def sources_get(): sources = g.sess.query(Source).order_by(Source.code) diff --git a/chellow/templates/base.html b/chellow/templates/base.html index 98696c128..ac79a5a0d 100644 --- a/chellow/templates/base.html +++ b/chellow/templates/base.html @@ -1,351 +1,190 @@ -{%- macro input_date(prefix, initial=None, resolution='minute') -%} - {% if prefix != None %} - {% set year_field = prefix + '_year' %} - {% set month_field = prefix + '_month' %} - {% set day_field = prefix + '_day' %} - {% set hour_field = prefix + '_hour' %} - {% set minute_field = prefix + '_minute' %} - {% else %} - {% set year_field = 'year' %} - {% set month_field = 'month' %} - {% set day_field = 'day' %} - {% set hour_field = 'hour' %} - {% set minute_field = 'minute' %} - {% endif %} - - {% set initial = initial|now_if_none|to_ct %} -
- - - {%- if resolution in ['month', 'day', 'hour', 'minute'] -%} - - - {%- endif -%} - - {% if resolution in ['day', 'hour', 'minute'] -%} - - - {%- endif -%} - - {% if resolution in ['hour', 'minute'] %} - - {%- endif -%} - - {% if resolution == 'minute' -%} - : - {%- endif %} -
-{%- endmacro -%} - -{%- macro input_option(name, item_id, desc, initial=None) -%} - -{%- endmacro -%} - -{% macro input_text( - name, initial=None, size=None, maxlength=None, placeholder=None, - required=None, pattern=None) %} - -{%- endmacro -%} - -{% macro input_number( - name, initial=None, size=None, maxlength=None, placeholder=None, - required=None) %} - -{%- endmacro -%} - -{% macro input_textarea( - name, initial, rows, cols, placeholder=None, show_pos=False) -%} -
- - {% if show_pos %} -

Line: Column:

- - {% endif %} -
-{%- endmacro -%} - -{%- macro input_checkbox(name, initial) %} - -{%- endmacro -%} - - - - - {% block head %} - - - {% if is_test %} - - - {% else %} - - {% endif %} +{% extends "macros.html" %} + +{% block html %} + + + + {% block head %} + + + {% if is_test %} + + + {% else %} + + {% endif %} - - - Chellow {% block title %}{% endblock %} - - {% block inside_head %}{% endblock %} - {% endblock %} - - - {% block body %} -
-
- - -
- {% if global_alerts %} + + + + +
+ {% if global_alerts %}
    - {% for message in messages %} -
  • {{message}}
  • + {% for alert in global_alerts %} +
  • {{alert|safe}}
  • {% endfor %}
{% endif %} - {% endwith %} - {% block content %} - {% endblock %} -
- {% endblock %} - - + + {% with messages = get_flashed_messages() %} + {% if messages %} +
    + {% for message in messages %} +
  • {{message}}
  • + {% endfor %} +
+ {% endif %} + {% endwith %} + {% block content %} + {% endblock %} +
+ {% endblock %} + + +{% endblock %} diff --git a/chellow/templates/e/site_add_e_supply.html b/chellow/templates/e/site_add_e_supply.html new file mode 100644 index 000000000..5e95c8ecb --- /dev/null +++ b/chellow/templates/e/site_add_e_supply.html @@ -0,0 +1,52 @@ +{% extends "base.html" %} + +{% block title %} + » Sites » {{site.code}} {{site.name}} » Add Electricity SUpply +{% endblock %} + +{% block nav %} + Sites » + {{site.code}} {{site.name}} » + Add Electricity Supply +{% endblock %} + +{% block content %} +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+{% endblock %} diff --git a/chellow/templates/e/site_add_e_supply_form.html b/chellow/templates/e/site_add_e_supply_form.html new file mode 100644 index 000000000..60bc08cda --- /dev/null +++ b/chellow/templates/e/site_add_e_supply_form.html @@ -0,0 +1,174 @@ +{% extends "macros.html" %} + +{% block html %} + Add an electricity supply + {% with messages = get_flashed_messages() %} + {% if messages %} + +
    + {% for message in messages %} +
  • {{message}}
  • + {% endfor %} +
+ {% endif %} + {% endwith %} + {{input_text('name', required=True)}} + {{input_date('start')}} + + + {% if source.code in ('gen', 'gen-net') %} + + + {% endif %} + {{input_text('msn')}} + + + + + + + + + + + + + + + {{input_text('mop_account', required=True)}} + + + {{input_text('dc_account', required=True)}} + + + + + + + + + + + + + + {{input_textarea('properties', '{}', 10, 80)}} + + {{input_checkbox('has_imp_mpan')}} + + {% if request.values.has_imp_mpan == 'true' %} +
+ Import + + {{input_text('imp_mpan_core', '', 35, pattern='[0-9 ]*', required=True)}} + + + {{input_number('imp_sc', '0', required=True)}} + + + + {{input_text('imp_supplier_account', required=True)}} +
+ {% endif %} + + {{input_checkbox('has_exp_mpan')}} + + {% if request.values.has_exp_mpan == 'true' %} +
+ Export + + {{input_text('exp_mpan_core', '', 35, pattern='[0-9 ]*', required=True)}} + + + + + + {{input_number('exp_sc', '0', required=True)}} + + + + {{input_text('exp_supplier_account', required=True)}} +
+ {% endif %} + +{% endblock %} diff --git a/chellow/templates/macros.html b/chellow/templates/macros.html new file mode 100644 index 000000000..beece3edd --- /dev/null +++ b/chellow/templates/macros.html @@ -0,0 +1,179 @@ +{%- macro input_date(prefix, initial=None, resolution='minute') -%} + {% if prefix != None %} + {% set year_field = prefix + '_year' %} + {% set month_field = prefix + '_month' %} + {% set day_field = prefix + '_day' %} + {% set hour_field = prefix + '_hour' %} + {% set minute_field = prefix + '_minute' %} + {% else %} + {% set year_field = 'year' %} + {% set month_field = 'month' %} + {% set day_field = 'day' %} + {% set hour_field = 'hour' %} + {% set minute_field = 'minute' %} + {% endif %} + + {% set initial = initial|now_if_none|to_ct %} +
+ + + {%- if resolution in ['month', 'day', 'hour', 'minute'] -%} + - + {%- endif -%} + + {% if resolution in ['day', 'hour', 'minute'] -%} + - + {%- endif -%} + + {% if resolution in ['hour', 'minute'] %} + + {%- endif -%} + + {% if resolution == 'minute' -%} + : + {%- endif %} +
+{%- endmacro -%} + +{%- macro input_option(name, item_id, desc, initial=None) -%} + +{%- endmacro -%} + +{% macro input_text( + name, initial=None, size=None, maxlength=None, placeholder=None, + required=None, pattern=None) %} + +{%- endmacro -%} + +{% macro input_number( + name, initial=None, size=None, maxlength=None, placeholder=None, + required=None) %} + +{%- endmacro -%} + +{% macro input_textarea( + name, initial, rows, cols, placeholder=None, show_pos=False) -%} +
+ + {% if show_pos %} +

Line: Column:

+ + {% endif %} +
+{%- endmacro -%} + +{%- macro input_checkbox(name, initial) %} + +{%- endmacro -%} + +{%- macro messages() %} + {% with msgs = get_flashed_messages() %} + {% if msgs %} +
    + {% for message in mgs %} +
  • {{message}}
  • + {% endfor %} +
+ {% endif %} + {% endwith %} +{%- endmacro -%} + +{% block html %} +{% endblock %} diff --git a/chellow/templates/site.html b/chellow/templates/site.html index 85ac45268..ef585a4fd 100644 --- a/chellow/templates/site.html +++ b/chellow/templates/site.html @@ -69,7 +69,10 @@ {% endif %} - + diff --git a/chellow/templates/site_edit.html b/chellow/templates/site_edit.html index ca6de6bb1..63911d578 100644 --- a/chellow/templates/site_edit.html +++ b/chellow/templates/site_edit.html @@ -46,165 +46,6 @@ -
Electricity supplies that power this site + Electricity supplies that power this site + [add] +
View
- - - - - - - - - - - - - {% for era in eras %} - - - - - - - - - {% endfor %} - -
Eras
FromToSourceSupplyImport MPAN coreExport MPAN core
{{era.start_date|hh_format}}{{era.finish_date|hh_format}}{{era.supply.source.code}}{{era.supply.name}} - {% if era.imp_mpan_core %} - {{era.imp_mpan_core}} - {% endif %} - - {% if era.exp_mpan_core %} - {{era.exp_mpan_core}} - {% endif %} -
- -
-
- Insert an electricity supply - - - - - {{input_text('name', required=True)}} - - {{input_date('start')}} - - {{input_text('msn')}} - - - - - {{input_text('mop_account')}} - - - {{input_text('dc_account')}} - - - - {{input_text('mtc_code', pattern='[0-9]*', maxlength='3')}} - - - - - {{input_text('ssc_code')}} - - - - {{input_textarea('properties', '{}', 20, 80)}} -
- Import - - {{input_text('imp_mpan_core', '', 35, pattern='[0-9 ]*')}} - - {{input_text('imp_llfc_code', pattern='[a-zA-Z0-9]{3}', maxlength='3')}} - - {{input_number('imp_sc', '0', required=True)}} - - - - {{input_text('imp_supplier_account')}} -
-
- Export - - {{input_text('exp_mpan_core', '', 35, pattern='[0-9 ]*')}} - - {{input_text('exp_llfc_code', maxlength='3', pattern='[0-9]*')}} - - {{input_number('exp_sc', '0', required=True)}} - - - - {{input_text('exp_supplier_account')}} -
- -
-
diff --git a/chellow/utils.py b/chellow/utils.py index 4a59b7253..d519911c1 100644 --- a/chellow/utils.py +++ b/chellow/utils.py @@ -45,6 +45,20 @@ def req_int(name): raise BadRequest(f"Problem parsing the field {name} as an integer: {e}") +def req_int_none(name): + val = req_str(name) + if val == "": + return None + else: + try: + return int(val) + except ValueError as e: + raise BadRequest( + f"Problem parsing the field '{name}' with value '{val}' as an integer: " + f"{e}" + ) + + def req_zish(name): try: return loads(req_str(name)) diff --git a/chellow/views.py b/chellow/views.py index aec947d38..3f39fb113 100644 --- a/chellow/views.py +++ b/chellow/views.py @@ -99,7 +99,6 @@ SiteGEra, Snag, Source, - Ssc, Supply, User, UserRole, @@ -111,7 +110,6 @@ ct_datetime, ct_datetime_now, hh_range, - parse_mpan_core, req_bool, req_date, req_decimal, @@ -733,40 +731,6 @@ def edi_viewer_post(): def site_edit_get(site_id): try: site = Site.get_by_id(g.sess, site_id) - sources = g.sess.query(Source).order_by(Source.code) - generator_types = g.sess.query(GeneratorType).order_by(GeneratorType.code) - gsp_groups = g.sess.query(GspGroup).order_by(GspGroup.code) - eras = ( - g.sess.query(Era) - .join(SiteEra) - .filter(SiteEra.site == site) - .order_by(Era.start_date.desc()) - ) - mop_contracts = ( - g.sess.query(Contract) - .join(MarketRole) - .filter(MarketRole.code == "M") - .order_by(Contract.name) - ) - dc_contracts = ( - g.sess.query(Contract) - .join(MarketRole) - .filter(MarketRole.code.in_(("C", "D"))) - .order_by(Contract.name) - ) - supplier_contracts = ( - g.sess.query(Contract) - .join(MarketRole) - .filter(MarketRole.code == "X") - .order_by(Contract.name) - ) - pcs = g.sess.query(Pc).order_by(Pc.code) - cops = g.sess.query(Cop).order_by(Cop.code) - comms = g.sess.execute(select(Comm).order_by(Comm.code)).scalars() - energisation_statuses = g.sess.query(EnergisationStatus).order_by( - EnergisationStatus.code - ) - default_energisation_status = EnergisationStatus.get_by_code(g.sess, "E") g_contracts = g.sess.execute( select(GContract) .where(GContract.is_industry == false()) @@ -780,18 +744,6 @@ def site_edit_get(site_id): return render_template( "site_edit.html", site=site, - sources=sources, - generator_types=generator_types, - gsp_groups=gsp_groups, - eras=eras, - energisation_statuses=energisation_statuses, - default_energisation_status=default_energisation_status, - mop_contracts=mop_contracts, - dc_contracts=dc_contracts, - supplier_contracts=supplier_contracts, - pcs=pcs, - cops=cops, - comms=comms, g_contracts=g_contracts, g_units=g_units, g_exit_zones=g_exit_zones, @@ -803,16 +755,6 @@ def site_edit_get(site_id): return render_template( "site_edit.html", site=site, - sources=sources, - generator_types=generator_types, - gsp_groups=gsp_groups, - eras=eras, - mop_contracts=mop_contracts, - dc_contracts=dc_contracts, - supplier_contracts=supplier_contracts, - pcs=pcs, - cops=cops, - comms=comms, g_contracts=g_contracts, g_units=g_units, g_exit_zones=g_exit_zones, @@ -838,123 +780,6 @@ def site_edit_post(site_id): flash("Site updated successfully.") return chellow_redirect(f"/sites/{site.id}", 303) - elif "insert_electricity" in request.form: - start_date = req_date("start") - name = req_str("name") - source_id = req_int("source_id") - source = Source.get_by_id(g.sess, source_id) - gsp_group_id = req_int("gsp_group_id") - gsp_group = GspGroup.get_by_id(g.sess, gsp_group_id) - mop_contract_id = req_int("mop_contract_id") - mop_contract = Contract.get_mop_by_id(g.sess, mop_contract_id) - mop_account = req_str("mop_account") - dc_contract_id = req_int("dc_contract_id") - dc_contract = Contract.get_dc_by_id(g.sess, dc_contract_id) - dc_account = req_str("dc_account") - msn = req_str("msn") - pc_id = req_int("pc_id") - pc = Pc.get_by_id(g.sess, pc_id) - mtc_code = req_str("mtc_code") - cop_id = req_int("cop_id") - cop = Cop.get_by_id(g.sess, cop_id) - comm_id = req_int("comm_id") - comm = Comm.get_by_id(g.sess, comm_id) - ssc_code = req_str("ssc_code") - if len(ssc_code) > 0: - ssc = Ssc.get_by_code(g.sess, ssc_code, start_date) - else: - ssc = None - energisation_status_id = req_int("energisation_status_id") - energisation_status = EnergisationStatus.get_by_id( - g.sess, energisation_status_id - ) - properties = req_zish("properties") - if "generator_type_id" in request.form: - generator_type_id = req_int("generator_type_id") - generator_type = GeneratorType.get_by_id(g.sess, generator_type_id) - else: - generator_type = None - - if "imp_mpan_core" in request.form: - imp_mpan_core_raw = req_str("imp_mpan_core") - if len(imp_mpan_core_raw) == 0: - imp_mpan_core = None - else: - imp_mpan_core = parse_mpan_core(imp_mpan_core_raw) - else: - imp_mpan_core = None - - if imp_mpan_core is None: - imp_supplier_contract = None - imp_supplier_account = None - imp_sc = None - imp_llfc_code = None - else: - imp_supplier_contract_id = req_int("imp_supplier_contract_id") - imp_supplier_contract = Contract.get_supplier_by_id( - g.sess, imp_supplier_contract_id - ) - imp_supplier_account = req_str("imp_supplier_account") - imp_sc = req_int("imp_sc") - imp_llfc_code = req_str("imp_llfc_code") - - if "exp_mpan_core" in request.form: - exp_mpan_core_raw = req_str("exp_mpan_core") - if len(exp_mpan_core_raw) == 0: - exp_mpan_core = None - else: - exp_mpan_core = parse_mpan_core(exp_mpan_core_raw) - else: - exp_mpan_core = None - - if exp_mpan_core is None: - exp_supplier_contract = None - exp_supplier_account = None - exp_sc = None - exp_llfc_code = None - else: - exp_supplier_contract_id = req_int("exp_supplier_contract_id") - exp_supplier_contract = Contract.get_supplier_by_id( - g.sess, exp_supplier_contract_id - ) - exp_supplier_account = req_str("exp_supplier_account") - exp_sc = req_int("exp_sc") - exp_llfc_code = req_str("exp_llfc_code") - - supply = site.insert_e_supply( - g.sess, - source, - generator_type, - name, - start_date, - None, - gsp_group, - mop_contract, - mop_account, - dc_contract, - dc_account, - msn, - pc, - mtc_code, - cop, - comm, - ssc, - energisation_status, - properties, - imp_mpan_core, - imp_llfc_code, - imp_supplier_contract, - imp_supplier_account, - imp_sc, - exp_mpan_core, - exp_llfc_code, - exp_supplier_contract, - exp_supplier_account, - exp_sc, - ) - g.sess.commit() - return chellow_redirect(f"/e/supplies/{supply.id}", 303) - elif "insert_gas" in request.form: name = req_str("name") msn = req_str("msn") diff --git a/test/e/test_e_views.py b/test/e/test_e_views.py index 3498b83cf..33a3dbaac 100644 --- a/test/e/test_e_views.py +++ b/test/e/test_e_views.py @@ -2232,6 +2232,359 @@ def test_scenario_edit_post(sess, client): match(response, 303, r"/scenarios/1") +def test_site_add_e_supply__form_get(client, sess): + vf = to_utc(ct_datetime(2000, 1, 1)) + site = Site.insert(sess, "CI017", "Water Works") + + market_role_Z = MarketRole.get_by_code(sess, "Z") + participant = Participant.insert(sess, "CALB", "AK Industries") + participant.insert_party(sess, market_role_Z, "None core", vf, None, None) + market_role_X = MarketRole.insert(sess, "X", "Supplier") + market_role_M = MarketRole.insert(sess, "M", "Mop") + market_role_C = MarketRole.insert(sess, "C", "HH Dc") + market_role_R = MarketRole.insert(sess, "R", "Distributor") + participant.insert_party(sess, market_role_M, "Fusion Mop Ltd", vf, None, None) + participant.insert_party(sess, market_role_X, "Fusion Ltc", vf, None, None) + participant.insert_party(sess, market_role_C, "Fusion DC", vf, None, None) + Contract.insert_mop(sess, "Fusion", participant, "", {}, vf, None, {}) + Contract.insert_dc(sess, "Fusion DC 2000", participant, "", {}, vf, None, {}) + insert_cops(sess) + insert_comms(sess) + Contract.insert_supplier( + sess, "Fusion Supplier 2000", participant, "", {}, vf, None, {} + ) + dno = participant.insert_party(sess, market_role_R, "WPD", vf, None, "22") + meter_type = MeterType.insert(sess, "C5", "COP 1-5", utc_datetime(2000, 1, 1), None) + meter_payment_type = MeterPaymentType.insert(sess, "CR", "Credit", vf, None) + mtc = Mtc.insert(sess, "845", False, True, vf, None) + MtcParticipant.insert( + sess, + mtc, + participant, + "HH COP5 And Above With Comms", + False, + True, + meter_type, + meter_payment_type, + 0, + vf, + None, + ) + insert_voltage_levels(sess) + voltage_level = VoltageLevel.get_by_code(sess, "HV") + dno.insert_llfc(sess, "510", "PC 5-8 & HH HV", voltage_level, False, True, vf, None) + insert_sources(sess) + insert_energisation_statuses(sess) + Pc.insert(sess, "00", "", vf, None) + + sess.commit() + + query_string = { + "dno_id": "", + "source_id": "", + "pc_id": "", + "mtc_participant_id": "", + } + response = client.get( + f"/e/sites/{site.id}/add_e_supply/form", query_string=query_string + ) + patterns = [ + r'\s*' - r'\s*' - r'\s*' - r"", - r'", - ] - match(response, 400, *patterns) - - def test_site_get(client, sess): valid_from = to_utc(ct_datetime(2000, 1, 1)) site = Site.insert(sess, "CI017", "Water Works") @@ -1043,57 +898,15 @@ def test_non_core_rate_script_edit_get(sess, client): match(response, 200) -def test_site_edit_get(sess, client, app): +def test_site_edit_get(sess, client): vf = to_utc(ct_datetime(2000, 1, 1)) site = Site.insert(sess, "CI017", "Water Works") - market_role_Z = MarketRole.get_by_code(sess, "Z") - participant = Participant.insert(sess, "CALB", "AK Industries") - participant.insert_party(sess, market_role_Z, "None core", vf, None, None) - market_role_X = MarketRole.insert(sess, "X", "Supplier") - market_role_M = MarketRole.insert(sess, "M", "Mop") - market_role_C = MarketRole.insert(sess, "C", "HH Dc") - market_role_R = MarketRole.insert(sess, "R", "Distributor") - participant.insert_party(sess, market_role_M, "Fusion Mop Ltd", vf, None, None) - participant.insert_party(sess, market_role_X, "Fusion Ltc", vf, None, None) - participant.insert_party(sess, market_role_C, "Fusion DC", vf, None, None) - Contract.insert_mop(sess, "Fusion", participant, "", {}, vf, None, {}) - Contract.insert_dc(sess, "Fusion DC 2000", participant, "", {}, vf, None, {}) - insert_cops(sess) - insert_comms(sess) - Contract.insert_supplier( - sess, "Fusion Supplier 2000", participant, "", {}, vf, None, {} - ) - dno = participant.insert_party(sess, market_role_R, "WPD", vf, None, "22") - meter_type = MeterType.insert(sess, "C5", "COP 1-5", utc_datetime(2000, 1, 1), None) - meter_payment_type = MeterPaymentType.insert(sess, "CR", "Credit", vf, None) - mtc = Mtc.insert(sess, "845", False, True, vf, None) - MtcParticipant.insert( - sess, - mtc, - participant, - "HH COP5 And Above With Comms", - False, - True, - meter_type, - meter_payment_type, - 0, - vf, - None, - ) - insert_voltage_levels(sess) - voltage_level = VoltageLevel.get_by_code(sess, "HV") - dno.insert_llfc(sess, "510", "PC 5-8 & HH HV", voltage_level, False, True, vf, None) - insert_sources(sess) - insert_energisation_statuses(sess) - GContract.insert_industry(sess, "cv", "", {}, vf, None, {}) sess.commit() response = client.get(f"/sites/{site.id}/edit") patterns = [ - r'\s*', ] match(response, 200, *patterns) @@ -1104,242 +917,6 @@ def test_rate_server_get(sess, client): match(response, 200) -def test_site_edit_post_hh(sess, client): - valid_from = to_utc(ct_datetime(1996, 1, 1)) - site = Site.insert(sess, "CI017", "Water Works") - - market_role_Z = MarketRole.get_by_code(sess, "Z") - participant = Participant.insert(sess, "CALB", "AK Industries") - participant.insert_party( - sess, market_role_Z, "None core", utc_datetime(2000, 1, 1), None, None - ) - market_role_X = MarketRole.insert(sess, "X", "Supplier") - market_role_M = MarketRole.insert(sess, "M", "Mop") - market_role_C = MarketRole.insert(sess, "C", "HH Dc") - market_role_R = MarketRole.insert(sess, "R", "Distributor") - participant.insert_party( - sess, market_role_M, "Fusion Mop Ltd", utc_datetime(2000, 1, 1), None, None - ) - participant.insert_party( - sess, market_role_X, "Fusion Ltc", utc_datetime(2000, 1, 1), None, None - ) - participant.insert_party( - sess, market_role_C, "Fusion DC", utc_datetime(2000, 1, 1), None, None - ) - mop_contract = Contract.insert_mop( - sess, "Fusion", participant, "", {}, utc_datetime(2000, 1, 1), None, {} - ) - dc_contract = Contract.insert_dc( - sess, "Fusion DC 2000", participant, "", {}, utc_datetime(2000, 1, 1), None, {} - ) - pc = Pc.insert(sess, "00", "hh", utc_datetime(2000, 1, 1), None) - insert_cops(sess) - cop = Cop.get_by_code(sess, "5") - insert_comms(sess) - comm = Comm.get_by_code(sess, "GSM") - imp_supplier_contract = Contract.insert_supplier( - sess, - "Fusion Supplier 2000", - participant, - "", - {}, - utc_datetime(2000, 1, 1), - None, - {}, - ) - dno = participant.insert_party( - sess, market_role_R, "WPD", utc_datetime(2000, 1, 1), None, "22" - ) - meter_type = MeterType.insert(sess, "C5", "COP 1-5", utc_datetime(2000, 1, 1), None) - meter_payment_type = MeterPaymentType.insert( - sess, "CR", "Credit", utc_datetime(1996, 1, 1), None - ) - mtc = Mtc.insert(sess, "845", False, True, valid_from, None) - mtc_participant = MtcParticipant.insert( - sess, - mtc, - participant, - "HH COP5 And Above With Comms", - False, - True, - meter_type, - meter_payment_type, - 0, - utc_datetime(1996, 1, 1), - None, - ) - insert_voltage_levels(sess) - voltage_level = VoltageLevel.get_by_code(sess, "HV") - llfc = dno.insert_llfc( - sess, - "510", - "PC 5-8 & HH HV", - voltage_level, - False, - True, - utc_datetime(1996, 1, 1), - None, - ) - MtcLlfc.insert(sess, mtc_participant, llfc, valid_from, None) - insert_sources(sess) - source = Source.get_by_code(sess, "net") - gsp_group = GspGroup.insert(sess, "_L", "South Western") - insert_energisation_statuses(sess) - energisation_status = EnergisationStatus.get_by_code(sess, "E") - sess.commit() - - data = { - "source_id": source.id, - "gsp_group_id": gsp_group.id, - "mop_contract_id": mop_contract.id, - "dc_contract_id": dc_contract.id, - "dc_account": "dc1", - "msn": "jjl4", - "pc_id": pc.id, - "mtc_code": "845", - "cop_id": cop.id, - "comm_id": comm.id, - "ssc_code": "", - "properties": "{}", - "start_year": "2021", - "start_month": "01", - "start_day": "01", - "start_hour": "00", - "start_minute": "00", - "mop_account": "ma1", - "imp_mpan_core": "22 6644 1123 880", - "imp_supplier_contract_id": imp_supplier_contract.id, - "imp_supplier_account": "sup1", - "imp_sc": "200", - "imp_llfc_code": "510", - "energisation_status_id": energisation_status.id, - "insert_electricity": "insert_electricity", - "name": "main", - } - response = client.post(f"/sites/{site.id}/edit", data=data) - match(response, 303, "/e/supplies") - - -def test_site_edit_post_nhh(sess, client): - valid_from = to_utc(ct_datetime(1996, 1, 1)) - site = Site.insert(sess, "CI017", "Water Works") - - market_role_Z = MarketRole.get_by_code(sess, "Z") - participant = Participant.insert(sess, "CALB", "AK Industries") - participant.insert_party( - sess, market_role_Z, "None core", utc_datetime(2000, 1, 1), None, None - ) - market_role_X = MarketRole.insert(sess, "X", "Supplier") - market_role_M = MarketRole.insert(sess, "M", "Mop") - market_role_C = MarketRole.insert(sess, "C", "HH Dc") - market_role_R = MarketRole.insert(sess, "R", "Distributor") - participant.insert_party( - sess, market_role_M, "Fusion Mop Ltd", utc_datetime(2000, 1, 1), None, None - ) - participant.insert_party( - sess, market_role_X, "Fusion Ltc", utc_datetime(2000, 1, 1), None, None - ) - participant.insert_party( - sess, market_role_C, "Fusion DC", utc_datetime(2000, 1, 1), None, None - ) - mop_contract = Contract.insert_mop( - sess, "Fusion", participant, "", {}, utc_datetime(2000, 1, 1), None, {} - ) - dc_contract = Contract.insert_dc( - sess, "Fusion DC 2000", participant, "", {}, utc_datetime(2000, 1, 1), None, {} - ) - pc = Pc.insert(sess, "03", "hh", utc_datetime(2000, 1, 1), None) - insert_cops(sess) - cop = Cop.get_by_code(sess, "5") - insert_comms(sess) - comm = Comm.get_by_code(sess, "GSM") - imp_supplier_contract = Contract.insert_supplier( - sess, - "Fusion Supplier 2000", - participant, - "", - {}, - utc_datetime(2000, 1, 1), - None, - {}, - ) - dno = participant.insert_party( - sess, market_role_R, "WPD", utc_datetime(2000, 1, 1), None, "22" - ) - meter_type = MeterType.insert(sess, "C5", "COP 1-5", utc_datetime(2000, 1, 1), None) - meter_payment_type = MeterPaymentType.insert( - sess, "CR", "Credit", utc_datetime(1996, 1, 1), None - ) - mtc = Mtc.insert(sess, "845", False, True, valid_from, None) - mtc_participant = MtcParticipant.insert( - sess, - mtc, - participant, - "HH COP5 And Above With Comms", - False, - True, - meter_type, - meter_payment_type, - 0, - valid_from, - None, - ) - insert_voltage_levels(sess) - voltage_level = VoltageLevel.get_by_code(sess, "HV") - llfc = dno.insert_llfc( - sess, - "510", - "PC 5-8 & HH HV", - voltage_level, - False, - True, - utc_datetime(1996, 1, 1), - None, - ) - insert_sources(sess) - source = Source.get_by_code(sess, "net") - gsp_group = GspGroup.insert(sess, "_L", "South Western") - insert_energisation_statuses(sess) - energisation_status = EnergisationStatus.get_by_code(sess, "E") - ssc = Ssc.insert(sess, "0001", "All", True, utc_datetime(1996, 1, 1), None) - MtcLlfc.insert(sess, mtc_participant, llfc, valid_from, None) - mtc_ssc = MtcSsc.insert(sess, mtc_participant, ssc, valid_from, None) - mtc_llfc_ssc = MtcLlfcSsc.insert(sess, mtc_ssc, llfc, valid_from, None) - MtcLlfcSscPc.insert(sess, mtc_llfc_ssc, pc, valid_from, None) - sess.commit() - - data = { - "source_id": source.id, - "gsp_group_id": gsp_group.id, - "mop_contract_id": mop_contract.id, - "dc_contract_id": dc_contract.id, - "dc_account": "dc1", - "msn": "jjl4", - "pc_id": pc.id, - "mtc_code": "845", - "cop_id": cop.id, - "comm_id": comm.id, - "ssc_code": ssc.code, - "properties": "{}", - "start_year": "2021", - "start_month": "01", - "start_day": "01", - "start_hour": "00", - "start_minute": "00", - "mop_account": "ma1", - "imp_mpan_core": "22 6644 1123 880", - "imp_supplier_contract_id": imp_supplier_contract.id, - "imp_supplier_account": "sup1", - "imp_sc": "200", - "imp_llfc_code": "510", - "energisation_status_id": energisation_status.id, - "insert_electricity": "insert_electricity", - "name": "main", - } - response = client.post(f"/sites/{site.id}/edit", data=data) - match(response, 303) - - def test_report_run_spreadsheet_get(sess, client): report_run = ReportRun.insert(sess, "bill_check", None, "_b_88", {}) report_run.insert_row(sess, "", ["clump"], {}, {})