chellow 1757320031.0.0__py3-none-any.whl → 1759411815.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.

Files changed (75) hide show
  1. chellow/e/bill_importer.py +136 -80
  2. chellow/e/bill_parsers/activity_mop_stark_xlsx.py +99 -86
  3. chellow/e/bill_parsers/annual_mop_stark_xlsx.py +78 -61
  4. chellow/e/bill_parsers/csv.py +139 -101
  5. chellow/e/bill_parsers/drax_edi.py +65 -89
  6. chellow/e/bill_parsers/engie_edi.py +187 -255
  7. chellow/e/bill_parsers/engie_xls.py +153 -167
  8. chellow/e/bill_parsers/haven_edi.py +189 -228
  9. chellow/e/bill_parsers/haven_edi_tprs.py +67 -67
  10. chellow/e/bill_parsers/nonsettlement_dc_stark_xlsx.py +75 -66
  11. chellow/e/bill_parsers/settlement_dc_stark_xlsx.py +229 -126
  12. chellow/e/bill_parsers/sse_edi.py +107 -75
  13. chellow/e/bill_parsers/sww_xls.py +78 -91
  14. chellow/e/computer.py +1 -1
  15. chellow/e/views.py +626 -281
  16. chellow/edi_lib.py +4 -27
  17. chellow/models.py +92 -3
  18. chellow/reports/report_111.py +514 -616
  19. chellow/reports/report_247.py +96 -137
  20. chellow/templates/e/dc_batch.html +110 -157
  21. chellow/templates/e/dc_batch_add.html +2 -3
  22. chellow/templates/e/dc_batch_edit.html +42 -46
  23. chellow/templates/e/dc_batch_file.html +2 -3
  24. chellow/templates/e/dc_batch_file_edit.html +28 -40
  25. chellow/templates/e/dc_batch_upload_file.html +68 -0
  26. chellow/templates/e/dc_batches.html +2 -1
  27. chellow/templates/e/dc_batches_edit.html +26 -0
  28. chellow/templates/e/dc_bill.html +27 -5
  29. chellow/templates/e/dc_bill_add.html +4 -4
  30. chellow/templates/e/dc_bill_edit.html +43 -63
  31. chellow/templates/e/dc_bill_import.html +1 -1
  32. chellow/templates/e/dc_bill_import_contract.html +130 -0
  33. chellow/templates/e/dc_contract.html +1 -1
  34. chellow/templates/e/dc_element.html +41 -0
  35. chellow/templates/e/dc_element_add.html +36 -0
  36. chellow/templates/e/dc_element_edit.html +49 -0
  37. chellow/templates/e/dc_rate_script_edit.html +27 -43
  38. chellow/templates/e/mop_batch.html +105 -152
  39. chellow/templates/e/mop_batch_add.html +2 -3
  40. chellow/templates/e/mop_batch_edit.html +43 -51
  41. chellow/templates/e/mop_batch_upload_file.html +71 -5
  42. chellow/templates/e/mop_batches.html +2 -1
  43. chellow/templates/e/mop_batches_edit.html +26 -0
  44. chellow/templates/e/mop_bill.html +31 -8
  45. chellow/templates/e/mop_bill_add.html +7 -27
  46. chellow/templates/e/mop_bill_import.html +1 -1
  47. chellow/templates/e/mop_bill_import_contract.html +130 -0
  48. chellow/templates/e/mop_contract.html +4 -5
  49. chellow/templates/e/mop_element.html +41 -0
  50. chellow/templates/e/mop_element_add.html +36 -0
  51. chellow/templates/e/mop_element_edit.html +49 -0
  52. chellow/templates/e/supplier_batch.html +3 -7
  53. chellow/templates/e/supplier_batch_add.html +2 -2
  54. chellow/templates/e/supplier_batch_edit.html +1 -1
  55. chellow/templates/e/supplier_batch_file.html +3 -5
  56. chellow/templates/e/supplier_batch_file_add.html +18 -11
  57. chellow/templates/e/supplier_batch_upload_file.html +83 -9
  58. chellow/templates/e/supplier_batches.html +4 -4
  59. chellow/templates/e/supplier_batches_edit.html +26 -0
  60. chellow/templates/e/supplier_bill.html +29 -6
  61. chellow/templates/e/supplier_bill_add.html +3 -3
  62. chellow/templates/e/supplier_bill_import.html +1 -1
  63. chellow/templates/e/supplier_bill_import_contract.html +118 -0
  64. chellow/templates/e/supplier_contract.html +1 -1
  65. chellow/templates/e/supplier_element.html +45 -0
  66. chellow/templates/e/supplier_element_add.html +36 -0
  67. chellow/templates/e/supplier_element_edit.html +51 -0
  68. chellow/templates/report_run_bill_check.html +137 -179
  69. chellow/templates/report_run_row_bill_check.html +187 -179
  70. chellow/views.py +57 -64
  71. {chellow-1757320031.0.0.dist-info → chellow-1759411815.0.0.dist-info}/METADATA +2 -2
  72. {chellow-1757320031.0.0.dist-info → chellow-1759411815.0.0.dist-info}/RECORD +73 -60
  73. chellow/e/bill_parsers/drax_element_edi.py +0 -459
  74. chellow/templates/e/supplier_bill_imports.html +0 -421
  75. {chellow-1757320031.0.0.dist-info → chellow-1759411815.0.0.dist-info}/WHEEL +0 -0
