chellow 1716370405.0.0__py3-none-any.whl → 1716564585.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/mm.py +236 -39
- chellow/e/views.py +4 -0
- chellow/models.py +15 -0
- chellow/reports/report_111.py +15 -21
- chellow/reports/report_387.py +2 -2
- chellow/templates/e/supplier_bill_import.html +26 -2
- {chellow-1716370405.0.0.dist-info → chellow-1716564585.0.0.dist-info}/METADATA +3 -3
- {chellow-1716370405.0.0.dist-info → chellow-1716564585.0.0.dist-info}/RECORD +9 -9
- {chellow-1716370405.0.0.dist-info → chellow-1716564585.0.0.dist-info}/WHEEL +0 -0
chellow/e/bill_parsers/mm.py
CHANGED
|
@@ -1,12 +1,222 @@
|
|
|
1
1
|
import datetime
|
|
2
|
+
from collections import defaultdict
|
|
2
3
|
from decimal import Decimal
|
|
3
4
|
from io import StringIO
|
|
4
5
|
|
|
5
|
-
from
|
|
6
|
+
from werkzeug.exceptions import BadRequest
|
|
6
7
|
|
|
8
|
+
from chellow.utils import HH, to_ct, to_utc
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
def parse_date(date_str):
|
|
12
|
+
return to_utc(to_ct(parse_date_naive(date_str)))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def parse_date_naive(date_str):
|
|
16
|
+
return datetime.datetime.strptime(date_str, "%Y%m%d")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _chop_record(record, **kwargs):
|
|
20
|
+
parts = {}
|
|
21
|
+
idx = 0
|
|
22
|
+
for name, length in kwargs.items():
|
|
23
|
+
parts[name] = record[idx : idx + length]
|
|
24
|
+
idx += length
|
|
25
|
+
return parts
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
DATE_LENGTH = 8
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _handle_0000(headers, pre_record, record):
|
|
32
|
+
parts = _chop_record(record, unknown_1=9, issue_date=DATE_LENGTH)
|
|
33
|
+
headers["issue_date"] = parse_date(parts["issue_date"])
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _handle_0050(headers, pre_record, record):
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _handle_0051(headers, pre_record, record):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _handle_0100(headers, pre_record, record):
|
|
45
|
+
issue_date = headers["issue_date"]
|
|
46
|
+
headers.clear()
|
|
47
|
+
headers["issue_date"] = issue_date
|
|
48
|
+
headers["account"] = pre_record[33:41]
|
|
49
|
+
headers["reference"] = pre_record[41:46]
|
|
50
|
+
headers["kwh"] = Decimal("0")
|
|
51
|
+
headers["breakdown"] = defaultdict(int, {"vat": {}})
|
|
52
|
+
headers["reads"] = []
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _handle_0101(headers, pre_record, record):
|
|
56
|
+
parts = _chop_record(record, start_date=DATE_LENGTH, finish_date=DATE_LENGTH)
|
|
57
|
+
headers["start_date"] = parse_date(parts["start_date"])
|
|
58
|
+
headers["finish_date"] = to_utc(to_ct(parse_date_naive(parts["finish_date"]) - HH))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
CHARGE_LOOKUP = {
|
|
62
|
+
"STDG": "days",
|
|
63
|
+
"UNIT": "kwh",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
ELEMENT_LOOKUP = {"10ANNUAL": "standing", "20RS0108": "0001", "9WANNUAL": "site_fee"}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _handle_0460(headers, pre_record, record):
|
|
70
|
+
parts = _chop_record(
|
|
71
|
+
record,
|
|
72
|
+
unknown_1=12,
|
|
73
|
+
gbp=12,
|
|
74
|
+
code=8,
|
|
75
|
+
quantity=12,
|
|
76
|
+
charge=4,
|
|
77
|
+
unknown_2=18,
|
|
78
|
+
rate=16,
|
|
79
|
+
unknown_date=DATE_LENGTH,
|
|
80
|
+
another_gbp=12,
|
|
81
|
+
charge_description=35,
|
|
82
|
+
)
|
|
83
|
+
units = CHARGE_LOOKUP[parts["charge"]]
|
|
84
|
+
gbp = Decimal(parts["gbp"]) / 100
|
|
85
|
+
quantity = Decimal(parts["quantity"])
|
|
86
|
+
rate = Decimal(parts["rate"])
|
|
87
|
+
element_name = ELEMENT_LOOKUP[parts["code"]]
|
|
88
|
+
breakdown = headers["breakdown"]
|
|
89
|
+
breakdown[f"{element_name}-{units}"] += quantity
|
|
90
|
+
rate_name = f"{element_name}-rate"
|
|
91
|
+
if rate_name in breakdown:
|
|
92
|
+
rates = breakdown[rate_name]
|
|
93
|
+
else:
|
|
94
|
+
rates = breakdown[rate_name] = set()
|
|
95
|
+
|
|
96
|
+
rates.add(rate)
|
|
97
|
+
breakdown[f"{element_name}-gbp"] += gbp
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
UNITS_LOOKUP = {"KWH": "kwh"}
|
|
101
|
+
|
|
102
|
+
REGISTER_CODE_LOOKUP = {"000001": "0001"}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _handle_0461(headers, pre_record, record):
|
|
106
|
+
parts = _chop_record(
|
|
107
|
+
record,
|
|
108
|
+
msn=11,
|
|
109
|
+
unknown_1=2,
|
|
110
|
+
prev_read_value=12,
|
|
111
|
+
pres_read_value=12,
|
|
112
|
+
register_code=6,
|
|
113
|
+
units=6,
|
|
114
|
+
quantity=12,
|
|
115
|
+
charge=6,
|
|
116
|
+
prev_read_type=1,
|
|
117
|
+
pres_read_type=1,
|
|
118
|
+
mpan_core=13,
|
|
119
|
+
mpan_top=8,
|
|
120
|
+
tariff_code=19,
|
|
121
|
+
pres_read_date=DATE_LENGTH,
|
|
122
|
+
prev_read_date=DATE_LENGTH,
|
|
123
|
+
)
|
|
124
|
+
mpan_core = parts["mpan_core"]
|
|
125
|
+
headers["mpan_core"] = mpan_core
|
|
126
|
+
units = UNITS_LOOKUP[parts["units"].strip()]
|
|
127
|
+
if units == "kwh":
|
|
128
|
+
headers["kwh"] += Decimal(parts["quantity"])
|
|
129
|
+
tpr_code = REGISTER_CODE_LOOKUP[parts["register_code"]]
|
|
130
|
+
|
|
131
|
+
headers["reads"].append(
|
|
132
|
+
{
|
|
133
|
+
"msn": parts["msn"].strip(),
|
|
134
|
+
"mpan": f"{parts['mpan_top']} {mpan_core}",
|
|
135
|
+
"coefficient": 1,
|
|
136
|
+
"units": units,
|
|
137
|
+
"tpr_code": tpr_code,
|
|
138
|
+
"prev_date": parse_date(parts["prev_read_date"]),
|
|
139
|
+
"prev_value": Decimal(parts["prev_read_value"]),
|
|
140
|
+
"prev_type_code": parts["prev_read_type"],
|
|
141
|
+
"pres_date": parse_date(parts["pres_read_date"]),
|
|
142
|
+
"pres_value": Decimal(parts["pres_read_value"]),
|
|
143
|
+
"pres_type_code": parts["pres_read_type"],
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _handle_0470(headers, pre_record, record):
|
|
149
|
+
pass
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _handle_1460(headers, pre_record, record):
|
|
153
|
+
parts = _chop_record(record, unknown_1=1, net=12, vat_rate=5, vat=12)
|
|
154
|
+
net = Decimal(parts["net"]) / Decimal(100)
|
|
155
|
+
vat_rate = int(Decimal(parts["vat_rate"]))
|
|
156
|
+
vat = Decimal(parts["vat"]) / Decimal(100)
|
|
157
|
+
|
|
158
|
+
vat_breakdown = headers["breakdown"]["vat"]
|
|
159
|
+
try:
|
|
160
|
+
vat_bd = vat_breakdown[vat_rate]
|
|
161
|
+
except KeyError:
|
|
162
|
+
vat_bd = vat_breakdown[vat_rate] = {"vat": Decimal("0"), "net": Decimal("0")}
|
|
163
|
+
|
|
164
|
+
vat_bd["vat"] += vat
|
|
165
|
+
vat_bd["net"] += net
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _handle_1500(headers, pre_record, record):
|
|
169
|
+
parts = _chop_record(
|
|
170
|
+
record,
|
|
171
|
+
unknown_1=8,
|
|
172
|
+
unknown_2=10,
|
|
173
|
+
net=10,
|
|
174
|
+
unknown_3=10,
|
|
175
|
+
unknown_4=20,
|
|
176
|
+
vat=10,
|
|
177
|
+
unknown_5=10,
|
|
178
|
+
unknown_6=20,
|
|
179
|
+
gross=12,
|
|
180
|
+
)
|
|
181
|
+
return {
|
|
182
|
+
"bill_type_code": "N",
|
|
183
|
+
"mpan_core": headers["mpan_core"],
|
|
184
|
+
"account": headers["account"],
|
|
185
|
+
"reference": headers["reference"],
|
|
186
|
+
"issue_date": headers["issue_date"],
|
|
187
|
+
"start_date": headers["start_date"],
|
|
188
|
+
"finish_date": headers["finish_date"],
|
|
189
|
+
"kwh": headers["kwh"],
|
|
190
|
+
"net": Decimal(parts["net"]),
|
|
191
|
+
"vat": Decimal(parts["vat"]),
|
|
192
|
+
"gross": Decimal(parts["gross"]),
|
|
193
|
+
"breakdown": headers["breakdown"],
|
|
194
|
+
"reads": headers["reads"],
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _handle_2000(headers, pre_record, record):
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def _handle_9999(headers, pre_record, record):
|
|
203
|
+
pass
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
LINE_HANDLERS = {
|
|
207
|
+
"0000": _handle_0000,
|
|
208
|
+
"0050": _handle_0050,
|
|
209
|
+
"0051": _handle_0051,
|
|
210
|
+
"0100": _handle_0100,
|
|
211
|
+
"0101": _handle_0101,
|
|
212
|
+
"0460": _handle_0460,
|
|
213
|
+
"0461": _handle_0461,
|
|
214
|
+
"0470": _handle_0470,
|
|
215
|
+
"1460": _handle_1460,
|
|
216
|
+
"1500": _handle_1500,
|
|
217
|
+
"2000": _handle_2000,
|
|
218
|
+
"9999": _handle_9999,
|
|
219
|
+
}
|
|
10
220
|
|
|
11
221
|
|
|
12
222
|
class Parser:
|
|
@@ -16,41 +226,28 @@ class Parser:
|
|
|
16
226
|
|
|
17
227
|
def make_raw_bills(self):
|
|
18
228
|
raw_bills = []
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
record_type = line[
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"account": account,
|
|
43
|
-
"reference": reference,
|
|
44
|
-
"issue_date": start_date,
|
|
45
|
-
"start_date": start_date,
|
|
46
|
-
"finish_date": finish_date,
|
|
47
|
-
"kwh": Decimal("0.00"),
|
|
48
|
-
"net": net,
|
|
49
|
-
"vat": vat,
|
|
50
|
-
"gross": Decimal("0.00"),
|
|
51
|
-
"breakdown": {},
|
|
52
|
-
"reads": [],
|
|
53
|
-
}
|
|
54
|
-
raw_bills.append(raw_bill)
|
|
229
|
+
headers = {}
|
|
230
|
+
for self.line_number, line in enumerate(self.f, 1):
|
|
231
|
+
pre_record, record_type, record = line[:80], line[80:84], line[84:]
|
|
232
|
+
try:
|
|
233
|
+
handler = LINE_HANDLERS[record_type]
|
|
234
|
+
except KeyError:
|
|
235
|
+
raise BadRequest(
|
|
236
|
+
f"Record type {record_type} not recognized on line "
|
|
237
|
+
f"{self.line_number} {line}"
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
bill = handler(headers, pre_record, record)
|
|
242
|
+
except BadRequest as e:
|
|
243
|
+
raise BadRequest(
|
|
244
|
+
f"Problem at line {self.line_number} {line}: {e.description}"
|
|
245
|
+
)
|
|
246
|
+
except BaseException as e:
|
|
247
|
+
raise Exception(
|
|
248
|
+
f"Problem at line {self.line_number} {line}: {e}"
|
|
249
|
+
) from e
|
|
250
|
+
if bill is not None:
|
|
251
|
+
raw_bills.append(bill)
|
|
55
252
|
|
|
56
253
|
return raw_bills
|
chellow/e/views.py
CHANGED
|
@@ -5252,6 +5252,10 @@ def supplier_bill_import_get(import_id):
|
|
|
5252
5252
|
fields["successful_max_registers"] = max(
|
|
5253
5253
|
len(bill["reads"]) for bill in imp_fields["successful_bills"]
|
|
5254
5254
|
)
|
|
5255
|
+
if "failed_bills" in imp_fields and len(imp_fields["failed_bills"]) > 0:
|
|
5256
|
+
fields["failed_max_registers"] = max(
|
|
5257
|
+
len(bill["reads"]) for bill in imp_fields["failed_bills"]
|
|
5258
|
+
)
|
|
5255
5259
|
fields.update(imp_fields)
|
|
5256
5260
|
fields["status"] = importer.status()
|
|
5257
5261
|
return render_template(
|
chellow/models.py
CHANGED
|
@@ -6400,8 +6400,23 @@ class ReportRun(Base, PersistentClass):
|
|
|
6400
6400
|
def insert(sess, name, user, title, data):
|
|
6401
6401
|
report_run = ReportRun(name, user, title, data)
|
|
6402
6402
|
sess.add(report_run)
|
|
6403
|
+
sess.flush()
|
|
6403
6404
|
return report_run
|
|
6404
6405
|
|
|
6406
|
+
@staticmethod
|
|
6407
|
+
def w_update(report_run_id, state):
|
|
6408
|
+
with Session() as wsess:
|
|
6409
|
+
report_run = ReportRun.get_by_id(wsess, report_run_id)
|
|
6410
|
+
report_run.update(state)
|
|
6411
|
+
wsess.commit()
|
|
6412
|
+
|
|
6413
|
+
@staticmethod
|
|
6414
|
+
def w_insert_row(report_run_id, tab, titles, values, properties):
|
|
6415
|
+
with Session() as wsess:
|
|
6416
|
+
report_run = ReportRun.get_by_id(wsess, report_run_id)
|
|
6417
|
+
report_run.insert_row(wsess, tab, titles, values, properties)
|
|
6418
|
+
wsess.commit()
|
|
6419
|
+
|
|
6405
6420
|
|
|
6406
6421
|
def _jsonize(val):
|
|
6407
6422
|
if isinstance(val, dict):
|
chellow/reports/report_111.py
CHANGED
|
@@ -29,9 +29,9 @@ from chellow.models import (
|
|
|
29
29
|
Llfc,
|
|
30
30
|
MarketRole,
|
|
31
31
|
MtcParticipant,
|
|
32
|
+
RSession,
|
|
32
33
|
RegisterRead,
|
|
33
34
|
ReportRun,
|
|
34
|
-
Session,
|
|
35
35
|
Site,
|
|
36
36
|
SiteEra,
|
|
37
37
|
Supply,
|
|
@@ -102,19 +102,17 @@ def content(
|
|
|
102
102
|
report_run_id,
|
|
103
103
|
):
|
|
104
104
|
caches = {}
|
|
105
|
-
tmp_file = sess = supply_id =
|
|
105
|
+
tmp_file = sess = supply_id = None
|
|
106
106
|
forecast_date = to_utc(Datetime.max)
|
|
107
107
|
|
|
108
108
|
try:
|
|
109
|
-
with
|
|
109
|
+
with RSession() as sess:
|
|
110
110
|
user = User.get_by_id(sess, user_id)
|
|
111
111
|
tmp_file = open_file(
|
|
112
112
|
f"bill_check_{fname_additional}.csv", user, mode="w", newline=""
|
|
113
113
|
)
|
|
114
114
|
writer = csv.writer(tmp_file, lineterminator="\n")
|
|
115
115
|
|
|
116
|
-
report_run = ReportRun.get_by_id(sess, report_run_id)
|
|
117
|
-
|
|
118
116
|
bills = (
|
|
119
117
|
sess.query(Bill)
|
|
120
118
|
.order_by(Bill.supply_id, Bill.reference)
|
|
@@ -216,30 +214,26 @@ def content(
|
|
|
216
214
|
virtual_bill_titles,
|
|
217
215
|
writer,
|
|
218
216
|
titles,
|
|
219
|
-
|
|
217
|
+
report_run_id,
|
|
220
218
|
)
|
|
221
|
-
|
|
222
|
-
report_run.update("finished")
|
|
223
|
-
sess.commit()
|
|
219
|
+
ReportRun.w_update(report_run_id, "finished")
|
|
224
220
|
|
|
225
221
|
except BadRequest as e:
|
|
226
|
-
if report_run is not None:
|
|
227
|
-
report_run.update("problem")
|
|
228
222
|
if supply_id is None:
|
|
229
223
|
prefix = "Problem: "
|
|
230
224
|
else:
|
|
231
225
|
prefix = f"Problem with supply {supply_id}:"
|
|
232
226
|
tmp_file.write(prefix + e.description)
|
|
227
|
+
ReportRun.w_update(report_run_id, "problem")
|
|
233
228
|
except BaseException:
|
|
234
|
-
|
|
235
|
-
|
|
229
|
+
msg = traceback.format_exc()
|
|
230
|
+
sys.stderr.write(msg + "\n")
|
|
236
231
|
if supply_id is None:
|
|
237
232
|
prefix = "Problem: "
|
|
238
233
|
else:
|
|
239
234
|
prefix = f"Problem with supply {supply_id}:"
|
|
240
|
-
msg = traceback.format_exc()
|
|
241
|
-
sys.stderr.write(msg + "\n")
|
|
242
235
|
tmp_file.write(prefix + msg)
|
|
236
|
+
ReportRun.w_update(report_run_id, "interrupted")
|
|
243
237
|
finally:
|
|
244
238
|
if tmp_file is not None:
|
|
245
239
|
tmp_file.close()
|
|
@@ -318,7 +312,7 @@ def _process_supply(
|
|
|
318
312
|
virtual_bill_titles,
|
|
319
313
|
writer,
|
|
320
314
|
titles,
|
|
321
|
-
|
|
315
|
+
report_run_id,
|
|
322
316
|
):
|
|
323
317
|
gaps = {}
|
|
324
318
|
data_sources = {}
|
|
@@ -761,8 +755,8 @@ def _process_supply(
|
|
|
761
755
|
values["batch_id"] = bill.batch.id
|
|
762
756
|
values["supply_id"] = supply.id
|
|
763
757
|
values["site_id"] = None if site_code is None else site.id
|
|
764
|
-
|
|
765
|
-
|
|
758
|
+
ReportRun.w_insert_row(
|
|
759
|
+
report_run_id, "", report_run_titles, values, {"is_checked": False}
|
|
766
760
|
)
|
|
767
761
|
|
|
768
762
|
for bill in sess.query(Bill).filter(
|
|
@@ -783,7 +777,7 @@ def _process_supply(
|
|
|
783
777
|
)
|
|
784
778
|
|
|
785
779
|
# Avoid long-running transactions
|
|
786
|
-
sess.
|
|
780
|
+
sess.rollback()
|
|
787
781
|
|
|
788
782
|
clumps = []
|
|
789
783
|
for element, elgap in sorted(gaps.items()):
|
|
@@ -837,7 +831,7 @@ def _process_supply(
|
|
|
837
831
|
vals["supply_id"] = supply.id
|
|
838
832
|
vals["site_id"] = None if site_code is None else site.id
|
|
839
833
|
|
|
840
|
-
|
|
834
|
+
ReportRun.w_insert_row(report_run_id, "", titles, vals, {"is_checked": False})
|
|
841
835
|
|
|
842
836
|
# Avoid long-running transactions
|
|
843
|
-
sess.
|
|
837
|
+
sess.rollback()
|
chellow/reports/report_387.py
CHANGED
|
@@ -10,7 +10,7 @@ from sqlalchemy.sql.expression import null, true
|
|
|
10
10
|
|
|
11
11
|
from chellow.dloads import open_file
|
|
12
12
|
from chellow.e.computer import SupplySource, forecast_date
|
|
13
|
-
from chellow.models import Era,
|
|
13
|
+
from chellow.models import Era, RSession, Site, SiteEra, Supply
|
|
14
14
|
from chellow.utils import (
|
|
15
15
|
csv_make_val,
|
|
16
16
|
hh_format,
|
|
@@ -25,7 +25,7 @@ def content(supply_id, start_date, finish_date, user):
|
|
|
25
25
|
caches = {}
|
|
26
26
|
f = None
|
|
27
27
|
try:
|
|
28
|
-
with
|
|
28
|
+
with RSession() as sess:
|
|
29
29
|
supply = Supply.get_by_id(sess, supply_id)
|
|
30
30
|
|
|
31
31
|
f_date = forecast_date()
|
|
@@ -50,7 +50,19 @@
|
|
|
50
50
|
<th>VAT</th>
|
|
51
51
|
<th>Gross</th>
|
|
52
52
|
<th>Breakdown</th>
|
|
53
|
-
|
|
53
|
+
{% for i in range(failed_max_registers) %}
|
|
54
|
+
<th>R{{loop.index}} MPAN</th>
|
|
55
|
+
<th>R{{loop.index}} Meter Serial Number</th>
|
|
56
|
+
<th>R{{loop.index}} Coefficient</th>
|
|
57
|
+
<th>R{{loop.index}} Units</th>
|
|
58
|
+
<th>R{{loop.index}} TPR</th>
|
|
59
|
+
<th>R{{loop.index}} Previous Read Date</th>
|
|
60
|
+
<th>R{{loop.index}} Previous Read Value</th>
|
|
61
|
+
<th>R{{loop.index}} Previous Read Type</th>
|
|
62
|
+
<th>R{{loop.index}} Present Read Date</th>
|
|
63
|
+
<th>R{{loop.index}} Present Read Value</th>
|
|
64
|
+
<th>R{{loop.index}} Present Read Type</th>
|
|
65
|
+
{% endfor %}
|
|
54
66
|
</tr>
|
|
55
67
|
</thead>
|
|
56
68
|
<tbody>
|
|
@@ -87,7 +99,19 @@
|
|
|
87
99
|
<pre>{{bill.breakdown|dumps}}</pre>
|
|
88
100
|
{% endif %}
|
|
89
101
|
</td>
|
|
90
|
-
|
|
102
|
+
{% for read in bill.reads %}
|
|
103
|
+
<td>{{read.mpan}}</td>
|
|
104
|
+
<td>{{read.msn}}</td>
|
|
105
|
+
<td>{{read.coefficient}}</td>
|
|
106
|
+
<td>{{read.units}}</td>
|
|
107
|
+
<td>{{read.tpr_code}}</td>
|
|
108
|
+
<td>{{read.prev_date|hh_format}}</td>
|
|
109
|
+
<td>{{read.prev_value}}</td>
|
|
110
|
+
<td>{{read.prev_type_code}}</td>
|
|
111
|
+
<td>{{read.pres_date|hh_format}}</td>
|
|
112
|
+
<td>{{read.pres_value}}</td>
|
|
113
|
+
<td>{{read.pres_type_code}}</td>
|
|
114
|
+
{% endfor %}
|
|
91
115
|
</tr>
|
|
92
116
|
{% endfor %}
|
|
93
117
|
</tbody>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: chellow
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1716564585.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)
|
|
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Requires-Python: >=3.9
|
|
10
10
|
Requires-Dist: flask-restx==1.2.0
|
|
11
11
|
Requires-Dist: flask==2.3.3
|
|
12
|
-
Requires-Dist: odio==0.0.
|
|
12
|
+
Requires-Dist: odio==0.0.23
|
|
13
13
|
Requires-Dist: openpyxl==3.1.2
|
|
14
14
|
Requires-Dist: paramiko==3.4.0
|
|
15
15
|
Requires-Dist: pep3143daemon==0.0.6
|
|
@@ -21,7 +21,7 @@ Requires-Dist: pypdf==3.17.0
|
|
|
21
21
|
Requires-Dist: python-dateutil==2.8.2
|
|
22
22
|
Requires-Dist: pytz==2022.6
|
|
23
23
|
Requires-Dist: requests==2.32.2
|
|
24
|
-
Requires-Dist: sqlalchemy==2.0.
|
|
24
|
+
Requires-Dist: sqlalchemy==2.0.30
|
|
25
25
|
Requires-Dist: waitress==2.1.2
|
|
26
26
|
Requires-Dist: xlrd==2.0.1
|
|
27
27
|
Requires-Dist: zish==0.1.11
|
|
@@ -5,7 +5,7 @@ chellow/commands.py,sha256=ESBe9ZWj1c3vdZgqMZ9gFvYAB3hRag2R1PzOwuw9yFo,1302
|
|
|
5
5
|
chellow/dloads.py,sha256=5SmP-0QPK6xCkd_wjIWh_8FAzN5OxNHCzyEQ1Xb-Y-M,5256
|
|
6
6
|
chellow/edi_lib.py,sha256=alu20x9ZX06iPfnNI9dEJzuP6RIf4We3Y_M_bl7RrcY,51789
|
|
7
7
|
chellow/general_import.py,sha256=l3EHq9zG9Vfl5Ee6XTVrC1nusXo4YGGB4VBmZ_JaJR8,65798
|
|
8
|
-
chellow/models.py,sha256=
|
|
8
|
+
chellow/models.py,sha256=uS4GHh4RF6yD7aSsN4nOC3hdNakHUjW1nVzrhM_79mQ,242736
|
|
9
9
|
chellow/national_grid.py,sha256=uxcv0qisHPyzw9AVIYPzsRqwt2XPAcZL-SBR12qcrS0,4364
|
|
10
10
|
chellow/proxy.py,sha256=cVXIktPlX3tQ1BYcwxq0nJXKE6r3DtFTtfFHPq55HaM,1351
|
|
11
11
|
chellow/rate_server.py,sha256=fg-Pf_9Hk3bXmC9riPQNGQxBvLvBa_WtNYdwDCjnCSg,5678
|
|
@@ -38,7 +38,7 @@ chellow/e/system_price.py,sha256=6w5J7bzwFAZubE2zdOFRiS8IIrVP8hkoIOaG2yCt-Ic,623
|
|
|
38
38
|
chellow/e/tlms.py,sha256=M33D6YpMixu2KkwSCzDRM3kThLgShg8exp63Obo75l8,8905
|
|
39
39
|
chellow/e/tnuos.py,sha256=XseYztPUsQXNKuBmystO2kzzwAG9ehCZgpGBTdgSk-A,4313
|
|
40
40
|
chellow/e/triad.py,sha256=lIQj7EdUrcFwEqleuHZXYU_bfzIwNOqUVVxB3NPQt4A,13710
|
|
41
|
-
chellow/e/views.py,sha256=
|
|
41
|
+
chellow/e/views.py,sha256=RQLiAzzWm5RUumvhR1rub1yFTMZ9uksqJIc1IShnXsQ,215256
|
|
42
42
|
chellow/e/bill_parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
43
|
chellow/e/bill_parsers/activity_mop_stark_xlsx.py,sha256=UgWXDPzQkQghyj_lfgBqoSJpHB-t-qOdSaB8qY6GLog,4071
|
|
44
44
|
chellow/e/bill_parsers/annual_mop_stark_xlsx.py,sha256=-HMoIfa_utXYKA44RuC0Xqv3vd2HLeQU_4P0iBUd3WA,4219
|
|
@@ -51,7 +51,7 @@ chellow/e/bill_parsers/gdf_csv.py,sha256=ZfK3Oc6oP28p_P9DIevLNB_zW2WLcEJ3Lvb1gL3
|
|
|
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
|
|
53
53
|
chellow/e/bill_parsers/haven_edi_tprs.py,sha256=ZVX9CCqUybsot_Z0BEOJPvl9x5kSr7fEWyuJXvZDcz4,11841
|
|
54
|
-
chellow/e/bill_parsers/mm.py,sha256=
|
|
54
|
+
chellow/e/bill_parsers/mm.py,sha256=b4Tzil_iXyKGvJSSbmMtBwH-4oiwIZthnvueU7CxNwg,6875
|
|
55
55
|
chellow/e/bill_parsers/nonsettlement_dc_stark_xlsx.py,sha256=yogXTuQHGRL7IiqvRWr2C9V24ez1j9Yx0128UygPE_k,4723
|
|
56
56
|
chellow/e/bill_parsers/settlement_dc_stark_xlsx.py,sha256=gKeYMdUO4bVycV8n1lWs5AIfF3bHZLkM6tkasD4rhHs,6239
|
|
57
57
|
chellow/e/bill_parsers/sse_edi.py,sha256=L85DOfNkqexeEIEr8pCBn_2sHJI-zEaw6cogpE3YyYM,15204
|
|
@@ -68,7 +68,7 @@ chellow/gas/transportation.py,sha256=Bkg8TWOs-v0ES-4qqwbleiOhqbE_t2KauUx9JYMZELM
|
|
|
68
68
|
chellow/gas/views.py,sha256=ZIMqByN0uBpf3y9wkMi-VogC1-NaHs-oO7WRVDk9Kkw,57428
|
|
69
69
|
chellow/reports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
70
70
|
chellow/reports/report_109.py,sha256=S8fsOwh-jVWGL0RsgyYLdqn00BAvlkBbi4VfTSGI-Mc,11181
|
|
71
|
-
chellow/reports/report_111.py,sha256=
|
|
71
|
+
chellow/reports/report_111.py,sha256=AlYjvCDpGNe1qBuzW52EONWDsFaIVElug0Vpe9qm1PY,28169
|
|
72
72
|
chellow/reports/report_169.py,sha256=tnTiHmhigcgZ7E8rUSfgzsVYUCW947xBZZq04-KqfK8,9287
|
|
73
73
|
chellow/reports/report_181.py,sha256=mCL6vXfrj8r0kL-LilDS0SnSu5tJOzCq7eMJVx9zpEw,4999
|
|
74
74
|
chellow/reports/report_183.py,sha256=DZX-hHJPl_Tbgkt31C_cuLZg_5L2b6iCPQ5foOZizR0,8817
|
|
@@ -81,7 +81,7 @@ chellow/reports/report_247.py,sha256=ozgCcee8XeqYbOpZCyU2STJKaz6h2x7TYQogagTaYLw
|
|
|
81
81
|
chellow/reports/report_29.py,sha256=KDFjgrLBv4WbG9efCdu_geMR7gT_QV9N97Wfdt7aDc4,2736
|
|
82
82
|
chellow/reports/report_291.py,sha256=rqBXy6s7hMeYWw-yNX6w_L5t2yz6rNEeos_4xO7wf90,7519
|
|
83
83
|
chellow/reports/report_33.py,sha256=laVz-itDbJTdvC6LxLEeuY0eKpYx43Un4adiExPTEEE,16730
|
|
84
|
-
chellow/reports/report_387.py,sha256=
|
|
84
|
+
chellow/reports/report_387.py,sha256=kmBZopb0AOivcowO2nPjRj6LnV0_QjCDXLwqPL7IGVE,5672
|
|
85
85
|
chellow/reports/report_41.py,sha256=QQeTshA1Og7N3wPaoZ8ynJzwsvZ1mgSFc7DDkVqIZoM,7447
|
|
86
86
|
chellow/reports/report_429.py,sha256=0GCc0rQnOSG0fusw69yMMOCxnWApBd3P2sGWIg1py9M,12359
|
|
87
87
|
chellow/reports/report_59.py,sha256=CCFPUspUFgoMt6sMFsdtLYW-inA9rN6D-6Kted6vskA,45458
|
|
@@ -299,7 +299,7 @@ chellow/templates/e/supplier_batches.html,sha256=ij8LuHc2HzxovBn34aHCMra4pm3Himk
|
|
|
299
299
|
chellow/templates/e/supplier_bill.html,sha256=7q79XfUSFPLR5npIXhRpTciQ9rGtNHhp9ryFZWXBhPc,4142
|
|
300
300
|
chellow/templates/e/supplier_bill_add.html,sha256=BsD-Zh7d9auiqJ61VPHiQrP8u8rTcw09mEKuKH9dxaA,2100
|
|
301
301
|
chellow/templates/e/supplier_bill_edit.html,sha256=oxZrMcMwrvluJSPxD4yfM9mWNeugoguAwT_ai9Ynl88,2732
|
|
302
|
-
chellow/templates/e/supplier_bill_import.html,sha256=
|
|
302
|
+
chellow/templates/e/supplier_bill_import.html,sha256=2_VvBoNE838UwuN0AiMwIrzqxQmWBo5DGY0lY833Bpk,5265
|
|
303
303
|
chellow/templates/e/supplier_bill_imports.html,sha256=9iTNGWKn9XjQTBP1Sepbo0QVNlgKh7EfizXapam7I6s,9356
|
|
304
304
|
chellow/templates/e/supplier_contract.html,sha256=oVGrYGIbCb-7MmpFQaXeTNRKBKy8GoGCWICWgo5E4xI,2863
|
|
305
305
|
chellow/templates/e/supplier_contract_add.html,sha256=gsozEtF24lzYi_Bb4LTenvh62tCt7dQ4CwaIz7rFck4,899
|
|
@@ -364,6 +364,6 @@ chellow/templates/g/supply_note_edit.html,sha256=6UQf_qbhFDys3cVsTp-c7ABWZpggW9R
|
|
|
364
364
|
chellow/templates/g/supply_notes.html,sha256=WR3YwGh_qqTklSJ7JqWX6BKBc9rk_jMff4RiWZiF2CM,936
|
|
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-1716564585.0.0.dist-info/METADATA,sha256=xaQbUGAclcjTkpSWGRS8X8pIe8pSo17WT6dFKZX4nwE,12205
|
|
368
|
+
chellow-1716564585.0.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
|
369
|
+
chellow-1716564585.0.0.dist-info/RECORD,,
|
|
File without changes
|