chellow 1740066311.0.0__py3-none-any.whl → 1740736363.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.

@@ -6,6 +6,7 @@ from collections import OrderedDict, defaultdict
6
6
  from datetime import datetime as Datetime
7
7
  from decimal import Decimal
8
8
  from itertools import combinations
9
+ from numbers import Number
9
10
 
10
11
  from flask import g, redirect, request
11
12
 
@@ -364,22 +365,61 @@ def _process_g_bill_ids(
364
365
  vals["g_supply_id"] = g_supply.id
365
366
  vals["site_id"] = site_id
366
367
  for element in sorted(elements):
367
- rate_name = f"difference_{element}_rate"
368
- covered_rates = vals.get(f"covered_{element}_rate", [0])
369
- virtual_rates = vals.get(f"virtual_{element}_rate", [0])
370
- if len(covered_rates) == 1 and len(virtual_rates) == 1:
371
- vals[rate_name] = (
372
- float(covered_rates.pop()) * 100 - float(virtual_rates.pop()) * 100
373
- )
368
+ for key in tuple(vals.keys()):
369
+ if not key.endswith("_gbp"):
370
+ covered_prefix = f"covered_{element}_"
371
+ virtual_prefix = f"virtual_{element}_"
372
+ if key.startswith(covered_prefix):
373
+ part_name = key[len(covered_prefix) :]
374
+ elif key.startswith(virtual_prefix):
375
+ part_name = key[len(virtual_prefix) :]
376
+ else:
377
+ continue
378
+ virtual_part = vals.get(f"virtual_{element}_{part_name}", {0})
379
+ covered_part = vals.get(f"covered_{element}_{part_name}", {0})
380
+ if isinstance(virtual_part, set) and len(virtual_part) == 1:
381
+ virtual_part = float(next(iter(virtual_part)))
382
+ if isinstance(covered_part, set) and len(covered_part) == 1:
383
+ covered_part = float(next(iter(covered_part)))
384
+
385
+ if isinstance(virtual_part, Number) and isinstance(
386
+ covered_part, Number
387
+ ):
388
+ diff = float(covered_part) - float(virtual_part)
389
+ else:
390
+ diff = 0
391
+
392
+ vals[f"difference_{element}_{part_name}"] = diff
393
+
394
+ for suffix in (
395
+ "kwh",
396
+ "units_consumed",
397
+ ):
398
+ try:
399
+ covered = float(vals[f"covered_{suffix}"])
400
+ virtual = float(vals[f"virtual_{suffix}"])
401
+ vals[f"difference_{suffix}"] = covered - virtual
402
+ except KeyError:
403
+ vals[f"difference_{suffix}"] = 0
404
+
405
+ for prefix in (
406
+ "correction_factor",
407
+ "unit_code",
408
+ "calorific_value",
409
+ ):
410
+ covered = vals.get(f"covered_{prefix}", [0])
411
+ virtual = vals.get(f"virtual_{prefix}", [0])
412
+ if len(covered) == 1 and len(virtual) == 1:
413
+ if covered == virtual:
414
+ diff = 0
415
+ else:
416
+ try:
417
+ diff = float(next(iter(covered))) - float(next(iter(virtual)))
418
+ except ValueError:
419
+ diff = False
374
420
  else:
375
- vals[rate_name] = 0
376
-
377
- try:
378
- covered_kwh = float(vals["covered_kwh"])
379
- virtual_kwh = float(vals["virtual_kwh"])
380
- vals["difference_kwh"] = covered_kwh - virtual_kwh
381
- except KeyError:
382
- vals["difference_kwh"] = None
421
+ diff = False
422
+ vals[f"difference_{prefix}"] = diff
383
423
 
384
424
  ReportRun.w_insert_row(report_run_id, "", titles, vals, {"is_checked": False})
385
425
 
@@ -1,5 +1,16 @@
1
1
  {% extends "base.html" %}
2
2
 
3
+ {% block inside_head %}
4
+ <style>
5
+ section.elements {
6
+ display: flex;
7
+ flex-wrap: wrap;
8
+ gap: 4em;
9
+ align-items: flex-start;
10
+ }
11
+ </style>
12
+ {% endblock %}
13
+
3
14
  {% block title %}
4
15
  &raquo; Report Runs &raquo; {{row.report_run.id}} &raquo; Row {{row.id}}
5
16
  {% endblock %}
@@ -10,146 +21,173 @@
10
21
  &raquo; Row {{row.id}}
11
22
  {% endblock %}
12
23
 
24
+
13
25
  {% block content %}
14
26
  {% set values = row.data['values'] %}
15
27
  {% set properties = row.data.get('properties', {}) %}
16
- {% if row.report_run.name == 'bill_check' %}
28
+ <table>
29
+ <caption>Bill Check</caption>
30
+ <thead>
31
+ <tr>
32
+ <th>Batch</th>
33
+ <th>Site</th>
34
+ <th>MPRN</th>
35
+ <th>Covered Bills</th>
36
+ <th>Covered Start</th>
37
+ <th>Covered Finish</th>
38
+ <th>Problem</th>
39
+ </tr>
40
+ </thead>
41
+ <tbody>
42
+ <tr>
43
+ <td><a href="/g/batches/{{values.g_batch_id}}">{{values.batch}}</a></td>
44
+ <td>
45
+ <a href="/sites/{{values.site_id}}">{{values.site_code}} {{values.site_name}}</a>
46
+ </td>
47
+ <td>
48
+ <a href="/g/supplies/{{values.g_supply_id}}">{{values.mprn}}</a>
49
+ </td>
50
+ <td>
51
+ {% if values['covered_bill_ids'] is not none %}
52
+ {% for bill_id in values['covered_bill_ids'] %}
53
+ <a href="/g/bills/{{bill_id}}">{{bill_id}}</a>
54
+ {% if bill_id == values.g_bill_id %}
55
+ {% endif %}
56
+ {% endfor %}
57
+ {% endif %}
58
+ </td>
59
+ <td><span title="{{values.covered_start}}">{{values.covered_start[:10]}}</span></td>
60
+ <td><span title="{{values.covered_finish}}">{{values.covered_finish[:10]}}</span></td>
61
+ {% for title in columns %}
62
+ <td>
63
+ {% if title in values and values[title] is not none %}
64
+ {{"%.2f"|format(values[title])}}
65
+ {% endif %}
66
+ </td>
67
+ {% endfor %}
68
+ <td>
69
+ {{ values.covered_problem }} {{ values.virtual_problem }}
70
+ </td>
71
+ </tr>
72
+ </tbody>
73
+ </table>
74
+
75
+ <section class="elements">
17
76
  <table>
18
- <caption>Bill Check</caption>
77
+ <caption>GBP</caption>
19
78
  <thead>
20
79
  <tr>
21
- <th rowspan="2">Batch</th>
22
- <th colspan="8">Bill</th>
23
- <th colspan="2">MPAN Core</th>
24
- <th colspan="2">Site</th>
25
- <th rowspan="2">Checking</th>
26
- </tr>
27
- <tr>
28
- <th>Reference</th>
29
- <th>Type</th>
30
- <th>kWh</th>
31
- <th>Net GBP</th>
32
- <th>VAT GBP</th>
33
- <th>Gross GBP</th>
34
- <th>Start</th>
35
- <th>Finish</th>
36
- <th>Import</th>
37
- <th>Export</th>
38
- <th>Code</th>
39
- <th>Name</th>
80
+ <th>Part</th>
81
+ <th>Covered</th>
82
+ <th>Virtual</th>
83
+ <th>Difference</th>
40
84
  </tr>
41
85
  </thead>
42
86
  <tbody>
43
- <tr>
44
- <td>
45
- {% if values.batch_id != None %}
46
- <a href="/e/supplier_batches/{{values.batch_id}}">{{values['batch']}}</a>
47
- {% endif %}
48
- </td>
49
- <td>
50
- {% if values.bill_id != None %}
51
- <a href="/e/supplier_bills/{{values.bill_id}}">{{
52
- values['bill-reference']}}</a>
53
- {% endif %}
54
- </td>
55
- <td>{{values['bill-type']}}</td>
56
- <td>{{values['bill-kwh']}}</td>
57
- <td>{{values['bill-net-gbp']}}</td>
58
- <td>{{values['bill-vat-gbp']}}</td>
59
- <td>{{values['bill-gross-gbp']}}</td>
60
- <td>{{values['bill-start-date']}}</td>
61
- <td>{{values['bill-finish-date']}}</td>
62
- <td>
63
- {% if values['imp-mpan-core'] != None %}
64
- <a href="/e/supplies/{{values.supply_id}}">{{
65
- values['imp-mpan-core']}}</a>
66
- {% endif %}
67
- </td>
68
- <td>
69
- {% if values['exp-mpan-core'] != None %}
70
- <a href="/e/supplies/{{values.supply_id}}">{{
71
- values['exp-mpan-core']}}</a>
72
- {% endif %}
73
- </td>
74
- <td>
75
- {% if values.site_id != None %}
76
- <a href="/sites/{{values.site_id}}">{{
77
- values['site-code']}}</a>
78
- {% endif %}
79
- </td>
80
- <td>{{values['site-name']}}</td>
81
- <td>
82
- <form action="/report_run_rows/{{row.id}}" method="post">
83
- <fieldset>
84
- {{input_textarea(
85
- 'note', properties.note, 5, 40,
86
- placeholder='Notes on checking go here...')}}
87
- <br>
88
- <br>
89
- <label>Checked?
90
- {{input_checkbox('is_checked', properties.is_checked)}}
91
- </label>
92
- <input type="submit" name="update" value="Update">
93
- </fieldset>
94
- </form>
95
- </td>
96
- </tr>
97
- </tbody>
87
+ {% if 'difference_gross_gbp' in values %}
88
+ <tr>
89
+ <td>gross</td>
90
+ <td>{{"{:0,.2f}".format(values.covered_gross_gbp)}}</td>
91
+ <td>{{"{:0,.2f}".format(values.virtual_gross_gbp)}}</td>
92
+ <td>{{"{:0,.2f}".format(values.difference_gross_gbp)}}</td>
93
+ </tr>
94
+ {% endif %}
95
+ <tr>
96
+ <td>net</td>
97
+ <td>{{"{:0,.2f}".format(values.covered_net_gbp)}}</td>
98
+ <td>{{"{:0,.2f}".format(values.virtual_net_gbp)}}</td>
99
+ <td>{{"{:0,.2f}".format(values.difference_net_gbp)}}</td>
100
+ </tr>
101
+ {% if 'difference_vat_gbp' in values %}
102
+ <tr>
103
+ <td>vat</td>
104
+ <td>{{"{:0,.2f}".format(values.covered_vat_gbp)}}</td>
105
+ <td>{{"{:0,.2f}".format(values.virtual_vat_gbp)}}</td>
106
+ <td>{{"{:0,.2f}".format(values.difference_vat_gbp)}}</td>
107
+ </tr>
108
+ {% endif %}
109
+ {% if 'difference_vat_rate' in values and values.difference_vat_rate != 0 %}
110
+ <tr>
111
+ <td>vat_rate</td>
112
+ <td>{{values.covered_vat_rate}}</td>
113
+ <td>{{values.virtual_vat_rate}}</td>
114
+ <td>{{"{:0,.2f}".format(values.difference_vat_rate)}}</td>
115
+ </tr>
116
+ {% endif %}
117
+ {% if 'difference_is_commercial' in values %}
118
+ <tr>
119
+ <td>is_commercial</td>
120
+ <td>{{values.covered_is_commercial}}</td>
121
+ <td>{{values.virtual_is_commercial}}</td>
122
+ <td>{{values.difference_is_commercial}}</td>
123
+ </tr>
124
+ {% endif %}
125
+
98
126
  </table>
99
127
 
100
128
  <table>
101
- <caption>Covered</caption>
129
+ <caption>kWh</caption>
102
130
  <thead>
103
131
  <tr>
104
- <th>From</th>
105
- <th>To</th>
106
- <th>Bills</th>
107
- <th>Metered kWh</th>
108
- <th>Net GBP</th>
109
- <th>Virtual Net GBP</th>
110
- <th>Difference GBP</th>
111
- <th>Problem</th>
112
- <th>Virtual Problem</th>
132
+ <th>Part</th>
133
+ <th>Covered</th>
134
+ <th>Virtual</th>
135
+ <th>Difference</th>
113
136
  </tr>
114
137
  </thead>
115
138
  <tbody>
116
139
  <tr>
117
- <td>{{values['covered-from']}}</td>
118
- <td>{{values['covered-to']}}</td>
140
+ <td>kwh</td>
141
+ <td>{{"{:0,.2f}".format(values.covered_kwh)}}</td>
142
+ <td>{{"{:0,.2f}".format(values.virtual_kwh)}}</td>
143
+ <td>{{"{:0,.2f}".format(values.difference_kwh)}}</td>
144
+ </tr>
145
+ <tr>
146
+ <td>units_consumed</td>
119
147
  <td>
120
- {% if values['covered-bills'] != None %}
121
- <ul>
122
- {% for bill_id in values['covered-bills'] %}
123
- <li>
124
- <a href="/e/supplier_bills/{{bill_id}}">{{bill_id}}</a>
125
- {% if bill_id == values.bill_id %}
126
- (This bill)
127
- {% endif %}
128
- </li>
129
- {% endfor %}
130
- </ul>
148
+ {% if 'covered_units_consumed' in values %}
149
+ {{"{:0,.2f}".format(values.covered_units_consumed)}}
131
150
  {% endif %}
132
151
  </td>
152
+ <td>{{"{:0,.2f}".format(values.virtual_units_consumed)}}</td>
153
+ <td>{{"{:0,.2f}".format(values.difference_units_consumed)}}</td>
154
+ </tr>
155
+ <tr>
156
+ <td>correction_factor</td>
133
157
  <td>
134
- {% if values['metered-kwh'] != None %}
135
- {{"%.0f"|format(values['metered-kwh'])}}
158
+ {% if values.covered_correction_factor is number %}
159
+ {{"{:0,.2f}".format(values.covered_correction_factor)}}
160
+ {% else %}
161
+ {{values.covered_correction_factor|join(' | ')}}
136
162
  {% endif %}
137
163
  </td>
138
- <td>{{values['covered-net-gbp']}}</td>
139
164
  <td>
140
- {% if values['virtual-net-gbp'] != None %}
141
- {{"%.2f"|format(values['virtual-net-gbp'])}}
165
+ {% if values.virtual_correction_factor is number %}
166
+ {{"{:0,.2f}".format(values.virtual_correction_factor)}}
167
+ {% else %}
168
+ {{values.virtual_correction_factor|join(' | ')}}
142
169
  {% endif %}
143
170
  </td>
144
171
  <td>
145
- {% if values['difference-net-gbp'] != None %}
146
- {{"%.2f"|format(values['difference-net-gbp'])}}
172
+ {% if values.difference_correction_factor is number %}
173
+ {{"{:0,.2f}".format(values.difference_correction_factor)}}</td>
174
+ {% else %}
175
+ {{values.difference_correction_factor|join(' | ')}}
147
176
  {% endif %}
148
177
  </td>
149
- <td>{{values['covered-problem']}}</td>
150
- <td>{{values['virtual-problem']}}</td>
151
178
  </tr>
152
- </tbody>
179
+ <tr>
180
+ <td>unit_code</td>
181
+ <td>{{values.covered_unit_code|join(' | ')}}</td>
182
+ <td>{{values.virtual_unit_code|join(' | ')}}</td>
183
+ <td>{{values.difference_unit_code}}</td>
184
+ </tr>
185
+ <tr>
186
+ <td>calorific_value</td>
187
+ <td>{{values.covered_calorific_value|join(' | ')}}</td>
188
+ <td>{{values.virtual_calorific_value|join(' | ')}}</td>
189
+ <td>{{values.difference_calorific_value}}</td>
190
+ </tr>
153
191
  </table>
154
192
 
155
193
  {% for table in tables %}
@@ -157,35 +195,67 @@
157
195
  <caption>{{table.name}}</caption>
158
196
  <thead>
159
197
  <tr>
160
- {% for title in table.titles %}
161
- <th>{{title}}</th>
162
- {% endfor %}
198
+ <th>Part</th>
199
+ <th>Covered</th>
200
+ <th>Virtual</th>
201
+ <th>Difference</th>
163
202
  </tr>
164
203
  </thead>
165
204
  <tbody>
166
205
  <tr>
167
- {% for v in table['values'] %}
168
- <td>{{v}}</td>
206
+ <td>gbp</td>
207
+ {% for pref in ('covered_', 'virtual_', 'difference_') %}
208
+ <td>
209
+ {% set k = pref + table.name + "_gbp" %}
210
+ {% if k in values %}
211
+ {% set val = values[k] %}
212
+ {% else %}
213
+ {% set val = '' %}
214
+ {% endif %}
215
+ {% if val is number %}
216
+ {{"{:0,.2f}".format(val)}}
217
+ {% else %}
218
+ {{val}}
219
+ {% endif %}
220
+ </td>
169
221
  {% endfor %}
170
222
  </tr>
223
+ {% for part in table['parts']|sort %}
224
+ <tr>
225
+ <td>{{part}}</td>
226
+ {% for pref in ('covered_', 'virtual_', 'difference_') %}
227
+ <td>
228
+ {% set k = pref + table.name + "_" + part %}
229
+ {% if k in values %}
230
+ {% set val = values[k] %}
231
+ {% else %}
232
+ {% set val = '' %}
233
+ {% endif %}
234
+ {% if val is number %}
235
+ {{"{:0,.2f}".format(val)}}
236
+ {% elif (val is string) or (val is boolean) %}
237
+ {{val}}
238
+ {% else %}
239
+ {% for v in val %}
240
+ {% if v is number %}
241
+ {{"{:0,.2f}".format(v)}}
242
+ {% else %}
243
+ {{v}}
244
+ {% endif %}
245
+ {% if not loop.last %}
246
+ |
247
+ {% endif %}
248
+ {% endfor %}
249
+ {% endif %}
250
+ </td>
251
+ {% endfor %}
252
+ </tr>
253
+ {% endfor %}
171
254
  </tbody>
172
255
  </table>
173
256
  {% endfor %}
257
+ </section>
174
258
 
175
- <h2>Raw</h2>
176
- <pre>{{raw_data}}</pre>
177
-
178
- {% else %}
179
- <table>
180
- <caption>Report Run Row</caption>
181
- <tbody>
182
- {% for title in row.data.titles %}
183
- <tr>
184
- <th>{{title}}</th>
185
- <td>{{row.data['values'][title]}}</td>
186
- </tr>
187
- {% endfor %}
188
- </tbody>
189
- </table>
190
- {% endif %}
259
+ <h2>Raw</h2>
260
+ <pre>{{raw_data}}</pre>
191
261
  {% endblock %}
chellow/views.py CHANGED
@@ -1617,6 +1617,11 @@ def report_run_row_get(row_id):
1617
1617
  "report_run_row_bill_check.html", row=row, raw_data=raw_data, tables=tables
1618
1618
  )