@@ -11,147 +11,116 @@
11
11
  {% endblock %}
12
12
 
13
13
  {% block content %}
14
- {% set values = row.data['values'] %}
14
+ {% set data = row.data['data'] %}
15
15
  {% set properties = row.data.get('properties', {}) %}
16
+ {% set market_role_code = data['market_role_code'] %}
17
+ {% if market_role_code == 'X' %}
18
+ {% set contract_type = 'supplier' %}
19
+ {% elif market_role_code == 'C' %}
20
+ {% set contract_type = 'dc' %}
21
+ {% elif market_role_code == 'M' %}
22
+ {% set contract_type = 'mop' %}
23
+ {% endif %}
24
+
16
25
  <table>
17
- <caption>Bill Check</caption>
26
+ <caption>Bill Check</caption>
18
27
  <thead>
19
28
  <tr>
20
- <th rowspan="2">Batch</th>
21
- <th colspan="8">Bill</th>
22
- <th colspan="2">MPAN Core</th>
23
- <th colspan="2">Site</th>
24
- <th rowspan="2">Checking</th>
25
- </tr>
26
- <tr>
27
- <th>Reference</th>
28
- <th>Type</th>
29
- <th>kWh</th>
30
- <th>Net GBP</th>
31
- <th>VAT GBP</th>
32
- <th>Gross GBP</th>
33
- <th>Start</th>
34
- <th>Finish</th>
35
- <th>Import</th>
36
- <th>Export</th>
37
- <th>Code</th>
38
- <th>Name</th>
29
+ <th>Contract</th>
30
+ <th>Supply</th>
31
+ <th>Import MPAN Core</th>
32
+ <th>Export MPAN Core</th>
33
+ <th>Site</th>
34
+ <th>From</th>
35
+ <th>To</th>
36
+ <th>Actual Net GBP</th>
37
+ <th>Virtual Net GBP</th>
38
+ <th>Difference Net GBP</th>
39
+ <th>Problem</th>
39
40
  </tr>
40
41
  </thead>
41
42
  <tbody>
42
43
  <tr>
43
44
  <td>
44
- {% if values.batch_id != None %}
45
- <a href="/e/supplier_batches/{{values.batch_id}}">{{values['batch']}}</a>
45
+ {% if data.contract_id is not none %}
46
+ <a href="/e/{{contract_type}}_contracts/{{data.contract_id}}">{{data['contract_name']}}</a>
46
47
  {% endif %}
47
48
  </td>
48
49
  <td>
