chellow 1718704260.0.0__py3-none-any.whl → 1718904221.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/e/bill_parsers/engie_xlsx.py +67 -51
- chellow/e/cfd.py +4 -1
- chellow/templates/site.html +2 -3
- {chellow-1718704260.0.0.dist-info → chellow-1718904221.0.0.dist-info}/METADATA +1 -1
- {chellow-1718704260.0.0.dist-info → chellow-1718904221.0.0.dist-info}/RECORD +6 -6
- {chellow-1718704260.0.0.dist-info → chellow-1718904221.0.0.dist-info}/WHEEL +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import csv
|
|
2
2
|
from datetime import datetime as Datetime
|
|
3
3
|
from decimal import Decimal, InvalidOperation
|
|
4
|
-
from
|
|
4
|
+
from enum import Enum, auto
|
|
5
5
|
|
|
6
6
|
from dateutil.relativedelta import relativedelta
|
|
7
7
|
|
|
@@ -147,39 +147,56 @@ def _find_names(tree, path):
|
|
|
147
147
|
return tree[None]
|
|
148
148
|
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
"
|
|
169
|
-
"
|
|
170
|
-
"
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
"
|
|
174
|
-
"Usage
|
|
175
|
-
"Price",
|
|
176
|
-
"Amount",
|
|
177
|
-
"
|
|
178
|
-
"
|
|
179
|
-
|
|
180
|
-
"
|
|
181
|
-
]
|
|
182
|
-
|
|
150
|
+
class Title(Enum):
|
|
151
|
+
METER_POINT = auto()
|
|
152
|
+
BILL_PERIOD = auto()
|
|
153
|
+
FROM_DATE = auto()
|
|
154
|
+
TO_DATE = auto()
|
|
155
|
+
BILL_DATE = auto()
|
|
156
|
+
BILL_NUMBER = auto()
|
|
157
|
+
USAGE = auto()
|
|
158
|
+
PRICE = auto()
|
|
159
|
+
AMOUNT = auto()
|
|
160
|
+
PRODUCT_ITEM_NAME = auto()
|
|
161
|
+
RATE_NAME = auto()
|
|
162
|
+
DESCRIPTION = auto()
|
|
163
|
+
PRODUCT_ITEM_CLASS = auto()
|
|
164
|
+
CUSTOMER_NUMBER = auto()
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
COLUMNS = {
|
|
168
|
+
Title.METER_POINT: ["Meter Point", "MeterPoint"],
|
|
169
|
+
Title.BILL_PERIOD: ["Bill Period", "BillPeriod"],
|
|
170
|
+
Title.FROM_DATE: ["From Date", "FromDate"],
|
|
171
|
+
Title.TO_DATE: ["To Date", "ToDate"],
|
|
172
|
+
Title.BILL_DATE: ["Bill Date", "BillDate"],
|
|
173
|
+
Title.BILL_NUMBER: ["Bill Number", "BillNumber"],
|
|
174
|
+
Title.USAGE: ["Usage"],
|
|
175
|
+
Title.PRICE: ["Price"],
|
|
176
|
+
Title.AMOUNT: ["Amount"],
|
|
177
|
+
Title.PRODUCT_ITEM_NAME: ["Product Item Name", "ProductItemName"],
|
|
178
|
+
Title.RATE_NAME: ["Rate Name", "RateName"],
|
|
179
|
+
Title.DESCRIPTION: ["Description"],
|
|
180
|
+
Title.PRODUCT_ITEM_CLASS: ["Product Item Class", "ProductItemClass"],
|
|
181
|
+
Title.CUSTOMER_NUMBER: ["Customer Number", "CustomerNumber"],
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def make_column_map(title_row):
|
|
186
|
+
titles = [cell.value for cell in title_row]
|
|
187
|
+
column_map = {}
|
|
188
|
+
for title, title_names in COLUMNS.items():
|
|
189
|
+
idx = None
|
|
190
|
+
for title_name in title_names:
|
|
191
|
+
try:
|
|
192
|
+
idx = titles.index(title_name)
|
|
193
|
+
except ValueError:
|
|
194
|
+
pass
|
|
195
|
+
if idx is None:
|
|
196
|
+
raise BadRequest(f"For the title {title} a column can't be found")
|
|
197
|
+
|
|
198
|
+
column_map[title] = idx + 1
|
|
199
|
+
return column_map
|
|
183
200
|
|
|
184
201
|
|
|
185
202
|
def get_date_naive(sheet, row, col):
|
|
@@ -198,8 +215,7 @@ def get_date(sheet, row, col_name):
|
|
|
198
215
|
return None if dt is None else to_utc(to_ct(dt))
|
|
199
216
|
|
|
200
217
|
|
|
201
|
-
def get_value(sheet, row,
|
|
202
|
-
col = COLUMN_MAP[col_name]
|
|
218
|
+
def get_value(sheet, row, col):
|
|
203
219
|
try:
|
|
204
220
|
return sheet.cell(row=row, column=col).value
|
|
205
221
|
except IndexError:
|
|
@@ -256,7 +272,6 @@ def _bd_add(bd, el_name, val):
|
|
|
256
272
|
|
|
257
273
|
|
|
258
274
|
def _customer_mods(cust_number, description, bill):
|
|
259
|
-
print(cust_number, type(cust_number), description)
|
|
260
275
|
if cust_number == 10001596:
|
|
261
276
|
if (
|
|
262
277
|
description == "RO Mutualisation 2021-22"
|
|
@@ -272,7 +287,8 @@ def _customer_mods(cust_number, description, bill):
|
|
|
272
287
|
|
|
273
288
|
|
|
274
289
|
def _parse_row(sheet, row, title_row):
|
|
275
|
-
|
|
290
|
+
column_map = make_column_map(title_row)
|
|
291
|
+
val = get_value(sheet, row, column_map[Title.METER_POINT])
|
|
276
292
|
try:
|
|
277
293
|
mpan_core = parse_mpan_core(str(int(val)))
|
|
278
294
|
except ValueError as e:
|
|
@@ -281,7 +297,7 @@ def _parse_row(sheet, row, title_row):
|
|
|
281
297
|
f"{e}"
|
|
282
298
|
)
|
|
283
299
|
|
|
284
|
-
bill_period = get_value(sheet, row,
|
|
300
|
+
bill_period = get_value(sheet, row, column_map[Title.BILL_PERIOD])
|
|
285
301
|
if "-" in bill_period:
|
|
286
302
|
period_start_naive, period_finish_naive = [
|
|
287
303
|
Datetime.strptime(v, "%Y-%m-%d") for v in bill_period.split(" - ")
|
|
@@ -291,14 +307,14 @@ def _parse_row(sheet, row, title_row):
|
|
|
291
307
|
else:
|
|
292
308
|
period_start, period_finish = None, None
|
|
293
309
|
|
|
294
|
-
from_date = get_date(sheet, row,
|
|
310
|
+
from_date = get_date(sheet, row, column_map[Title.FROM_DATE])
|
|
295
311
|
if from_date is None:
|
|
296
312
|
if period_start is None:
|
|
297
313
|
raise BadRequest("Can't find a bill start date.")
|
|
298
314
|
else:
|
|
299
315
|
from_date = period_start
|
|
300
316
|
|
|
301
|
-
to_date_naive = get_date_naive(sheet, row,
|
|
317
|
+
to_date_naive = get_date_naive(sheet, row, column_map[Title.TO_DATE])
|
|
302
318
|
if to_date_naive is None:
|
|
303
319
|
if period_finish is None:
|
|
304
320
|
raise BadRequest("Can't find a bill finish date.")
|
|
@@ -308,8 +324,8 @@ def _parse_row(sheet, row, title_row):
|
|
|
308
324
|
else:
|
|
309
325
|
to_date = to_utc(to_ct(to_date_naive + relativedelta(days=1) - HH))
|
|
310
326
|
|
|
311
|
-
issue_date = get_date(sheet, row,
|
|
312
|
-
bill_number = get_value(sheet, row,
|
|
327
|
+
issue_date = get_date(sheet, row, column_map[Title.BILL_DATE])
|
|
328
|
+
bill_number = get_value(sheet, row, column_map[Title.BILL_NUMBER])
|
|
313
329
|
bill = {
|
|
314
330
|
"bill_type_code": "N",
|
|
315
331
|
"kwh": Decimal(0),
|
|
@@ -325,16 +341,16 @@ def _parse_row(sheet, row, title_row):
|
|
|
325
341
|
}
|
|
326
342
|
bd = bill["breakdown"]
|
|
327
343
|
|
|
328
|
-
usage = get_dec(sheet, row,
|
|
344
|
+
usage = get_dec(sheet, row, column_map[Title.USAGE])
|
|
329
345
|
# usage_units = get_value(sheet, row, 'Usage Unit')
|
|
330
|
-
price = get_dec(sheet, row,
|
|
331
|
-
amount = get_dec(sheet, row,
|
|
332
|
-
product_item_name = get_value(sheet, row,
|
|
333
|
-
rate_name = get_value(sheet, row,
|
|
346
|
+
price = get_dec(sheet, row, column_map[Title.PRICE])
|
|
347
|
+
amount = get_dec(sheet, row, column_map[Title.AMOUNT])
|
|
348
|
+
product_item_name = get_value(sheet, row, column_map[Title.PRODUCT_ITEM_NAME])
|
|
349
|
+
rate_name = get_value(sheet, row, column_map[Title.RATE_NAME])
|
|
334
350
|
if product_item_name == "Renewables Obligation (RO)" and usage is not None:
|
|
335
351
|
bill["kwh"] += round(usage, 2)
|
|
336
|
-
description = get_value(sheet, row,
|
|
337
|
-
product_class = get_value(sheet, row,
|
|
352
|
+
description = get_value(sheet, row, column_map[Title.DESCRIPTION])
|
|
353
|
+
product_class = get_value(sheet, row, column_map[Title.PRODUCT_ITEM_CLASS])
|
|
338
354
|
if description in ("Standard VAT@20%", "Reduced VAT@5%"):
|
|
339
355
|
bill["vat"] += round(amount, 2)
|
|
340
356
|
if description.endswith("20%"):
|
|
@@ -416,7 +432,7 @@ def _parse_row(sheet, row, title_row):
|
|
|
416
432
|
|
|
417
433
|
bill["reference"] = reference
|
|
418
434
|
bill["gross"] = bill["net"] + bill["vat"]
|
|
419
|
-
customer_number = get_value(sheet, row,
|
|
435
|
+
customer_number = get_value(sheet, row, column_map[Title.CUSTOMER_NUMBER])
|
|
420
436
|
return _customer_mods(customer_number, description, bill)
|
|
421
437
|
|
|
422
438
|
|
chellow/e/cfd.py
CHANGED
|
@@ -370,7 +370,10 @@ def import_forecast_ilr_tra(sess, log, set_progress, s):
|
|
|
370
370
|
)
|
|
371
371
|
|
|
372
372
|
for record in api_records(log, s, "fbece4ce-7cfc-42b7-8fb2-387cf59a3c32"):
|
|
373
|
-
|
|
373
|
+
period_start_str = record["Period_Start"]
|
|
374
|
+
if len(period_start_str) == 0:
|
|
375
|
+
continue
|
|
376
|
+
period_start = _parse_varying_date(period_start_str)
|
|
374
377
|
|
|
375
378
|
rs = sess.execute(
|
|
376
379
|
select(RateScript).where(
|
chellow/templates/site.html
CHANGED
|
@@ -351,9 +351,8 @@ Table of site level monthly kWh, MD kWh etc.</a>
|
|
|
351
351
|
<fieldset>
|
|
352
352
|
<input type="hidden" name="site_id" value="{{site.id}}">
|
|
353
353
|
<legend>Monthly Duration</legend>
|
|
354
|
-
<
|
|
355
|
-
|
|
356
|
-
{{input_date('finish', last_month_finish, resolution='month')}}
|
|
354
|
+
<label>Number Of Months</label> {{input_text('months', '1', 2, 2)}}
|
|
355
|
+
<label>Last Month</label> {{input_date('finish', last_month_finish, resolution='month')}}
|
|
357
356
|
<input type="submit" value="Download">
|
|
358
357
|
</fieldset>
|
|
359
358
|
</form>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: chellow
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1718904221.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 @@ chellow/e/bill_importer.py,sha256=7UcnqNlKbJc2GhW9gy8sDp9GuqambJVpZLvbafOZztA,74
|
|
|
18
18
|
chellow/e/bmarketidx.py,sha256=C0BaHn2RxIuWH2QzA-OmSP0fbUGvW9tqEUhLnzOEdmA,7968
|
|
19
19
|
chellow/e/bsuos.py,sha256=hdP9vnOJSuZl46OAkJeUg1XJYvYIBj4J6Sqce1Hy9Vs,15542
|
|
20
20
|
chellow/e/ccl.py,sha256=30dh_SvlgzsTQPPAJNZWILaMvbeDsv9-P-S1JxS5_SQ,3184
|
|
21
|
-
chellow/e/cfd.py,sha256=
|
|
21
|
+
chellow/e/cfd.py,sha256=RvJRLDLY-KvT299a8xF-HRmslPZczqTgJ9C1zBo55U8,14456
|
|
22
22
|
chellow/e/computer.py,sha256=KjHE57I3I7-1zPkyqX0mSjORlyUNfSEhQb2df4sCNkU,67244
|
|
23
23
|
chellow/e/dno_rate_parser.py,sha256=9A3SEBUQnnjx2Tw3CpA2q0KsJ-Pjgmt_mbADkEtsIzc,21497
|
|
24
24
|
chellow/e/duos.py,sha256=nwviRjz-qIt3GxIMHk0hItIT4dtKsxOWq9TUC1z-hO8,30864
|
|
@@ -46,7 +46,7 @@ chellow/e/bill_parsers/bgb_edi.py,sha256=GuwHeYbAGk7BVg5n19FcTANFDyKI-y0z3f9niQa
|
|
|
46
46
|
chellow/e/bill_parsers/csv.py,sha256=U5zcIaZ6B5QTTpFDAcBnk4G2r8B3j5kJhDPL4AJNkEk,5640
|
|
47
47
|
chellow/e/bill_parsers/engie_edi.py,sha256=CTobTskDjzdcqqf_qk2ukDSaTLrVpGZMM0sYlwehog4,14985
|
|
48
48
|
chellow/e/bill_parsers/engie_xls.py,sha256=jrut2heH_ZWmSjcn7celOydZS9Y49GfpYjDk_EKwamI,14453
|
|
49
|
-
chellow/e/bill_parsers/engie_xlsx.py,sha256=
|
|
49
|
+
chellow/e/bill_parsers/engie_xlsx.py,sha256=4Hu3ls1uNMH7vjDHgcP6QARlGlvb616CqG3xZVjAKWo,16888
|
|
50
50
|
chellow/e/bill_parsers/gdf_csv.py,sha256=ZfK3Oc6oP28p_P9DIevLNB_zW2WLcEJ3Lvb1gL310YU,7382
|
|
51
51
|
chellow/e/bill_parsers/haven_csv.py,sha256=0uENq8IgVNqdxfBQMBxLTSZWCOuDHXZC0xzk52SbfyE,13652
|
|
52
52
|
chellow/e/bill_parsers/haven_edi.py,sha256=YGPHRxPOhje9s32jqPHHELni2tooOYj3cMC_qaZVPq4,16107
|
|
@@ -139,7 +139,7 @@ chellow/templates/report_run_row.html,sha256=bmtcdqJaS1CXpL0i8PuqvmeF98jKNYX5-mn
|
|
|
139
139
|
chellow/templates/report_run_row_bill_check.html,sha256=aC2LMu_6NvmTN3ZdxHJPPPczyxPN6hg0F-PPcqIWUws,4683
|
|
140
140
|
chellow/templates/report_run_supply_contacts.html,sha256=JNzwz9M6qbLRDMkCzFCxxANapUer5klxo7t5a48nAzg,2117
|
|
141
141
|
chellow/templates/report_runs.html,sha256=Xef2nilmHHSnyRNKUQJrU2qWsQfslFL_wWD5rR92SOo,667
|
|
142
|
-
chellow/templates/site.html,sha256=
|
|
142
|
+
chellow/templates/site.html,sha256=H0hHgwLSkTZKRh1_aW9X9EKd6HUWJhGIu3AXBBskOmw,10104
|
|
143
143
|
chellow/templates/site_add.html,sha256=NxYmOIZQH6X8EBOuJUbhUJ8IYB3t0BukjR1yVRhnJhM,422
|
|
144
144
|
chellow/templates/site_edit.html,sha256=TJ_ZDDkodj-uDB3GPP9Cel3FGZY2oP42KCzHOydPWVc,2909
|
|
145
145
|
chellow/templates/site_gen_graph.html,sha256=LXkD4n_aC_sFm9JJTCmBRrczpyTn2UUEgBToFiM5RPo,3468
|
|
@@ -364,6 +364,6 @@ chellow/templates/g/supply_note_edit.html,sha256=b8mB6_ucBwoljp03iy6AgVaZUhGw3-1
|
|
|
364
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-
|
|
368
|
-
chellow-
|
|
369
|
-
chellow-
|
|
367
|
+
chellow-1718904221.0.0.dist-info/METADATA,sha256=IisGBzL1b8FQnHDQYk0fVZH4QA21ue5l6JYZ8K4pVIE,12205
|
|
368
|
+
chellow-1718904221.0.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
|
369
|
+
chellow-1718904221.0.0.dist-info/RECORD,,
|
|
File without changes
|