1619
1619
  elif row.report_run.name == "g_bill_check":
1620
+ g_contract = GContract.get_by_id(g.sess, row.report_run.data["g_contract_id"])
1621
+ g_contract_props = g_contract.make_properties()
1622
+ props = g_contract_props.get("report_run", {})
1623
+ table_names_hide = props.get("table_names_hide", [])
1624
+
1620
1625
  values = row.data["values"]
1621
1626
  elements = {}
1622
1627
  for t in row.data["values"].keys():
@@ -1625,34 +1630,31 @@ def report_run_row_get(row_id):
1625
1630
  t.startswith("covered_")
1626
1631
  or t.startswith("virtual_")
1627
1632
  or t.startswith("difference_")
1628
- ) and t not in (
1629
- "covered_from",
1630
- "covered_to",
1631
- "covered_bills",
1632
- "covered_problem",
1633
- "virtual_problem",
1634
- ):
1633
+ ) and t.endswith("_gbp"):
1635
1634
  toks = t.split("_")
1636
1635
  name = "_".join(toks[1:-1])
1636
+ if name in ("vat", "gross", "net") or name in table_names_hide:
1637
+ continue
1637
1638
  try:
1638
1639
  table = elements[name]
1639
1640
  except KeyError:
1640
- table = elements[name] = {"order": 0}
1641
+ table = elements[name] = {"order": 0, "name": name, "parts": set()}
1642
+ tables.append(table)
1641
1643
 