49
- {% if values.bill_id != None %}
50
- <a href="/e/supplier_bills/{{values.bill_id}}">{{
51
- values['bill-reference']}}</a>
50
+ {% if data.supply_id != None %}
51
+ <a href="/e/supplies/{{data.supply_id}}">view</a>
52
52
  {% endif %}
53
53
  </td>
54
- <td>{{values['bill-type']}}</td>
55
- <td>{{values['bill-kwh']}}</td>
56
- <td>{{values['bill-net-gbp']}}</td>
57
- <td>{{values['bill-vat-gbp']}}</td>
58
- <td>{{values['bill-gross-gbp']}}</td>
59
- <td>{{values['bill-start-date']}}</td>
60
- <td>{{values['bill-finish-date']}}</td>
54
+ <td>{{data['imp_mpan_core']}}</td>
61
55
  <td>
62
- {% if values['imp-mpan-core'] != None %}
63
- <a href="/e/supplies/{{values.supply_id}}">{{
64
- values['imp-mpan-core']}}</a>
56
+ {% if data['exp_mpan_core'] is not none %}
57
+ {{data['exp_mpan_core']}}
65
58
  {% endif %}
66
59
  </td>
67
60
  <td>
68
- {% if values['exp-mpan-core'] != None %}
69
- <a href="/e/supplies/{{values.supply_id}}">{{
70
- values['exp-mpan-core']}}</a>
61
+ {% if data.site_id is not none %}
62
+ <a href="/sites/{{data['site_id']}}">{{data['site_code']}} {{data['site_name']}}</a>
71
63
  {% endif %}
72
64
  </td>
73
- <td>
74
- {% if values.site_id != None %}
75
- <a href="/sites/{{values.site_id}}">{{
76
- values['site-code']}}</a>
77
- {% endif %}
78
- </td>
79
- <td>{{values['site-name']}}</td>
80
- <td>
81
- <form action="/report_run_rows/{{row.id}}" method="post">
82
- <fieldset>
83
- {{input_textarea(
84
- 'note', properties.note, 5, 40,
85
- placeholder='Notes on checking go here...')}}
86
- <br>
87
- <br>
88
- <label>Checked?
89
- {{input_checkbox('is_checked', properties.is_checked)}}
90
- </label>
91
- <input type="submit" name="update" value="Update">
92
- </fieldset>
93
- </form>
94
- </td>
65
+ <td>{{data['period_start']}}</td>
66
+ <td>{{data['period_finish']}}</td>
67
+ <td>{{"{:0,.2f}".format(data['actual_net_gbp'])}}</td>
68
+ <td>{{"{:0,.2f}".format(data['virtual_net_gbp'])}}</td>
69
+ <td>{{"{:0,.2f}".format(data['difference_net_gbp'])}}</td>
70
+ <td>{{data['problem']}}</td>
95
71
  </tr>
96
72
  </tbody>
97
73
  </table>
98
74
 
99
75
  <table>
100
- <caption>Covered</caption>
76
+ <caption>Actual Bills</caption>
101
77
  <thead>
102
78
  <tr>
103
- <th>From</th>
104
- <th>To</th>
105
- <th>Bills</th>
106
- <th>Metered kWh</th>
79
+ <th>Batch</th>
80
+ <th>View</th>
81
+ <th>Start Date</th>
82
+ <th>Finish Date</th>
107
83
  <th>Net GBP</th>
108
- <th>Virtual Net GBP</th>
109
- <th>Difference GBP</th>
84
+ <th>Vat GBP</th>
85
+ <th>Gross GBP</th>
110
86
  <th>Problem</th>
111
- <th>Virtual Problem</th>
87
+ <th>Breakdown</th>
112
88
  </tr>
113
89
  </thead>
114
90
  <tbody>
