chellow 1722002880.0.0__py3-none-any.whl → 1723041465.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.

@@ -0,0 +1,217 @@
1
+ from datetime import datetime as Datetime
2
+ from decimal import Decimal, InvalidOperation
3
+
4
+ from dateutil.relativedelta import relativedelta
5
+
6
+ from openpyxl import load_workbook
7
+
8
+ from werkzeug.exceptions import BadRequest
9
+
10
+ from chellow.utils import HH, ct_datetime, parse_mpan_core, to_ct, to_utc
11
+
12
+
13
+ def get_cell(sheet, col, row):
14
+ try:
15
+ coordinates = f"{col}{row}"
16
+ return sheet[coordinates]
17
+ except IndexError:
18
+ raise BadRequest(f"Can't find the cell {coordinates} on sheet {sheet}.")
19
+
20
+
21
+ def get_date(sheet, col, row):
22
+ cell = get_cell(sheet, col, row)
23
+ val = cell.value
24
+ if not isinstance(val, Datetime):
25
+ raise BadRequest(
26
+ f"Problem reading {val} (of type {type(val)}) as a timestamp at "
27
+ f"{cell.coordinate}."
28
+ )
29
+ return val
30
+
31
+
32
+ def get_str(sheet, col, row):
33
+ return get_cell(sheet, col, row).value.strip()
34
+
35
+
36
+ def get_dec(sheet, col, row):
37
+ cell = get_cell(sheet, col, row)
38
+ try:
39
+ return Decimal(str(cell.value))
40
+ except InvalidOperation as e:
41
+ raise BadRequest(f"Problem parsing the number at {cell.coordinate}. {e}")
42
+
43
+
44
+ def get_int(sheet, col, row):
45
+ return int(get_cell(sheet, col, row).value)
46
+
47
+
48
+ ELEM_LOOKUP = {
49
+ "Capacity": {
50
+ "name": "duos-availability",
51
+ "gbp": "duos-availability-gbp",
52
+ "units": "duos-availability-kva",
53
+ "rate": "duos-availability-rate",
54
+ },
55
+ "Fixed Charge": {
56
+ "name": "duos-fixed",
57
+ "gbp": "duos-fixed-gbp",
58
+ "units": "duos-fixed-days",
59
+ "rate": "duos-fixed-rate",
60
+ },
61
+ "Unit Rate Zero": None,
62
+ "Excess Reactive Power": {
63
+ "name": "duos-reactive",
64
+ "gbp": "duos-reactive-gbp",
65
+ "units": "duos-reactive-kvarh",
66
+ "rate": "duos-reactive-gbp-per-kvarh",
67
+ },
68
+ "Unit Rate Amber": {
69
+ "name": "duos-amber",
70
+ "gbp": "duos-amber-gbp",
71
+ "units": "duos-amber-kwh",
72
+ "rate": "duos-amber-gbp-per-kwh",
73
+ },
74
+ "Unit Rate Green": {
75
+ "name": "duos-green",
76
+ "gbp": "duos-green-gbp",
77
+ "units": "duos-green-kwh",
78
+ "rate": "duos-green-gbp-per-kwh",
79
+ },
80
+ "Unit Rate Red": {
81
+ "name": "duos-red",
82
+ "gbp": "duos-red-gbp",
83
+ "units": "duos-red-kwh",
84
+ "rate": "duos-red-gbp-per-kwh",
85
+ },
86
+ }
87
+
88
+
89
+ def _make_raw_bills(book):
90
+ bills = []
91
+ sheet = book.worksheets[0]
92
+ issue_date_raw = get_date(sheet, "H", 24)
93
+ issue_date = to_utc(
94
+ ct_datetime(issue_date_raw.year, issue_date_raw.month, issue_date_raw.day)
95
+ )
96
+
97
+ mpan_core = parse_mpan_core(str(get_int(sheet, "D", 25)))
98
+ start_date_str = get_str(sheet, "D", 22)
99
+ start_date_ct = to_ct(Datetime.strptime(start_date_str, "%d-%b-%Y"))
100
+ start_date = to_utc(start_date_ct)
101
+ finish_date_str = get_str(sheet, "F", 22)
102
+ finish_date_ct = to_ct(Datetime.strptime(finish_date_str, "%d-%b-%Y"))
103
+ finish_date = to_utc(finish_date_ct + relativedelta(hours=23, minutes=30))
104
+ net = round(get_dec(sheet, "H", 33), 2)
105
+ kwh = get_dec(sheet, "D", 33)
106
+
107
+ breakdown = {
108
+ "ssp-kwh": kwh,
109
+ "ssp-gbp": net,
110
+ }
111
+
112
+ bills.append(
113
+ {
114
+ "bill_type_code": "N",
115
+ "kwh": kwh,
116
+ "vat": Decimal("0.00"),
117
+ "net": net,
118
+ "gross": net,
119
+ "reads": [],
120
+ "breakdown": breakdown,
121
+ "account": mpan_core,
122
+ "issue_date": issue_date,
123
+ "start_date": start_date,
124
+ "finish_date": finish_date,
125
+ "mpan_core": mpan_core,
126
+ "reference": "_".join(
127
+ (
128
+ to_ct(start_date).strftime("%Y%m%d"),
129
+ to_ct(finish_date).strftime("%Y%m%d"),
130
+ to_ct(issue_date).strftime("%Y%m%d"),
131
+ mpan_core,
132
+ "ssp",
133
+ )
134
+ ),
135
+ }
136
+ )
137
+ sheet = book.worksheets[3]
138
+ for row in range(2, len(sheet["A"]) + 1):
139
+ val = get_cell(sheet, "A", row).value
140
+ if val is None or val == "":
141
+ break
142
+
143
+ start_date_str = get_str(sheet, "B", row)
144
+ start_date_ct = to_ct(Datetime.strptime(start_date_str, "%Y-%m"))
145
+ start_date = to_utc(start_date_ct)
146
+ finish_date = to_utc(start_date_ct + relativedelta(months=1) - HH)
147
+
148
+ element_desc = get_str(sheet, "D", row).strip()
149
+ units = get_dec(sheet, "E", row)
150
+ rate = get_dec(sheet, "F", row)
151
+ net = round(get_dec(sheet, "G", row), 2)
152
+
153
+ titles = ELEM_LOOKUP[element_desc]
154
+ if titles is None:
155
+ continue
156
+
157
+ breakdown = {
158
+ titles["gbp"]: net,
159
+ titles["units"]: units,
160
+ titles["rate"]: [rate],
161
+ }
162
+
163
+ bills.append(
164
+ {
165
+ "bill_type_code": "N",
166
+ "kwh": Decimal(0),
167
+ "vat": Decimal("0.00"),
168
+ "net": net,
169
+ "gross": net,
170
+ "reads": [],
171
+ "breakdown": breakdown,
172
+ "account": mpan_core,
173
+ "issue_date": issue_date,
174
+ "start_date": start_date,
175
+ "finish_date": finish_date,
176
+ "mpan_core": mpan_core,
177
+ "reference": "_".join(
178
+ (
179
+ to_ct(start_date).strftime("%Y%m%d"),
180
+ to_ct(finish_date).strftime("%Y%m%d"),
181
+ to_ct(issue_date).strftime("%Y%m%d"),
182
+ mpan_core,
183
+ titles["name"],
184
+ )
185
+ ),
186
+ }
187
+ )
188
+ return bills
189
+
190
+
191
+ class Parser:
192
+ def __init__(self, f):
193
+ self.book = load_workbook(f, data_only=True)
194
+
195
+ self.last_line = None
196
+ self._line_number = None
197
+ self._title_line = None
198
+
199
+ @property
200
+ def line_number(self):
201
+ return None if self._line_number is None else self._line_number + 1
202
+
203
+ def _set_last_line(self, i, line):
204
+ self._line_number = i
205
+ self.last_line = line
206
+ if i == 0:
207
+ self._title_line = line
208
+ return line
209
+
210
+ def make_raw_bills(self):
211
+ row = bills = None
212
+ try:
213
+ bills = _make_raw_bills(self.book)
214
+ except BadRequest as e:
215
+ raise BadRequest(f"Row number: {row} {e.description}")
216
+
217
+ return bills
@@ -80,6 +80,11 @@ CHARGE_UNITS_LOOKUP = {
80
80
  }