1642
- if "titles" not in table:
1643
- table["titles"] = []
1644
- table["titles"].append(toks[0] + "_" + "_".join(toks[2:]))
1645
- if "values" not in table:
1646
- table["values"] = []
1647
- table["values"].append(values[t])
1648
- if t.startswith("difference_") and t.endswith("-gbp"):
1649
- table["order"] = abs(values[t])
1644
+ for t in row.data["values"].keys():
1650
1645
 
1651
- for k, v in elements.items():
1652
- if k == "net":
1653
- continue
1654
- v["name"] = k
1655
- tables.append(v)
1646
+ toks = t.split("_")
1647
+ if toks[0] in ("covered", "virtual", "difference"):
1648
+ tail = "_".join(toks[1:])
1649
+ for element in elements.keys():
1650
+ table = elements[element]
1651
+ elstr = f"{element}_"
1652
+ if tail.startswith(elstr):
1653
+ part = tail[len(elstr) :]
1654
+ if part != "gbp":
1655
+ table["parts"].add(part)
1656
+ if t.startswith("difference_") and t.endswith("_gbp"):
1657
+ table["order"] = abs(values[t])
1656
1658
 
1657
1659
  tables.sort(key=lambda t: t["order"], reverse=True)
1658
1660
  return render_template(
@@ -1,14 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chellow
3
- Version: 1740066311.0.0
3
+ Version: 1740736363.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)
7
7
  Classifier: Operating System :: OS Independent
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Requires-Python: >=3.9
10
- Requires-Dist: flask-restx==1.2.0
11
- Requires-Dist: flask==2.3.3
10
+ Requires-Dist: flask-restx==1.3.0
11
+ Requires-Dist: flask==3.1.0
12
+ Requires-Dist: jsonschema==4.17.3
12
13
  Requires-Dist: odio==0.0.23