115
- <tr>
116
- <td>{{values['covered-from']}}</td>
117
- <td>{{values['covered-to']}}</td>
118
- <td>
119
- {% if values['covered-bills'] != None %}
120
- <ul>
121
- {% for bill_id in values['covered-bills'] %}
122
- <li>
123
- <a href="/e/supplier_bills/{{bill_id}}">{{bill_id}}</a>
124
- {% if bill_id == values.bill_id %}
125
- (This bill)
126
- {% endif %}
127
- </li>
128
- {% endfor %}
129
- </ul>
130
- {% endif %}
131
- </td>
132
- <td>
133
- {% if values['metered-kwh'] != None %}
134
- {{"%.0f"|format(values['metered-kwh'])}}
135
- {% endif %}
136
- </td>
137
- <td>{{values['covered-net-gbp']}}</td>
138
- <td>
139
- {% if values['virtual-net-gbp'] != None %}
140
- {{"%.2f"|format(values['virtual-net-gbp'])}}
141
- {% endif %}
142
- </td>
143
- <td>
144
- {% if values['difference-net-gbp'] != None %}
145
- {{"%.2f"|format(values['difference-net-gbp'])}}
146
- {% endif %}
147
- </td>
148
- <td>{{values['covered-problem']}}</td>
149
- <td>{{values['virtual-problem']}}</td>
150
- </tr>
91
+ {% for bill in data.actual_bills %}
92
+ <tr>
93
+ <td>
94
+ {% if data.contract_id is not none %}
95
+ <a href="/e/{{contract_type}}_batches/{{bill.batch_id}}">{{bill.batch_reference}}</a>
96
+ {% endif %}
97
+ </td>
98
+ <td>
99
+ {% if data.contract_id is not none %}
100
+ <a href="/e/{{contract_type}}_bills/{{bill.id}}">view</a>
101
+ {% endif %}
102
+ </td>
103
+ <td>{{bill.start_date}}</td>
104
+ <td>{{bill.finish_date}}</td>
105
+ <td>{{bill.net}}</td>
106
+ <td>{{bill.vat}}</td>
107
+ <td>{{bill.gross}}</td>
108
+ <td>
109
+ <strong style="color: red">{{bill.problem}}</strong>
110
+ </td>
111
+ <td>
112
+ <details>
113
+ <summary>Breakdown</summary>
114
+ <pre>{{bill.breakdown}}</pre>
115
+ </details>
116
+ </td>
117
+ </tr>
118
+ {% endfor %}
151
119
  </tbody>
152
120
  </table>
153
121
 
154
122
  <section class="elements">
123
+ <!--
155
124
  <table>
156
125
  <caption>GBP</caption>
157
126
  <thead>
@@ -166,130 +135,169 @@
166
135
  <tr>
167
136
  <td>gross</td>
168
137
  <td>
169
- {% if 'covered-gross-gbp' in values and values['covered-gross-gbp'] is number %}
170
- {{"{:0,.2f}".format(values['covered-gross-gbp'])}}
138
+ {% if 'covered-gross-gbp' in data and data['covered-gross-gbp'] is number %}
139
+ {{"{:0,.2f}".format(data['covered-gross-gbp'])}}
171
140
  {% endif %}
172
141
  </td>
173
142
  <td>
174
- {% if 'virtual-gross-gbp' in values and values['virtual-gross-gbp'] is number %}
175
- {{"{:0,.2f}".format(values['virtual-gross-gbp'])}}
143
+ {% if 'virtual-gross-gbp' in data and data['virtual-gross-gbp'] is number %}
144
+ {{"{:0,.2f}".format(data['virtual-gross-gbp'])}}
176
145
  {% endif %}
177
146
  </td>
178
147
  <td>
179
- {% if 'difference-gross-gbp' in values and values['difference-gross-gbp'] is number %}
180
- {{"{:0,.2f}".format(values['difference-gross-gbp'])}}
148
+ {% if 'difference-gross-gbp' in data and data['difference-gross-gbp'] is number %}
149
+ {{"{:0,.2f}".format(data['difference-gross-gbp'])}}
181
150
  {% endif %}
182
151
  </td>
183
152
  </tr>
184
153
  <tr>
185
154
  <td>net</td>
186
155
  <td>
