chellow 1755614564.0.0__py3-none-any.whl → 1759155233.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_importer.py +136 -80
- chellow/e/bill_parsers/activity_mop_stark_xlsx.py +99 -86
- chellow/e/bill_parsers/annual_mop_stark_xlsx.py +78 -61
- chellow/e/bill_parsers/csv.py +139 -101
- chellow/e/bill_parsers/drax_edi.py +65 -88
- chellow/e/bill_parsers/engie_edi.py +187 -255
- chellow/e/bill_parsers/engie_xls.py +153 -167
- chellow/e/bill_parsers/haven_edi.py +189 -228
- chellow/e/bill_parsers/haven_edi_tprs.py +67 -67
- chellow/e/bill_parsers/nonsettlement_dc_stark_xlsx.py +75 -66
- chellow/e/bill_parsers/settlement_dc_stark_xlsx.py +229 -126
- chellow/e/bill_parsers/sse_edi.py +107 -75
- chellow/e/bill_parsers/sww_xls.py +78 -91
- chellow/e/computer.py +1 -1
- chellow/e/views.py +626 -281
- chellow/edi_lib.py +4 -27
- chellow/models.py +92 -3
- chellow/reports/report_111.py +478 -616
- chellow/reports/report_247.py +96 -137
- chellow/templates/e/dc_batch.html +110 -157
- chellow/templates/e/dc_batch_add.html +2 -3
- chellow/templates/e/dc_batch_edit.html +42 -46
- chellow/templates/e/dc_batch_file.html +2 -3
- chellow/templates/e/dc_batch_file_edit.html +28 -40
- chellow/templates/e/dc_batch_upload_file.html +68 -0
- chellow/templates/e/dc_batches.html +2 -1
- chellow/templates/e/dc_batches_edit.html +26 -0
- chellow/templates/e/dc_bill.html +27 -5
- chellow/templates/e/dc_bill_add.html +4 -4
- chellow/templates/e/dc_bill_edit.html +43 -63
- chellow/templates/e/dc_bill_import.html +1 -1
- chellow/templates/e/dc_bill_import_contract.html +130 -0
- chellow/templates/e/dc_contract.html +1 -1
- chellow/templates/e/dc_element.html +41 -0
- chellow/templates/e/dc_element_add.html +36 -0
- chellow/templates/e/dc_element_edit.html +49 -0
- chellow/templates/e/dc_rate_script_edit.html +27 -43
- chellow/templates/e/mop_batch.html +105 -152
- chellow/templates/e/mop_batch_add.html +2 -3
- chellow/templates/e/mop_batch_edit.html +43 -51
- chellow/templates/e/mop_batch_upload_file.html +71 -5
- chellow/templates/e/mop_batches.html +2 -1
- chellow/templates/e/mop_batches_edit.html +26 -0
- chellow/templates/e/mop_bill.html +31 -8
- chellow/templates/e/mop_bill_add.html +7 -27
- chellow/templates/e/mop_bill_import.html +1 -1
- chellow/templates/e/mop_bill_import_contract.html +130 -0
- chellow/templates/e/mop_contract.html +4 -5
- chellow/templates/e/mop_element.html +41 -0
- chellow/templates/e/mop_element_add.html +36 -0
- chellow/templates/e/mop_element_edit.html +49 -0
- chellow/templates/e/supplier_batch.html +3 -7
- chellow/templates/e/supplier_batch_add.html +2 -2
- chellow/templates/e/supplier_batch_edit.html +1 -1
- chellow/templates/e/supplier_batch_file.html +3 -5
- chellow/templates/e/supplier_batch_file_add.html +18 -11
- chellow/templates/e/supplier_batch_upload_file.html +83 -9
- chellow/templates/e/supplier_batches.html +4 -4
- chellow/templates/e/supplier_batches_edit.html +26 -0
- chellow/templates/e/supplier_bill.html +29 -6
- chellow/templates/e/supplier_bill_add.html +3 -3
- chellow/templates/e/supplier_bill_import.html +1 -1
- chellow/templates/e/supplier_bill_import_contract.html +118 -0
- chellow/templates/e/supplier_contract.html +1 -1
- chellow/templates/e/supplier_element.html +45 -0
- chellow/templates/e/supplier_element_add.html +36 -0
- chellow/templates/e/supplier_element_edit.html +51 -0
- chellow/templates/report_run_bill_check.html +137 -179
- chellow/templates/report_run_row_bill_check.html +182 -179
- chellow/views.py +55 -65
- {chellow-1755614564.0.0.dist-info → chellow-1759155233.0.0.dist-info}/METADATA +2 -2
- {chellow-1755614564.0.0.dist-info → chellow-1759155233.0.0.dist-info}/RECORD +73 -60
- chellow/e/bill_parsers/drax_element_edi.py +0 -459
- chellow/templates/e/supplier_bill_imports.html +0 -421
- {chellow-1755614564.0.0.dist-info → chellow-1759155233.0.0.dist-info}/WHEEL +0 -0
|
@@ -14,134 +14,105 @@ from chellow.utils import HH, parse_mpan_core, to_ct, to_utc
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
ELEM_MAP = {
|
|
17
|
-
None:
|
|
18
|
-
|
|
19
|
-
None:
|
|
17
|
+
None: {
|
|
18
|
+
None: None,
|
|
19
|
+
"OOC MOP": {None: "meter-rental"},
|
|
20
20
|
},
|
|
21
|
+
"Charge - Recurring": {None: "duos-fixed"},
|
|
21
22
|
"Meter - Standard": {
|
|
22
|
-
"Energy Bill Relief Scheme": {None:
|
|
23
|
-
"Energy Bill Relief Scheme Discount": {None:
|
|
24
|
-
"Energy Bill Discount Scheme": {None:
|
|
25
|
-
},
|
|
26
|
-
"Meter - UK Electricity - AAHEDC Pass-Thru": {
|
|
27
|
-
None: ["aahedc-gbp", "aahedc-rate", "aahedc-gsp-kwh"]
|
|
28
|
-
},
|
|
29
|
-
"Meter - UK Electricity - BSUoS Pass-Thru": {
|
|
30
|
-
None: ["bsuos-gbp", "bsuos-rate", "bsuos-nbp-kwh"]
|
|
23
|
+
"Energy Bill Relief Scheme": {None: "ebrs"},
|
|
24
|
+
"Energy Bill Relief Scheme Discount": {None: "ebrs"},
|
|
25
|
+
"Energy Bill Discount Scheme": {None: "ebrs"},
|
|
31
26
|
},
|
|
27
|
+
"Meter - UK Electricity - AAHEDC Pass-Thru": {None: "aahedc"},
|
|
28
|
+
"Meter - UK Electricity - BSUoS Pass-Thru": {None: "bsuos"},
|
|
32
29
|
"Meter - UK Electricity - Capacity Market Pass-Thru": {
|
|
33
|
-
None:
|
|
34
|
-
"Reverse Capacity Market Estimate": {None:
|
|
35
|
-
},
|
|
36
|
-
"Meter - UK Electricity - CfD FiT Pass-Thru": {
|
|
37
|
-
None: ["cfd-fit-gbp", "cfd-fit-rate", "cfd-fit-nbp-kwh"]
|
|
30
|
+
None: "capacity",
|
|
31
|
+
"Reverse Capacity Market Estimate": {None: "capacity"},
|
|
38
32
|
},
|
|
33
|
+
"Meter - UK Electricity - CfD FiT Pass-Thru": {None: "cfd-fit"},
|
|
39
34
|
"Meter - UK Electricity - CCL": {
|
|
40
|
-
None:
|
|
41
|
-
"CCL": {None:
|
|
42
|
-
"Levy Exempt Energy": {None:
|
|
35
|
+
None: "ccl",
|
|
36
|
+
"CCL": {None: "ccl"},
|
|
37
|
+
"Levy Exempt Energy": {None: "lec"},
|
|
43
38
|
},
|
|
44
39
|
"Meter - UK Electricity - DUoS": {
|
|
45
40
|
None: None,
|
|
46
41
|
"DUoS Unit Rate 3": {
|
|
47
|
-
None:
|
|
42
|
+
None: "duos-green",
|
|
48
43
|
},
|
|
49
44
|
"DUoS Unit Charge 3": {
|
|
50
|
-
None:
|
|
45
|
+
None: "duos-green",
|
|
51
46
|
},
|
|
52
47
|
"DUoS Unit Charge 2": {
|
|
53
|
-
None:
|
|
48
|
+
None: "duos-amber",
|
|
54
49
|
},
|
|
55
50
|
"DUoS Unit Rate 2": {
|
|
56
|
-
None:
|
|
51
|
+
None: "duos-amber",
|
|
57
52
|
},
|
|
58
|
-
"DUoS Unit Charge 1": {None:
|
|
59
|
-
"DUoS Unit Rate 1": {None:
|
|
60
|
-
"DUoS Standing Charge": {
|
|
61
|
-
|
|
62
|
-
},
|
|
63
|
-
"DUoS Fixed": {None: ("duos-fixed-gbp", "duos-fixed-rate", "duos-fixed-days")},
|
|
53
|
+
"DUoS Unit Charge 1": {None: "duos-red"},
|
|
54
|
+
"DUoS Unit Rate 1": {None: "duos-red"},
|
|
55
|
+
"DUoS Standing Charge": {None: "duos-fixed"},
|
|
56
|
+
"DUoS Fixed": {None: "duos-fixed"},
|
|
64
57
|
"DUoS Reactive": {
|
|
65
|
-
None:
|
|
58
|
+
None: "duos-reactive",
|
|
66
59
|
},
|
|
67
60
|
},
|
|
68
61
|
"Meter - UK Electricity - FiT Pass-Thru": {
|
|
69
|
-
None:
|
|
62
|
+
None: "fit",
|
|
70
63
|
},
|
|
71
64
|
"Pass Thru - UK Electricity Cost Component": {
|
|
72
|
-
None:
|
|
73
|
-
},
|
|
74
|
-
"Meter - UK Electricity - RO Pass-Thru": {
|
|
75
|
-
None: ("ro-gbp", "ro-rate", "ro-msp-kwh")
|
|
65
|
+
None: "meter-rental",
|
|
76
66
|
},
|
|
67
|
+
"Meter - UK Electricity - RO Pass-Thru": {None: "ro"},
|
|
77
68
|
"Meter - UK Electricity - TUoS": {
|
|
78
|
-
None:
|
|
69
|
+
None: "triad",
|
|
79
70
|
"TNUoS Fixed": {
|
|
80
|
-
None:
|
|
71
|
+
None: "tnuos",
|
|
81
72
|
},
|
|
82
73
|
},
|
|
83
74
|
"Meter - UK Electricity - Standard": {
|
|
84
75
|
None: None,
|
|
85
76
|
"Unit Rate": {
|
|
86
77
|
"Summer Weekday": {
|
|
87
|
-
None:
|
|
88
|
-
"summer-weekday-gbp",
|
|
89
|
-
"summer-weekday-rate",
|
|
90
|
-
"summer-weekday-gsp-kwh",
|
|
91
|
-
)
|
|
78
|
+
None: "summer-weekday",
|
|
92
79
|
},
|
|
93
|
-
"Peak": {None:
|
|
80
|
+
"Peak": {None: "peak"},
|
|
94
81
|
"Peak Shoulder": {
|
|
95
|
-
None:
|
|
96
|
-
"peak-shoulder-gbp",
|
|
97
|
-
"peak-shoulder-gsp-kwh",
|
|
98
|
-
"peak-shoulder-rate",
|
|
99
|
-
)
|
|
82
|
+
None: "peak-shoulder",
|
|
100
83
|
},
|
|
101
84
|
"Summer Night": {
|
|
102
|
-
None:
|
|
85
|
+
None: "summer-night",
|
|
103
86
|
},
|
|
104
87
|
"Summer Weekend & Bank Holiday": {
|
|
105
|
-
None:
|
|
106
|
-
"summer-weekend-gbp",
|
|
107
|
-
"summer-weekend-rate",
|
|
108
|
-
"summer-weekend-gsp-kwh",
|
|
109
|
-
)
|
|
88
|
+
None: "summer-weekend",
|
|
110
89
|
},
|
|
111
|
-
"Night": {None:
|
|
90
|
+
"Night": {None: "night"},
|
|
112
91
|
"Winter Weekday": {
|
|
113
|
-
None:
|
|
114
|
-
"winter-weekday-gbp",
|
|
115
|
-
"winter-weekday-rate",
|
|
116
|
-
"winter-weekday-gsp-kwh",
|
|
117
|
-
)
|
|
92
|
+
None: "winter-weekday",
|
|
118
93
|
},
|
|
119
94
|
"Winter Weekend & Bank Holiday": {
|
|
120
|
-
None:
|
|
121
|
-
"winter-weekend-gbp",
|
|
122
|
-
"winter-weekend-rate",
|
|
123
|
-
"winter-weekend-gsp-kwh",
|
|
124
|
-
)
|
|
95
|
+
None: "winter-weekend",
|
|
125
96
|
},
|
|
126
97
|
"Winter Night": {
|
|
127
|
-
None:
|
|
98
|
+
None: "winter-night",
|
|
128
99
|
},
|
|
129
|
-
"Day": {None:
|
|
130
|
-
"Single": {None:
|
|
131
|
-
"Off Peak / Weekends": {None:
|
|
100
|
+
"Day": {None: "day"},
|
|
101
|
+
"Single": {None: "day"},
|
|
102
|
+
"Off Peak / Weekends": {None: "day"},
|
|
132
103
|
},
|
|
133
104
|
"Reverse BSUoS in Unit Rate": {
|
|
134
|
-
None:
|
|
105
|
+
None: "bsuos-reverse",
|
|
135
106
|
},
|
|
136
107
|
},
|
|
137
|
-
"Meter - UK Gas - CCL": {None:
|
|
108
|
+
"Meter - UK Gas - CCL": {None: "ccl"},
|
|
138
109
|
}
|
|
139
110
|
|
|
140
111
|
|
|
141
|
-
def
|
|
112
|
+
def _find_name(tree, path):
|
|
142
113
|
if len(path) > 0:
|
|
143
114
|
try:
|
|
144
|
-
return
|
|
115
|
+
return _find_name(tree[path[0]], path[1:])
|
|
145
116
|
except KeyError:
|
|
146
117
|
pass
|
|
147
118
|
|
|
@@ -219,23 +190,23 @@ def get_dec(row, name):
|
|
|
219
190
|
return None
|
|
220
191
|
|
|
221
192
|
|
|
222
|
-
def
|
|
223
|
-
if
|
|
224
|
-
|
|
225
|
-
bd[el_name] = set()
|
|
226
|
-
bd[el_name].add(val)
|
|
193
|
+
def _get_vat_values(bd, percentage):
|
|
194
|
+
if "vat" in bd:
|
|
195
|
+
vat_breakdown = bd["vat"]
|
|
227
196
|
else:
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
)
|
|
197
|
+
vat_breakdown = bd["vat"] = {}
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
vat_values = vat_breakdown[percentage]
|
|
201
|
+
except KeyError:
|
|
202
|
+
vat_values = vat_breakdown[percentage] = {
|
|
203
|
+
"vat": Decimal("0.00"),
|
|
204
|
+
"net": Decimal("0.00"),
|
|
205
|
+
}
|
|
206
|
+
return vat_values
|
|
236
207
|
|
|
237
208
|
|
|
238
|
-
def _parse_row(row, row_index, datemode, title_row):
|
|
209
|
+
def _parse_row(bills, row, row_index, datemode, title_row):
|
|
239
210
|
val = get_value(row, "Meter Point")
|
|
240
211
|
try:
|
|
241
212
|
mpan_core = parse_mpan_core(str(int(val)))
|
|
@@ -245,6 +216,11 @@ def _parse_row(row, row_index, datemode, title_row):
|
|
|
245
216
|
f"{e}"
|
|
246
217
|
)
|
|
247
218
|
|
|
219
|
+
try:
|
|
220
|
+
mc = bills[mpan_core]
|
|
221
|
+
except KeyError:
|
|
222
|
+
mc = bills[mpan_core] = {}
|
|
223
|
+
|
|
248
224
|
bill_period = get_value(row, "Bill Period")
|
|
249
225
|
if "-" in bill_period:
|
|
250
226
|
period_start_naive, period_finish_naive = [
|
|
@@ -255,6 +231,26 @@ def _parse_row(row, row_index, datemode, title_row):
|
|
|
255
231
|
else:
|
|
256
232
|
period_start, period_finish = None, None
|
|
257
233
|
|
|
234
|
+
issue_date = get_date(row, "Bill Date", datemode)
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
bill = mc[bill_period]
|
|
238
|
+
except KeyError:
|
|
239
|
+
bill = mc[bill_period] = {
|
|
240
|
+
"bill_type_code": "N",
|
|
241
|
+
"kwh": Decimal(0),
|
|
242
|
+
"vat": Decimal("0.00"),
|
|
243
|
+
"net": Decimal("0.00"),
|
|
244
|
+
"reads": [],
|
|
245
|
+
"breakdown": {"raw_lines": [str(title_row)]},
|
|
246
|
+
"account": mpan_core,
|
|
247
|
+
"issue_date": issue_date,
|
|
248
|
+
"start_date": period_start,
|
|
249
|
+
"finish_date": period_finish,
|
|
250
|
+
"mpan_core": mpan_core,
|
|
251
|
+
"elements": [],
|
|
252
|
+
}
|
|
253
|
+
|
|
258
254
|
from_date = get_date(row, "From Date", datemode)
|
|
259
255
|
if from_date is None:
|
|
260
256
|
if period_start is None:
|
|
@@ -272,25 +268,11 @@ def _parse_row(row, row_index, datemode, title_row):
|
|
|
272
268
|
else:
|
|
273
269
|
to_date = to_utc(to_ct(to_date_naive + relativedelta(days=1) - HH))
|
|
274
270
|
|
|
275
|
-
issue_date = get_date(row, "Bill Date", datemode)
|
|
276
271
|
bill_number = get_value(row, "Bill Number")
|
|
277
|
-
bill = {
|
|
278
|
-
"bill_type_code": "N",
|
|
279
|
-
"kwh": Decimal(0),
|
|
280
|
-
"vat": Decimal("0.00"),
|
|
281
|
-
"net": Decimal("0.00"),
|
|
282
|
-
"reads": [],
|
|
283
|
-
"breakdown": {"raw_lines": [str(title_row)]},
|
|
284
|
-
"account": mpan_core,
|
|
285
|
-
"issue_date": issue_date,
|
|
286
|
-
"start_date": from_date,
|
|
287
|
-
"finish_date": to_date,
|
|
288
|
-
"mpan_core": mpan_core,
|
|
289
|
-
}
|
|
290
272
|
bd = bill["breakdown"]
|
|
291
273
|
|
|
292
274
|
usage = get_dec(row, "Usage")
|
|
293
|
-
|
|
275
|
+
usage_units = get_value(row, "Usage Unit")
|
|
294
276
|
price = get_dec(row, "Price")
|
|
295
277
|
amount = get_dec(row, "Amount")
|
|
296
278
|
product_item_name = get_value(row, "Product Item Name")
|
|
@@ -299,92 +281,96 @@ def _parse_row(row, row_index, datemode, title_row):
|
|
|
299
281
|
bill["kwh"] += round(usage, 2)
|
|
300
282
|
description = get_value(row, "Description")
|
|
301
283
|
product_class = get_value(row, "Product Item Class")
|
|
284
|
+
|
|
302
285
|
if description in ("Standard VAT@20%", "Reduced VAT@5%"):
|
|
303
|
-
|
|
286
|
+
vat_gbp = round(amount, 2)
|
|
287
|
+
bill["vat"] += vat_gbp
|
|
304
288
|
if description.endswith("20%"):
|
|
305
289
|
vat_percentage = Decimal("20")
|
|
306
290
|
else:
|
|
307
291
|
vat_percentage = Decimal("5")
|
|
308
292
|
bd["vat_percentage"] = vat_percentage
|
|
293
|
+
|
|
294
|
+
if "vat-rate" in bd:
|
|
295
|
+
vat_rate = bd["vat-rate"]
|
|
296
|
+
else:
|
|
297
|
+
vat_rate = bd["vat-rate"] = set()
|
|
298
|
+
|
|
299
|
+
vat_rate.add(vat_percentage / Decimal("100"))
|
|
300
|
+
|
|
301
|
+
vat_values = _get_vat_values(bd, vat_percentage)
|
|
302
|
+
vat_values["vat"] += vat_gbp
|
|
309
303
|
else:
|
|
310
|
-
|
|
304
|
+
net = round(amount, 2)
|
|
305
|
+
bill["net"] += net
|
|
311
306
|
|
|
312
|
-
|
|
313
|
-
|
|
307
|
+
sales_tax_rate = get_value(row, "Sales Tax Rate")
|
|
308
|
+
if sales_tax_rate == "Commercial UK Energy VAT":
|
|
309
|
+
vat_values = _get_vat_values(bd, 20)
|
|
310
|
+
vat_values["net"] += net
|
|
314
311
|
|
|
312
|
+
path = [product_class, description, rate_name]
|
|
313
|
+
elname = _find_name(ELEM_MAP, path)
|
|
314
|
+
ebd = {}
|
|
315
315
|
duos_avail_prefix = "DUoS Availability ("
|
|
316
316
|
duos_excess_avail_prefix = "DUoS Excess Availability ("
|
|
317
317
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
_bd_add(bd, "duos-excess-availability-days", usage)
|
|
335
|
-
_bd_add(bd, "duos-excess-availability-rate", price)
|
|
336
|
-
_bd_add(bd, "duos-excess-availability-gbp", amount)
|
|
337
|
-
elif description.startswith("BSUoS Black Start "):
|
|
338
|
-
_bd_add(bd, "black-start-gbp", amount)
|
|
339
|
-
elif description.startswith("BSUoS Reconciliation - "):
|
|
340
|
-
if usage is not None:
|
|
341
|
-
_bd_add(bd, "bsuos-nbp-kwh", usage)
|
|
342
|
-
if price is not None:
|
|
343
|
-
_bd_add(bd, "bsuos-rate", price)
|
|
344
|
-
_bd_add(bd, "bsuos-gbp", amount)
|
|
345
|
-
elif description.startswith("FiT Rec - "):
|
|
346
|
-
_bd_add(bd, "fit-gbp", amount)
|
|
347
|
-
elif description.startswith("FiT Reconciliation "):
|
|
348
|
-
_bd_add(bd, "fit-gbp", amount)
|
|
349
|
-
elif description.startswith("CfD FiT Rec - ") or description.startswith(
|
|
350
|
-
"CfD FiT Reconciliation"
|
|
318
|
+
for prefix, name in (
|
|
319
|
+
("DUoS Availability Adjustment ", "duos-availability"),
|
|
320
|
+
("DUoS Availability", "duos-availability"),
|
|
321
|
+
("DUoS Excess Availability", "duos-excess-availability"),
|
|
322
|
+
("BSUoS Black Start ", "black-start"),
|
|
323
|
+
("BSUoS Reconciliation - ", "bsuos"),
|
|
324
|
+
("FiT Rec - ", "fit"),
|
|
325
|
+
("FiT Reconciliation ", "fit"),
|
|
326
|
+
("CfD FiT Rec - ", "cfd-fit"),
|
|
327
|
+
("CfD FiT Reconciliation", "cfd-fit"),
|
|
328
|
+
("Flex", "reconciliation"),
|
|
329
|
+
("Legacy TNUoS Reversal ", "triad"),
|
|
330
|
+
("Hand Held Read -", "meter-rental"),
|
|
331
|
+
("RO Mutualisation ", "ro"),
|
|
332
|
+
("OOC MOP - ", "meter-rental"),
|
|
333
|
+
("KVa Adjustment ", "duos-availability"),
|
|
351
334
|
):
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
elif description.startswith("OOC MOP - "):
|
|
362
|
-
_bd_add(bd, "meter-rental-gbp", amount)
|
|
363
|
-
elif description.startswith("KVa Adjustment "):
|
|
364
|
-
_bd_add(bd, "duos-availability-gbp", amount)
|
|
365
|
-
elif names is not None:
|
|
366
|
-
for elem_k, elem_v in zip(names, (amount, price, usage)):
|
|
367
|
-
if elem_k is not None:
|
|
368
|
-
_bd_add(bd, elem_k, elem_v)
|
|
369
|
-
else:
|
|
335
|
+
if description.startswith(prefix):
|
|
336
|
+
elname = name
|
|
337
|
+
if description.startswith(duos_excess_avail_prefix):
|
|
338
|
+
ebd["kva"] = int(description[len(duos_excess_avail_prefix) : -5])
|
|
339
|
+
elif description.startswith(duos_avail_prefix):
|
|
340
|
+
ebd["kva"] = int(description[len(duos_avail_prefix) : -5])
|
|
341
|
+
break
|
|
342
|
+
|
|
343
|
+
if elname is None:
|
|
370
344
|
raise BadRequest(
|
|
371
345
|
f"For the path {path} the parser can't work out the element."
|
|
372
346
|
)
|
|
373
347
|
|
|
348
|
+
if usage is not None:
|
|
349
|
+
if isinstance(usage_units, str) and usage_units != "":
|
|
350
|
+
units = usage_units.lower()
|
|
351
|
+
else:
|
|
352
|
+
units = "kwh"
|
|
353
|
+
ebd[units] = usage
|
|
354
|
+
if price is not None:
|
|
355
|
+
ebd["rate"] = price
|
|
356
|
+
bill["elements"].append(
|
|
357
|
+
{
|
|
358
|
+
"start_date": from_date,
|
|
359
|
+
"finish_date": to_date,
|
|
360
|
+
"name": elname,
|
|
361
|
+
"net": net,
|
|
362
|
+
"breakdown": ebd,
|
|
363
|
+
}
|
|
364
|
+
)
|
|
365
|
+
|
|
374
366
|
reference = str(bill_number) + "_" + str(row_index + 1)
|
|
375
|
-
for k, v in tuple(bd.items()):
|
|
376
|
-
if isinstance(v, set):
|
|
377
|
-
bd[k] = list(v)
|
|
378
|
-
elif k.endswith("-gbp"):
|
|
379
|
-
reference += "_" + k[:-4]
|
|
380
367
|
|
|
381
368
|
bill["reference"] = reference
|
|
382
369
|
bill["gross"] = bill["net"] + bill["vat"]
|
|
383
|
-
return bill
|
|
384
370
|
|
|
385
371
|
|
|
386
372
|
def _make_raw_bills(sheet, datemode):
|
|
387
|
-
bills =
|
|
373
|
+
bills = {}
|
|
388
374
|
title_row = sheet.row(0)
|
|
389
375
|
for row_index in range(1, sheet.nrows):
|
|
390
376
|
row = sheet.row(row_index)
|
|
@@ -392,11 +378,11 @@ def _make_raw_bills(sheet, datemode):
|
|
|
392
378
|
val = row[21].value
|
|
393
379
|
if val not in (None, ""):
|
|
394
380
|
try:
|
|
395
|
-
|
|
381
|
+
_parse_row(bills, row, row_index, datemode, title_row)
|
|
396
382
|
except BadRequest as e:
|
|
397
383
|
raise BadRequest(f"On row {row_index + 1}: {e.description}")
|
|
398
384
|
|
|
399
|
-
return bills
|
|
385
|
+
return [b for mc in bills.values() for b in mc.values()]
|
|
400
386
|
|
|
401
387
|
|
|
402
388
|
class Parser:
|