13
14
  Requires-Dist: openpyxl==3.1.2
14
15
  Requires-Dist: paramiko==3.4.1
@@ -12,7 +12,7 @@ chellow/rate_server.py,sha256=fg-Pf_9Hk3bXmC9riPQNGQxBvLvBa_WtNYdwDCjnCSg,5678
12
12
  chellow/rrun.py,sha256=1Kt2q_K9UoDG_nsZz-Q6XJiMNKroWqlqFdxn2M6Q8CA,2088
13
13
  chellow/testing.py,sha256=Od4HHH6pZrhJ_De118_F55RJEKmAvhUH2S24QE9qFQk,3635
14
14
  chellow/utils.py,sha256=Ej7dsbQ6Ee8X2aZ7B2Vs-hUFCsMABioAdOV1DJjwY-0,19293
15
- chellow/views.py,sha256=82V1OtdscrAmbiT3B5MDZoCe50fDSJwfBF-PpbB5tm8,83513
15
+ chellow/views.py,sha256=2WCU-_8lDuSDROvNlCGsAQVLSMh5qrD2wmeSr2G-umA,83872
16
16
  chellow/e/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  chellow/e/aahedc.py,sha256=d2usudp7KYWpU6Pk3fal5EQ47EbvkvKeaFGylnb3NWw,606