187
- {% if 'covered-net-gbp' in values and values['covered-net-gbp'] is number %}
188
- {{"{:0,.2f}".format(values['covered-net-gbp'])}}</td>
156
+ {% if 'covered-net-gbp' in data and data['covered-net-gbp'] is number %}
157
+ {{"{:0,.2f}".format(data['covered-net-gbp'])}}</td>
189
158
  {% endif %}
190
159
  <td>
191
- {% if 'virtual-net-gbp' in values and values['virtual-net-gbp'] is number %}
192
- {{"{:0,.2f}".format(values['virtual-net-gbp'])}}</td>
160
+ {% if 'virtual-net-gbp' in data and data['virtual-net-gbp'] is number %}
161
+ {{"{:0,.2f}".format(data['virtual-net-gbp'])}}</td>
193
162
  {% endif %}
194
163
  <td>
195
- {% if 'difference-net-gbp' in values and values['difference-net-gbp'] is number %}
196
- {{"{:0,.2f}".format(values['difference-net-gbp'])}}</td>
164
+ {% if 'difference-net-gbp' in data and data['difference-net-gbp'] is number %}
165
+ {{"{:0,.2f}".format(data['difference-net-gbp'])}}</td>
197
166
  {% endif %}
198
167
  </tr>
199
168
  <tr>
200
169
  <td>vat</td>
201
170
  <td>
202
- {% if 'covered-vat-gbp' in values and values['covered-vat-gbp'] is number %}
203
- {{"{:0,.2f}".format(values['covered-vat-gbp'])}}</td>
171
+ {% if 'covered-vat-gbp' in data and data['covered-vat-gbp'] is number %}
172
+ {{"{:0,.2f}".format(data['covered-vat-gbp'])}}</td>
204
173
  {% endif %}
205
174
  <td>
206
- {% if 'virtual-vat-gbp' in values and values['virtual-vat-gbp'] is number %}
207
- {{"{:0,.2f}".format(values['virtual-vat-gbp'])}}</td>
175
+ {% if 'virtual-vat-gbp' in data and data['virtual-vat-gbp'] is number %}
176
+ {{"{:0,.2f}".format(data['virtual-vat-gbp'])}}</td>
208
177
  {% endif %}
209
178
  <td>
210
- {% if 'difference-vat-gbp' in values and values['difference-vat-gbp'] is number %}
211
- {{"{:0,.2f}".format(values['difference-vat-gbp'])}}</td>
179
+ {% if 'difference-vat-gbp' in data and data['difference-vat-gbp'] is number %}
180
+ {{"{:0,.2f}".format(data['difference-vat-gbp'])}}</td>
212
181
  {% endif %}
213
182
  </tr>
214
183
  <tr>
215
184
  <td>vat-rate</td>
216
185
  <td>
217
- {{values['covered-vat-rate']}}</td>
218
- <td>{{values['virtual-vat-rate']}}</td>
186
+ {{data['covered-vat-rate']}}</td>
187
+ <td>{{data['virtual-vat-rate']}}</td>
219
188
  <td>
220
- {% if values['difference-vat-rate'] is number %}
221
- {{"{:0,.2f}".format(values['difference-vat-rate'])}}
189
+ {% if data['difference-vat-rate'] is number %}
190
+ {{"{:0,.2f}".format(data['difference-vat-rate'])}}
222
191
  {% endif %}
223
192
  </td>
224
193
  </tr>
225
194
  </tbody>
226
195
  </table>
196
+ -->
227
197
 
228
198
  {% for table in tables %}