81
81
 
82
82
  ELEMENT_LOOKUP = {
83
+ "1ANNUAL": "duos-red",
84
+ "2ANNUAL": "duos-amber",
85
+ "3ANNUAL": "duos-green",
86
+ "7ANNUAL": "duos-fixed",
87
+ "9ANNUAL": "duos-reactive",
83
88
  "10ANNUAL": "standing",
84
89
  "20RS0108": "single",
85
90
  "30ANNUAL": "mop",
@@ -119,7 +124,7 @@ def _handle_0460(headers, pre_record, record):
119
124
  gbp = Decimal(parts["gbp"]) / 100
120
125
  quantity = Decimal(parts["quantity"])
121
126
  rate = Decimal(parts["rate"])
122
- element_name = ELEMENT_LOOKUP[parts["code"]]
127
+ element_name = ELEMENT_LOOKUP[parts["code"].strip()]
123
128
  breakdown = headers["breakdown"]
124
129
  breakdown[f"{element_name}-{units}"] += quantity
125
130
  rate_name = f"{element_name}-rate"
chellow/views.py CHANGED
@@ -1501,7 +1501,7 @@ def report_run_row_get(row_id):
1501
1501
  "virtual-problem",
1502
1502
  ):
1503
1503
  toks = t.split("-")