18
18
  chellow/e/bill_importer.py,sha256=7UcnqNlKbJc2GhW9gy8sDp9GuqambJVpZLvbafOZztA,7411
@@ -90,7 +90,7 @@ chellow/reports/report_291.py,sha256=BnWtxe0eWN2QKKWpwjs5-RI5LbReBKL119QbkrkNhV8
90
90
  chellow/reports/report_33.py,sha256=lt1EN_LNx6u-AgdaS3YRkPMZA33JgMcELolHF4oJUMw,16689
91
91
  chellow/reports/report_387.py,sha256=bBqtnGGDWIXzXe2zVm9yeDRZKNgkUaOS3XTX6k09f18,5631
92
92
  chellow/reports/report_41.py,sha256=8xUIN9D5dtT0Dn1RmbnWsLRmM-QbGA5xGhWCK3ljAzA,7406
93
- chellow/reports/report_429.py,sha256=SbFlBsHXWMWRlMbY_e0zco2R8tMG9XVulr56E3mRalU,14287
93
+ chellow/reports/report_429.py,sha256=1LzrhfePeLg98eczzxy9HrR0EYcPYINw1LSJKk9kKAM,15812
94
94
  chellow/reports/report_59.py,sha256=PkdRA6ctvDGWTQd5vb9cQH6MG920TxcD6aHh268zrj8,42221
