chellow 1717768383.0.0__py3-none-any.whl → 1718704260.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of chellow might be problematic. Click here for more details.

chellow/gas/views.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import csv
2
2
  from collections import defaultdict
3
3
  from datetime import datetime as Datetime
4
+ from decimal import Decimal
4
5
  from importlib import import_module
5
6
  from io import BytesIO, StringIO
6
7
 
@@ -22,6 +23,8 @@ from sqlalchemy.orm import joinedload
22
23
 
23
24
  from werkzeug.exceptions import BadRequest
24
25
 
26
+ from zish import dumps, loads
27
+
25
28
  import chellow.gas.bill_import
26
29
  import chellow.gas.dn_rate_parser
27
30
  from chellow.models import (
@@ -231,24 +234,19 @@ def supply_get(g_supply_id):
231
234
  for report_id in properties["g_supply_reports"]:
232
235
  batch_reports.append(Report.get_by_id(g.sess, report_id))
233
236
 
234
- truncated_note = None
235
- is_truncated = False
236
- note = None
237
- if len(g_supply.note.strip()) == 0:
238
- note_str = "{'notes': []}"
239
- else:
240
- note_str = g_supply.note
237
+ note = truncated_line = None
238
+ g_supply_note = (
239
+ {"notes": []} if len(g_supply.note.strip()) == 0 else loads(g_supply.note)
240
+ )
241
241
 
242
- supply_note = eval(note_str)
243
- notes = supply_note["notes"]
242
+ notes = g_supply_note["notes"]
244
243
  if len(notes) > 0:
245
- note = notes[0]
244
+ note = notes[-1]
246
245
  lines = note["body"].splitlines()
247
246
  if len(lines) > 0:
248
- trunc_line = lines[0][:50]
249
- if len(lines) > 1 or len(lines[0]) > len(trunc_line):
250
- is_truncated = True
251
- truncated_note = trunc_line
247
+ line0 = lines[0]
248
+ if len(lines) > 1 or len(line0) > 50:
249
+ truncated_line = line0[:50]
252
250
  return render_template(
253
251
  "supply.html",
254
252
  triad_year=triad_year,
@@ -258,8 +256,7 @@ def supply_get(g_supply_id):
258
256
  g_era_bundles=g_era_bundles,
259
257
  g_supply=g_supply,
260
258
  system_properties=properties,
261
- is_truncated=is_truncated,
262
- truncated_note=truncated_note,
259
+ truncated_line=truncated_line,
263
260
  note=note,
264
261
  this_month_start=this_month_start,
265
262
  batch_reports=batch_reports,
@@ -447,8 +444,8 @@ def batch_get(g_batch_id):
447
444
  except KeyError:
448
445
  vbd = vat_breakdown[vat_percentage] = defaultdict(int)
449
446
 
450
- vbd["vat"] += vat_bd["vat"]
451
- vbd["net"] += vat_bd["net"]
447
+ vbd["vat"] += vat_bd.get("vat", Decimal("0"))
448
+ vbd["net"] += vat_bd.get("net", Decimal("0"))
452
449
 
453
450
  config_contract = Contract.get_non_core_by_name(g.sess, "configuration")
454
451
  properties = config_contract.make_properties()
@@ -720,10 +717,9 @@ def supply_notes_get(g_supply_id):
720
717
  g_supply = GSupply.get_by_id(g.sess, g_supply_id)
721
718
 
722
719
  if len(g_supply.note.strip()) > 0:
723
- note_str = g_supply.note
720
+ g_supply_note = loads(g_supply.note)
724
721
  else:
725
- note_str = "{'notes': []}"
726
- g_supply_note = eval(note_str)
722
+ g_supply_note = {"notes": []}
727
723
 
728
724
  return render_template(
729
725
  "supply_notes.html", g_supply=g_supply, g_supply_note=g_supply_note
@@ -741,15 +737,13 @@ def supply_note_add_post(g_supply_id):
741
737
  try:
742
738
  g_supply = GSupply.get_by_id(g.sess, g_supply_id)
743
739
  body = req_str("body")
744
- category = req_str("category")
745
- is_important = req_bool("is_important")
746
740
  if len(g_supply.note.strip()) == 0:
747
- g_supply.note = "{'notes': []}"
748
- note_dict = eval(g_supply.note)
749
- note_dict["notes"].append(
750
- {"category": category, "is_important": is_important, "body": body}
751
- )
752
- g_supply.note = str(note_dict)
741
+ note_dict = {"notes": []}
742
+ else:
743
+ note_dict = loads(g_supply.note)
744
+
745
+ note_dict["notes"].append({"body": body, "timestamp": utc_datetime_now()})
746
+ g_supply.note = dumps(note_dict)
753
747
  g.sess.commit()
754
748
  return chellow_redirect(f"/supplies/{g_supply_id}", 303)
755
749
  except BadRequest as e:
@@ -762,36 +756,43 @@ def supply_note_add_post(g_supply_id):
762
756
  @gas.route("/supplies/<int:g_supply_id>/notes/<int:index>/edit")
763
757
  def supply_note_edit_get(g_supply_id, index):
764
758
  g_supply = GSupply.get_by_id(g.sess, g_supply_id)
765
- g_supply_note = eval(g_supply.note)
759
+ g_supply_note = loads(g_supply.note)
766
760
  note = g_supply_note["notes"][index]
767
761
  note["index"] = index
768
762
  return render_template("supply_note_edit.html", g_supply=g_supply, note=note)
769
763
 
770
764
 
765
+ @gas.route("/supplies/<int:g_supply_id>/notes/<int:index>/edit", methods=["DELETE"])
766
+ def supply_note_edit_delete(g_supply_id, index):
767
+ try:
768
+ g_supply = GSupply.get_by_id(g.sess, g_supply_id)
769
+ g_supply_note = loads(g_supply.note)
770
+ del g_supply_note["notes"][index]
771
+ g_supply.note = dumps(g_supply_note)
772
+ g.sess.commit()
773
+ return hx_redirect(f"/supplies/{g_supply_id}/notes")
774
+ except BadRequest as e:
775
+ flash(e.description)
776
+ g_supply_note = loads(g_supply.note)
777
+ note = g_supply_note["notes"][index]
778
+ note["index"] = index
779
+ return render_template("supply_note_edit.html", g_supply=g_supply, note=note)
780
+
781
+
771
782
  @gas.route("/supplies/<int:g_supply_id>/notes/<int:index>/edit", methods=["POST"])
772
783
  def supply_note_edit_post(g_supply_id, index):
773
784
  try:
774
785
  g_supply = GSupply.get_by_id(g.sess, g_supply_id)
775
- g_supply_note = eval(g_supply.note)
776
- if "delete" in request.values:
777
- del g_supply_note["notes"][index]
778
- g_supply.note = str(g_supply_note)
779
- g.sess.commit()
780
- return chellow_redirect(f"/supplies/{g_supply_id}/notes", 303)
781
- else:
782
- category = req_str("category")
783
- is_important = req_bool("is_important")
784
- body = req_str("body")
785
- note = g_supply_note["notes"][index]
786
- note["category"] = category
787
- note["is_important"] = is_important
788
- note["body"] = body
789
- g_supply.note = str(g_supply_note)
790
- g.sess.commit()
791
- return chellow_redirect(f"/supplies/{g_supply_id}/notes", 303)
786
+ g_supply_note = loads(g_supply.note)
787
+ body = req_str("body")
788
+ note = g_supply_note["notes"][index]
789
+ note["body"] = body
790
+ g_supply.note = dumps(g_supply_note)
791
+ g.sess.commit()
792
+ return hx_redirect(f"/supplies/{g_supply_id}/notes/{index}")
792
793
  except BadRequest as e:
793
794
  flash(e.description)
794
- g_supply_note = eval(g_supply.note)
795
+ g_supply_note = loads(g_supply.note)
795
796
  note = g_supply_note["notes"][index]
796
797
  note["index"] = index
797
798
  return render_template("supply_note_edit.html", g_supply=g_supply, note=note)
@@ -800,7 +801,11 @@ def supply_note_edit_post(g_supply_id, index):
800
801
  @gas.route("/eras/<int:g_era_id>/edit")
801
802
  def era_edit_get(g_era_id):
802
803
  g_era = GEra.get_by_id(g.sess, g_era_id)
803
- supplier_g_contracts = g.sess.query(GContract).order_by(GContract.name)
804
+ supplier_g_contracts = g.sess.scalars(
805
+ select(GContract)
806
+ .where(GContract.is_industry == false())
807
+ .order_by(GContract.name)
808
+ )
804
809
  site_g_eras = (
805
810
  g.sess.query(SiteGEra)
806
811
  .join(Site)
@@ -12,7 +12,6 @@
12
12
 
13
13
  {% block content %}
14
14
  <table>
15
- <legend>Notes</legend>
16
15
  <thead>
17
16
  <tr>
18
17
  <th>Edit</th>
@@ -97,30 +97,16 @@
97
97
  <th><a href="/g/supplies/{{g_supply.id}}/notes">Notes</a></th>
98
98
  <td>
99
99
  {% if note %}
100
- {% if is_truncated %}
101
- <div id="truncated_note">
102
- {{ truncated_note }}
103
- </div>
104
- <div id="full_note" style="display: none;">
105
- <pre
106
- style=" white-space: pre-wrap;"
107
- >{{ g_supply.note }}</pre>
108
- <a
109
- href="JavaScript:void()" onClick="hideText()"
110
- >Less...</a>
111
- </div>
112
- {% else %}
113
- Category: {{note.category}}
114
- {% if note.is_important %}
115
- Important
116
- {% else %}
117
- Not important
118
- {% endif %}
119
- <pre style="display: inline;">{{note.body}}</pre>
120
- {% endif %}
100
+ <pre style="white-space pre-wrap;">
101
+ {%- if note.timestamp -%}<em>{{note.timestamp|hh_format}}</em>{%- endif %}
102
+ {%- if truncated_line -%}
103
+ <details><summary><span>{{truncated_line}}</span></summary>{{note.body}}</details>
104
+ {%- else %} {{note.body}}
105
+ {%- endif -%}
106
+ </pre>
121
107
  {% endif %}
122
108
  </td>
123
- </tr>
109
+ <tr>
124
110
  </table>
125
111
 
126
112
  {% for g_era_bundle in g_era_bundles %}
@@ -5,17 +5,17 @@
5
5
  {% endblock %}
6
6
 
7
7
  {% block nav %}
8
- <a href="/g_supplies">Gas Supplies</a> &raquo;
9
- <a href="/g_supplies/{{g_supply.id}}">{{g_supply.id}}</a> &raquo;
10
- <a href="/g_supplies/{{g_supply.id}}/notes">Notes</a> &raquo; Add
8
+ <a href="/g/supplies">Gas Supplies</a> &raquo;
9
+ <a href="/g/supplies/{{g_supply.id}}">{{g_supply.id}}</a> &raquo;
10
+ <a href="/g/supplies/{{g_supply.id}}/notes">Notes</a> &raquo; Add
11
11
  {% endblock %}
12
12
 
13
13
  {% block content %}
14
- <form method="post" action="/g_supplies/{{g_supply.id}}/notes/add">
15
- <input type="hidden" name="g_supply_id" value="{{g_supply.id}}">
16
- <label>Category</label> {{input_text('category')}}
17
- <label>Important?</label> {{input_checkbox('is_important')}}
18
- <label>Body</label> {{input_textarea('body', '', 30, 80)}}
19
- <input type="submit" value="Add">
14
+ <form method="post" action="/g/supplies/{{g_supply.id}}/notes/add">
15
+ <fieldset>
16
+ <input type="hidden" name="g_supply_id" value="{{g_supply.id}}">
17
+ <label>Body</label> {{input_textarea('body', '', 30, 80)}}
18
+ <input type="submit" value="Add">
19
+ </fieldset>
20
20
  </form>
21
21
  {% endblock %}
@@ -5,27 +5,30 @@
5
5
  {% endblock %}
6
6
 
7
7
  {% block nav %}
8
- <a href="/g_supplies">Gas Supplies</a> &raquo;
9
- <a href="/g_supplies/{{g_supply.id}}">{{g_supply.id}}</a> &raquo;
10
- <a href="/g_supplies/{{g_supply.id}}/notes">Notes</a> &raquo;
11
- {{note.index}} Edit
8
+ <a href="/g/supplies">Gas Supplies</a> &raquo;
9
+ <a href="/g/supplies/{{g_supply.id}}">{{g_supply.id}}</a> &raquo;
10
+ <a href="/g/supplies/{{g_supply.id}}/notes">Notes</a> &raquo; {{note.index}} Edit
12
11
  {% endblock %}
13
12
 
14
13
  {% block content %}
15
- <form method="post" action="/g_supplies/{{g_supply.id}}/notes/{{note.index}}/edit">
14
+ <form method="post" action="/g/supplies/{{g_supply.id}}/notes/{{note.index}}/edit">
16
15
  <fieldset>
17
- <legend>Edit Note</legend>
18
- <label>Category</label> {{input_text('category', note.category)}}
19
- <label>Important?</label> {{input_checkbox('is_important', note.is_important)}}
16
+ <legend>Update Supply Note</legend>
17
+ {% if note.timestamp %}
18
+ <label>Timestamp</label> {{ note.timestamp|hh_format }}
19
+ {% endif %}
20
20
  <label>Body</label> {{input_textarea('body', note.body, 30, 80)}}
21
- <input type="submit" name="update" value="Edit">
21
+ <input type="submit" value="Update">
22
22
  </fieldset>
23
23
  </form>
24
24
 
25
- <form action="/g_supplies/{{g_supply.id}}/notes/{{note.index}}/edit" method="post">
25
+ <form
26
+ hx-delete="/g/supplies/{{g_supply.id}}/notes/{{note.index}}/edit"
27
+ hx-confirm="Are you sure you want to delete this note?"
28
+ >
26
29
  <fieldset>
27
- <legend>Delete Note</legend>
28
- <input type="submit" name="delete" value="Delete">
30
+ <legend>Delete Supply Note</legend>
31
+ <input type="submit" value="Delete">
29
32
  </fieldset>
30
33
  </form>
31
34
  {% endblock %}
@@ -5,9 +5,9 @@
5
5
  {% endblock %}
6
6
 
7
7
  {% block nav %}
8
- <a href="/g_supplies">Gas Supplies</a> &raquo;
9
- <a href="/g_supplies/{{g_supply.id}}">{{g_supply.id}}</a> &raquo; Notes
10
- [<a href="/g_supplies/{{g_supply.id}}/notes/add">add</a>]
8
+ <a href="/g/supplies">Gas Supplies</a> &raquo;
9
+ <a href="/g/supplies/{{g_supply.id}}">{{g_supply.id}}</a> &raquo; Notes
10
+ [<a href="/g/supplies/{{g_supply.id}}/notes/add">add</a>]
11
11
  {% endblock %}
12
12
 
13
13
  {% block content %}
@@ -15,25 +15,17 @@
15
15
  <thead>
16
16
  <tr>
17
17
  <th>Edit</th>
18
- <th>Category</th>
19
- <th>Importance</th>
18
+ <th>Timestamp</th>
20
19
  <th>Body</th>
21
20
  </tr>
22
21
  </thead>
23
22
  <tbody>
24
- {% for note in g_supply_note.notes %}
23
+ {% for note in g_supply_note.notes|reverse %}
25
24
  <tr>
26
25
  <td>
27
- [<a href="/g_supplies/{{g_supply.id}}/notes/{{loop.index0}}/edit">edit</a>]
28
- </td>
29
- <td>{{note.category}}</td>
30
- <td>
31
- {% if note.is_important %}
32
- High
33
- {% else %}
34
- Low
35
- {% endif %}
26
+ [<a href="/g/supplies/{{g_supply.id}}/notes/{{loop.index0}}/edit">edit</a>]
36
27
  </td>
28
+ <td>{% if note.timestamp %}{{note.timestamp|hh_format}}{% endif %}</td>
37
29
  <td>
38
30
  <pre style=" white-space: pre-wrap;">{{note.body}}</pre>
39
31
  </td>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: chellow
3
- Version: 1717768383.0.0
3
+ Version: 1718704260.0.0
4
4
  Summary: Web Application for checking UK energy bills.
5
5
  Project-URL: Homepage, https://github.com/WessexWater/chellow
6
6
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
@@ -65,7 +65,7 @@ chellow/gas/cv.py,sha256=4cdYYQ8Qak6NeYdBCB4YaQ0jX8-UkaydIIdibCQuXxM,7344
65
65
  chellow/gas/dn_rate_parser.py,sha256=Mq8rAcUEUxIQOks59bsCKl8GrefvoHbrTCHqon9N0z0,11340
66
66
  chellow/gas/engine.py,sha256=jT7m6vddi5GnWd51wCYEVhBS-LZEn1T9ggZX7Y9HGK0,25263
67
67
  chellow/gas/transportation.py,sha256=Bkg8TWOs-v0ES-4qqwbleiOhqbE_t2KauUx9JYMZELM,5300
68
- chellow/gas/views.py,sha256=ZIMqByN0uBpf3y9wkMi-VogC1-NaHs-oO7WRVDk9Kkw,57428
68
+ chellow/gas/views.py,sha256=N_vj5A3ia0FmLm2M18bcZQTGpVQXd7oHrIiFXa44aLo,57511
69
69
  chellow/reports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
70
  chellow/reports/report_109.py,sha256=S8fsOwh-jVWGL0RsgyYLdqn00BAvlkBbi4VfTSGI-Mc,11181
71
71
  chellow/reports/report_111.py,sha256=AlYjvCDpGNe1qBuzW52EONWDsFaIVElug0Vpe9qm1PY,28169
@@ -315,7 +315,7 @@ chellow/templates/e/supply_hh_data.html,sha256=d9ho4Tq3ZkR5GmxSZr_zHGwCU68PH3aSc
315
315
  chellow/templates/e/supply_months.html,sha256=2EUF_SWCcjG9GiAw86gco8xR6LXaqCPXfQE5A33TqqI,1927
316
316
  chellow/templates/e/supply_note_add.html,sha256=wsrG7P38h8fj63zVAZXfLogdYxIKnn8qxEJFr3Fna4k,553
317
317
  chellow/templates/e/supply_note_edit.html,sha256=FmM1JdjPbB9EI2LEfKE_zNtA0b3UgufEd9fhrDe63Jc,954
318
- chellow/templates/e/supply_notes.html,sha256=_ThBlIv_eCwNnGdQWVhtYeRUM-X8lDexyn8OUsj5GAg,863
318
+ chellow/templates/e/supply_notes.html,sha256=ifkYwh4A98FSJ8iWBXA-fbBht_BKRUiDNG_dzXkWdss,838
319
319
  chellow/templates/e/supply_post.html,sha256=o4BBLCtazj-AMCieclBDHNk2jN1G1N9MABXL7aZCgPI,180
320
320
  chellow/templates/e/supply_virtual_bill.html,sha256=fAexhs9brfZ_hMb52uMqSQRe8lHMde7qi0GGKav0Tq0,1239
321
321
  chellow/templates/e/tpr.html,sha256=cdUan1kf9dc3Gg0SrvarMrEj986_D3XnKtXNVQeG1TQ,1452
@@ -357,13 +357,13 @@ chellow/templates/g/supplier_rate_script.html,sha256=e4dwskWTQcLv6qyX150VUeuaUvE
357
357
  chellow/templates/g/supplier_rate_script_add.html,sha256=zMjTkjupOsHFu-peUXL4IKjjc2OaSL-2ah4T9OdKp_o,620
358
358
  chellow/templates/g/supplier_rate_script_edit.html,sha256=GoUqXf52gWEH1iApmNdxOcKLItzpA-o7iQPQ1_in9BA,1950
359
359
  chellow/templates/g/supplies.html,sha256=oEAEfZaAuKv7EA6fd3blWjPwv_XKoNHLPlkRJ_afZHs,1267
360
- chellow/templates/g/supply.html,sha256=Jeqm7AhZQd4uzu-ncRIIeh6DK9NYSvYrLrxmBE4ERIM,10975
360
+ chellow/templates/g/supply.html,sha256=gr4Ivz5JkwmP09GPuWgwl6hhie1dJcAyyaAU0TKo5JE,10713
361
361
  chellow/templates/g/supply_edit.html,sha256=F2Ip4xCXLl4eFiRjMLZyUMIiznWw97GF7mN_50QAEWA,1653
362
- chellow/templates/g/supply_note_add.html,sha256=npmobg9u1xKcgJKSRCwLY_tH5WJ0bAx3i2XZWqfFeHs,744
363
- chellow/templates/g/supply_note_edit.html,sha256=6UQf_qbhFDys3cVsTp-c7ABWZpggW9R1rhxRKK3h_p8,1043
364
- chellow/templates/g/supply_notes.html,sha256=WR3YwGh_qqTklSJ7JqWX6BKBc9rk_jMff4RiWZiF2CM,936
362
+ chellow/templates/g/supply_note_add.html,sha256=zWwppQTxBfN7Dw6Cgr330mw7SgDRoTcaIdAucNisZRE,658
363
+ chellow/templates/g/supply_note_edit.html,sha256=b8mB6_ucBwoljp03iy6AgVaZUhGw3-1nAPevz-AgkhQ,1036
364
+ chellow/templates/g/supply_notes.html,sha256=6epNmZ3NKdXZz27fvmRUGeffg_oc1kmwuBeyRzQe3Rg,854
365
365
  chellow/templates/g/unit.html,sha256=KouNVU0-i84afANkLQ_heJ0uDfJ9H5A05PuLqb8iCN8,438
366
366
  chellow/templates/g/units.html,sha256=p5Nd-lAIboKPEOO6N451hx1bcKxMg4BDODnZ-43MmJc,441
367
- chellow-1717768383.0.0.dist-info/METADATA,sha256=FSbmmHYytVZN9CdVIekLk3eUbkbT4a-3mLVR3ow7PFM,12205
368
- chellow-1717768383.0.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
369
- chellow-1717768383.0.0.dist-info/RECORD,,
367
+ chellow-1718704260.0.0.dist-info/METADATA,sha256=x7O0IguijEUTz7OSVR7s3clEig-oNl7IOxsCZn0gFBM,12205
368
+ chellow-1718704260.0.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
369
+ chellow-1718704260.0.0.dist-info/RECORD,,