1504
- name = toks[1]
1504
+ name = "-".join(toks[1:-1])
1505
1505
  try:
1506
1506
  table = elements[name]
1507
1507
  except KeyError:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: chellow
3
- Version: 1722002880.0.0
3
+ Version: 1723041465.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)
@@ -11,7 +11,7 @@ chellow/proxy.py,sha256=cVXIktPlX3tQ1BYcwxq0nJXKE6r3DtFTtfFHPq55HaM,1351
11
11
  chellow/rate_server.py,sha256=fg-Pf_9Hk3bXmC9riPQNGQxBvLvBa_WtNYdwDCjnCSg,5678
12
12
  chellow/testing.py,sha256=Od4HHH6pZrhJ_De118_F55RJEKmAvhUH2S24QE9qFQk,3635
13
13
  chellow/utils.py,sha256=32qPWEGzCPKPhSM7ztpzcR6ZG74sVZanScDIdK50Rq4,19308
14
- chellow/views.py,sha256=eDvTQM_PUqRvrCQvBdlF5q7MEs7w2yJmRjcC8WDbHtE,79584
14
+ chellow/views.py,sha256=s_pKNpBkiegxevAWEjowJKAtUPXpowOTbXI5473em4Y,79597
15
15
  chellow/e/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  chellow/e/aahedc.py,sha256=d2usudp7KYWpU6Pk3fal5EQ47EbvkvKeaFGylnb3NWw,606
17
17
  chellow/e/bill_importer.py,sha256=7UcnqNlKbJc2GhW9gy8sDp9GuqambJVpZLvbafOZztA,7411
@@ -44,6 +44,7 @@ chellow/e/bill_parsers/activity_mop_stark_xlsx.py,sha256=UgWXDPzQkQghyj_lfgBqoSJ
44
44
  chellow/e/bill_parsers/annual_mop_stark_xlsx.py,sha256=-HMoIfa_utXYKA44RuC0Xqv3vd2HLeQU_4P0iBUd3WA,4219
45
45
  chellow/e/bill_parsers/bgb_edi.py,sha256=GuwHeYbAGk7BVg5n19FcTANFDyKI-y0z3f9niQaPSSw,4828