95
95
  chellow/reports/report_81.py,sha256=bBpV6MtvKGtoLiqzZoK2h21KDs4vfDwy-etpfL9oiEI,5570
96
96
  chellow/reports/report_87.py,sha256=udzbCuXcckWD-OHmfJCT6bwg_paYhm4vfDWlL8WM-jA,6933
@@ -146,7 +146,7 @@ chellow/templates/report_run_g_bill_check.html,sha256=tOXl_mjR__foYKiOYflJbK-459
146
146
  chellow/templates/report_run_monthly_duration_org.html,sha256=gGNGJ4Q50q4BtIMi98rhO-7NqRHcsFUmbj2qzeOLejw,1713
147
147
  chellow/templates/report_run_row.html,sha256=bmtcdqJaS1CXpL0i8PuqvmeF98jKNYX5-mnQu-OuDKQ,3791
148
148
  chellow/templates/report_run_row_bill_check.html,sha256=aC2LMu_6NvmTN3ZdxHJPPPczyxPN6hg0F-PPcqIWUws,4683
149
- chellow/templates/report_run_row_g_bill_check.html,sha256=aC2LMu_6NvmTN3ZdxHJPPPczyxPN6hg0F-PPcqIWUws,4683
149
+ chellow/templates/report_run_row_g_bill_check.html,sha256=2Ym9mkwvA_DGDrgktDDwXQXlUK7tR2aR3gp3KUqMLoI,7017
150
150
  chellow/templates/report_run_supply_contacts.html,sha256=JNzwz9M6qbLRDMkCzFCxxANapUer5klxo7t5a48nAzg,2117