229
- <table>
230
- <caption>{{table.name}}</caption>
231
- <thead>
232
- <tr>
233
- <th>Part</th>
234
- <th>Covered</th>
235
- <th>Virtual</th>
236
- <th>Difference</th>
237
- </tr>
238
- </thead>
239
- <tbody>
240
- <tr>
241
- <td>gbp</td>
242
- {% for pref in ('covered-', 'virtual-', 'difference-') %}
243
- <td>
244
- {% set k = pref + table.name + "-gbp" %}
245
- {% if k in values %}
246
- {% set val = values[k] %}
247
- {% else %}
248
- {% set val = '' %}
249
- {% endif %}
250
- {% if val is none %}
251
- {% elif val is number %}
252
- {{"{:0,.2f}".format(val)}}
253
- {% else %}
254
- {{val}}
255
- {% endif %}
256
- </td>
257
- {% endfor %}
258
- </tr>
259
- {% for part in table['parts']|sort %}
199
+ {% set element = data['elements'][table] %}
200
+ {% set parts = element['parts'] %}
201
+
202
+ <div style="display: flex; gap: 4rem;">
203
+ <table>
204
+ <caption>{{table}}</caption>
205
+ <thead>
260
206
  <tr>
261
- <td>{{part}}</td>
262
- {% for pref in ('covered-', 'virtual-', 'difference-') %}
263
- <td>
264
- {% set k = pref + table.name + "-" + part %}
265
- {% if k in values %}
266
- {% set val = values[k] %}
207
+ <th>Part</th>
208
+ <th>Actual</th>
209
+ <th>Virtual</th>
210
+ <th>Difference</th>
211
+ </tr>
212
+ </thead>
213
+ <tbody>
214
+ <tr>
215
+ <td>gbp</td>
216
+ {% for k in ('actual', 'virtual', 'difference') %}
217
+ <td style="text-align: right;">
218
+ {% set part = parts['gbp'] %}
219
+ {% if k in part %}
220
+ {% set val = part[k] %}
267
221
  {% else %}
268
222
  {% set val = '' %}
269
223
  {% endif %}
270
224
  {% if val is none %}
271
225
  {% elif val is number %}
272
226
  {{"{:0,.2f}".format(val)}}
273
- {% elif (val is string) or (val is boolean) %}
274
- {{val}}
275
227
  {% else %}
276
- {% for v in val %}
277
- {% if v is number %}
278
- {{"{:0,.2f}".format(v)}}
279
- {% else %}
280
- {{v}}
281
- {% endif %}
282
- {% if not loop.last %}
283
- |
284
- {% endif %}
285
- {% endfor %}
228
+ {{val}}
286
229
  {% endif %}
287
230
  </td>
288
231
  {% endfor %}
289
232
  </tr>
290
- {% endfor %}
291
- </tbody>
292
- </table>
233
+ {% for part_name, part in parts.items()|sort %}
234
+ {% if part_name != 'gbp' %}
235
+ <tr>
236
+ <td>{{part_name}}</td>
237
+ {% for k in ('actual', 'virtual', 'difference') %}
238
+ <td style="text-align: right;">
239
+ {% if k in part %}
240
+ {% set val = part[k] %}
241
+ {% else %}
242
+ {% set val = '' %}
243
+ {% endif %}
244
+ {% if val is none %}
245
+ {% elif val is number %}
246
+ {{"{:0,.2f}".format(val)}}
247
+ {% elif (val is string) or (val is boolean) %}
248
+ {{val}}
249
+ {% else %}
250
+ {% for v in val %}
251
+ {% if v is number %}
252
+ {{"{:0,.2f}".format(v)}}
253
+ {% else %}
254
+ {{v}}
255
+ {% endif %}
256
+ {% if not loop.last %}
257
+ |
258
+ {% endif %}
259
+ {% endfor %}
260
+ {% endif %}
261
+ </td>
262
+ {% endfor %}
263
+ </tr>
264
+ {% endif %}
265
+ {% endfor %}
266
+ </tbody>
267
+ </table>
268
+
269
+ <table>
270
+ <caption>Actual {{table}} Elements</caption>
271
+ <thead>
272
+ <tr>
273
+ <th>View</th>
274
+ <th>Batch</th>
275
+ <th>Bill</th>
276
+ <th>Start Date</th>
277
+ <th>Finish Date</th>
278
+ <th>Net GBP</th>
279
+ <th>Breakdown</th>
280
+ </tr>
281
+ </thead>
282
+ <tbody>
283
+ {% for el in element['actual_elements'] %}
284
+ <tr>
285
+ <td><a href="/e/{{contract_type}}_elements/{{el.id}}">View</a></td>
286
+ <td>
287
+ <a href="/e/{{contract_type}}_batches/{{el.bill.batch.id}}"
288
+ >{{el.bill.batch.reference}}</a>
289
+ </td>
290
+ <td><a href="/e/{{contract_type}}_bills/{{el.bill.id}}">View</a></td>
291
+ <td>{{el.start_date}}</td>
292
+ <td>{{el.finish_date}}</td>
293
+ <td>{{"{:0,.2f}".format(el.net)}}</td>
294
+ <td>{{el.breakdown}}</td>
295
+ </tr>
296
+ {% endfor %}
297
+ </tbody>
298
+ </table>
299
+
300
+ </div>
293
301
  {% endfor %}