46
46
  chellow/e/bill_parsers/csv.py,sha256=U5zcIaZ6B5QTTpFDAcBnk4G2r8B3j5kJhDPL4AJNkEk,5640
47
+ chellow/e/bill_parsers/edf_export_xlsx.py,sha256=t-M9-dGNWXu3VDI1DbS5Ez1oHW33oopJryNgMTvTjys,6307
47
48
  chellow/e/bill_parsers/engie_edi.py,sha256=CTobTskDjzdcqqf_qk2ukDSaTLrVpGZMM0sYlwehog4,14985
48
49
  chellow/e/bill_parsers/engie_xls.py,sha256=jrut2heH_ZWmSjcn7celOydZS9Y49GfpYjDk_EKwamI,14453
49
50
  chellow/e/bill_parsers/engie_xlsx.py,sha256=4Hu3ls1uNMH7vjDHgcP6QARlGlvb616CqG3xZVjAKWo,16888
@@ -51,7 +52,7 @@ chellow/e/bill_parsers/gdf_csv.py,sha256=ZfK3Oc6oP28p_P9DIevLNB_zW2WLcEJ3Lvb1gL3
51
52
  chellow/e/bill_parsers/haven_csv.py,sha256=0uENq8IgVNqdxfBQMBxLTSZWCOuDHXZC0xzk52SbfyE,13652
52
53
  chellow/e/bill_parsers/haven_edi.py,sha256=YGPHRxPOhje9s32jqPHHELni2tooOYj3cMC_qaZVPq4,16107
53
54
  chellow/e/bill_parsers/haven_edi_tprs.py,sha256=ZVX9CCqUybsot_Z0BEOJPvl9x5kSr7fEWyuJXvZDcz4,11841
54
- chellow/e/bill_parsers/mm.py,sha256=0Ch-ngypH2X7eeEq5tDkaGQreCZUbjeDCmhbyGo2_vQ,9305
55
+ chellow/e/bill_parsers/mm.py,sha256=KhAwF8o3cdabTBmc2pbZgm9MlkAachwNsy4bsivTSrM,9459
55
56
  chellow/e/bill_parsers/nonsettlement_dc_stark_xlsx.py,sha256=yogXTuQHGRL7IiqvRWr2C9V24ez1j9Yx0128UygPE_k,4723
56
57
  chellow/e/bill_parsers/settlement_dc_stark_xlsx.py,sha256=PlEqCZuJ9DfQXeeYQ64jtf3ML7sUt_tt61QOOTnkE5c,6380
57
58
  chellow/e/bill_parsers/sse_edi.py,sha256=L85DOfNkqexeEIEr8pCBn_2sHJI-zEaw6cogpE3YyYM,15204
@@ -364,6 +365,6 @@ chellow/templates/g/supply_note_edit.html,sha256=b8mB6_ucBwoljp03iy6AgVaZUhGw3-1
364
365
  chellow/templates/g/supply_notes.html,sha256=6epNmZ3NKdXZz27fvmRUGeffg_oc1kmwuBeyRzQe3Rg,854
365
366
  chellow/templates/g/unit.html,sha256=KouNVU0-i84afANkLQ_heJ0uDfJ9H5A05PuLqb8iCN8,438
366
367
  chellow/templates/g/units.html,sha256=p5Nd-lAIboKPEOO6N451hx1bcKxMg4BDODnZ-43MmJc,441
367
- chellow-1722002880.0.0.dist-info/METADATA,sha256=oEvvu_5ycUK-OM8xM9AzvKRuCFxHnfIlR1Bl46mQGJ4,12241
368
- chellow-1722002880.0.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
369
- chellow-1722002880.0.0.dist-info/RECORD,,
368
+ chellow-1723041465.0.0.dist-info/METADATA,sha256=97E2o-6rhdaB00zicHeZC1x2945uPxYqRtm-K1m1uLo,12241
369
+ chellow-1723041465.0.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
370
+ chellow-1723041465.0.0.dist-info/RECORD,,