151
151
  chellow/templates/report_runs.html,sha256=ecoIkl2WtfYtifiTxnslmpMGYYGVQW-CVSBpqhXyiE4,1131
152
152
  chellow/templates/scenario.html,sha256=tCoq1wBq4l9PRS-zFtPcCWXlxD_SSFvFFkERf4FWVNU,2055
@@ -378,6 +378,6 @@ chellow/templates/g/supply_note_edit.html,sha256=b8mB6_ucBwoljp03iy6AgVaZUhGw3-1
378
378
  chellow/templates/g/supply_notes.html,sha256=6epNmZ3NKdXZz27fvmRUGeffg_oc1kmwuBeyRzQe3Rg,854
379
379
  chellow/templates/g/unit.html,sha256=KouNVU0-i84afANkLQ_heJ0uDfJ9H5A05PuLqb8iCN8,438
380
380
  chellow/templates/g/units.html,sha256=p5Nd-lAIboKPEOO6N451hx1bcKxMg4BDODnZ-43MmJc,441
381
- chellow-1740066311.0.0.dist-info/METADATA,sha256=Ptkn8LQ0lzGXaW-pi11oteZKiDLxBJuK0WvC7HpscYY,12204
382
- chellow-1740066311.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
383
- chellow-1740066311.0.0.dist-info/RECORD,,
381
+ chellow-1740736363.0.0.dist-info/METADATA,sha256=qWpHKbIMKoTX4yjpi3XczaOvWuvWo2PVOHgflg919HY,12238
382
+ chellow-1740736363.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
383
+ chellow-1740736363.0.0.dist-info/RECORD,,