294
302
 
295
303
  </section>
chellow/views.py CHANGED
@@ -1368,48 +1368,72 @@ def report_run_get(run_id):
1368
1368
  pass
1369
1369
 
1370
1370
  else:
1371
- titles = row.data["titles"]
1372
- diff_titles = [
1373
- t for t in titles if t.startswith("difference-") and t.endswith("-gbp")
1374
- ]
1371
+ summary["sum_difference"] = g.sess.scalar(
1372
+ select(
1373
+ func.sum(ReportRunRow.data["data"]["difference_net_gbp"].as_float())
1374
+ ).where(ReportRunRow.report_run == run)
1375
+ )
1376
+ element_names = g.sess.scalars(
1377
+ select(func.jsonb_object_keys(ReportRunRow.data["data"]["elements"]))
1378
+ .where(ReportRunRow.report_run == run)
1379
+ .distinct()
1380
+ ).all()
1375
1381
  diff_selects = [
1376
- func.sum(ReportRunRow.data["values"][t].as_float()) for t in diff_titles
1382
+ func.sum(
1383
+ func.coalesce(
1384
+ ReportRunRow.data["data"]["elements"][n]["parts"]["gbp"][
1385
+ "difference"
1386
+ ].as_float(),
1387
+ 0,
1388
+ )
1389
+ )
1390
+ for n in element_names
1377
1391
  ]
1378
- sum_diffs = (
1379
- g.sess.query(*diff_selects).filter(ReportRunRow.report_run == run).one()
1380
- )
1392
+ if len(diff_selects) > 0:
1393
+ sum_diffs = g.sess.execute(
1394
+ select(*diff_selects).where(ReportRunRow.report_run == run)
1395
+ ).one()
1381
1396
 
1382
- for t, sum_diff in zip(diff_titles, sum_diffs):
1383
- elem = t[11:-4]
1384
- if elem == "net":
1385
- summary["sum_difference"] = sum_diff
1386
- else:
1397
+ for elem, sum_diff in zip(element_names, sum_diffs):
1387
1398
  elements.append((elem, sum_diff))
1388
1399
 
1389
- elements.sort(key=lambda x: abs(x[1]), reverse=True)
1390
- elements.insert(0, ("net", summary["sum_difference"]))
1400
+ elements.sort(
1401
+ key=lambda x: 0 if x[1] is None else abs(x[1]), reverse=True
1402
+ )
1391
1403
 
1392
1404
  if "element" in request.values:
1393
1405
  element = req_str("element")
1394
1406
  else:
1395
- element = "net"
1407
+ element = "problem"
1396
1408
 
1397
1409
  hide_checked = req_bool("hide_checked")
1398
1410
 
1399
- order_by = f"difference-{element}-gbp"
1400
- q = g.sess.query(ReportRunRow).filter(ReportRunRow.report_run == run)
1411
+ ROW_LIMIT = 200
1412
+ q = select(ReportRunRow).where(ReportRunRow.report_run == run).limit(ROW_LIMIT)
1401
1413
  if hide_checked:
1402
- q = q.filter(
1414
+ q = q.where(
1403
1415
  ReportRunRow.data["properties"]["is_checked"].as_boolean() == false()
1404
1416
  )
1405
- ROW_LIMIT = 200
1406
- rows = (
1407
- q.order_by(
1408
- func.abs(ReportRunRow.data["values"][order_by].as_float()).desc()
1417
+ if element == "problem":
1418
+ order_by = (
1419
+ ReportRunRow.data["data"]["problem"].as_string(),
1420
+ func.abs(
1421
+ func.coalesce(
1422
+ ReportRunRow.data["data"]["difference_net_gbp"].as_float(), 0
1423
+ )
1424
+ ).desc(),
1409
1425
  )
1410
- .limit(ROW_LIMIT)
1411
- .all()
1412
- )
1426
+ else:
1427
+ if element == "net":
1428
+ ob = ReportRunRow.data["data"]["difference_net_gbp"]
1429
+ else:
1430
+ ob = ReportRunRow.data["data"]["elements"][element]["parts"]["gbp"][
1431
+ "difference"
1432
+ ]
1433
+ order_by = (func.abs(func.coalesce(ob.as_float(), 0)).desc(),)
1434
+ q = q.order_by(*order_by)
1435
+
1436
+ rows = g.sess.scalars(q).all()
1413
1437
  return render_template(
1414
1438
  "report_run_bill_check.html",
1415
1439
  run=run,
@@ -1654,44 +1678,13 @@ def report_run_row_get(row_id):
1654
1678
  tables = []
1655
1679
 
1656
1680
  if row.report_run.name == "bill_check":
1657
- values = row.data["values"]
1658
- elements = {}
1659
- for t in values.keys():
1660
-
1661
- if (
1662
- t.startswith("covered-")
1663
- or t.startswith("virtual-")
1664
- or t.startswith("difference-")
1665
- ) and t.endswith("-gbp"):
1666
- toks = t.split("-")
1667
- name = "-".join(toks[1:-1])
1668
- if name in ("vat", "gross", "net", "tpr"):
1669
- continue
1670
- try:
1671
- table = elements[name]
1672
- except KeyError:
1673
- table = elements[name] = {"order": 0, "name": name, "parts": set()}
1674
- tables.append(table)
1675
-
1676
- if t.startswith("difference-"):
1677
- table["order"] = abs(values[t])
1678
-
1679
- for t in values.keys():
1680
-
1681
- toks = t.split("-")
1682
- if toks[0] in ("covered", "virtual", "difference"):
1683
- tail = "-".join(toks[1:])
1684
- for element in sorted(elements.keys(), key=len, reverse=True):
1685
-
1686
- table = elements[element]
1687
- elstr = f"{element}-"
1688
- if tail.startswith(elstr):
1689
- part = tail[len(elstr) :]
1690
- if part != "gbp":
1691
- table["parts"].add(part)
1692
- break
1693
-
1694
- tables.sort(key=lambda t: t["order"], reverse=True)
1681
+ elements = row.data["data"]["elements"]
1682
+ for el_name, _ in sorted(
1683
+ list(elements.items()),
1684
+ key=lambda x: abs(x[1]["parts"]["gbp"]["difference"]),
1685
+ reverse=True,
1686
+ ):
1687
+ tables.append(el_name)
1695
1688
  return render_template(
1696
1689
  "report_run_row_bill_check.html", row=row, raw_data=raw_data, tables=tables
1697
1690
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chellow
3
- Version: 1757320031.0.0
3
+ Version: 1759411815.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)
@@ -18,7 +18,7 @@ Requires-Dist: pg8000==1.31.1
18
18
  Requires-Dist: pip>=9.0.1
19
19
  Requires-Dist: psutil==5.9.5
20
20
  Requires-Dist: pympler==1.0.1
21
- Requires-Dist: pypdf==4.3.1
21
+ Requires-Dist: pypdf==6.0.0
22
22
  Requires-Dist: python-dateutil==2.8.2
23
23
  Requires-Dist: pytz==2022.6
24
24
  Requires-Dist: requests==2.32.4