chellow 1729269304.0.0__py3-none-any.whl → 1729760318.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/hh_importer.py +9 -1
- chellow/e/hh_parser_schneider_csv.py +75 -0
- chellow/e/hh_parser_schneider_xlsx.py +118 -0
- chellow/e/views.py +2 -140
- chellow/reports/report_g_monthly_duration.py +234 -153
- chellow/templates/base.html +1 -1
- chellow/templates/e/channel_snags.html +1 -1
- chellow/templates/home.html +1 -1
- chellow/templates/scenario.html +61 -0
- chellow/templates/scenario_add.html +21 -0
- chellow/templates/scenario_docs.html +256 -0
- chellow/templates/scenario_edit.html +35 -0
- chellow/templates/scenarios.html +39 -0
- chellow/views.py +140 -0
- {chellow-1729269304.0.0.dist-info → chellow-1729760318.0.0.dist-info}/METADATA +1 -1
- {chellow-1729269304.0.0.dist-info → chellow-1729760318.0.0.dist-info}/RECORD +17 -10
- {chellow-1729269304.0.0.dist-info → chellow-1729760318.0.0.dist-info}/WHEEL +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import sys
|
|
2
1
|
import threading
|
|
3
2
|
import traceback
|
|
4
3
|
|
|
@@ -14,34 +13,36 @@ from werkzeug.exceptions import BadRequest
|
|
|
14
13
|
|
|
15
14
|
import chellow.e.computer
|
|
16
15
|
from chellow.dloads import open_file
|
|
17
|
-
from chellow.e.computer import contract_func
|
|
16
|
+
from chellow.e.computer import contract_func, forecast_date
|
|
18
17
|
from chellow.gas.engine import GDataSource
|
|
19
18
|
from chellow.models import (
|
|
20
19
|
GBill,
|
|
21
20
|
GContract,
|
|
22
21
|
GEra,
|
|
23
22
|
GSupply,
|
|
24
|
-
|
|
23
|
+
RSession,
|
|
24
|
+
ReportRun,
|
|
25
|
+
Scenario,
|
|
25
26
|
Site,
|
|
26
27
|
SiteGEra,
|
|
28
|
+
User,
|
|
27
29
|
)
|
|
28
30
|
from chellow.utils import (
|
|
31
|
+
c_months_c,
|
|
29
32
|
c_months_u,
|
|
30
|
-
ct_datetime_now,
|
|
31
33
|
hh_format,
|
|
32
34
|
hh_max,
|
|
33
35
|
hh_min,
|
|
34
36
|
make_val,
|
|
35
37
|
req_bool,
|
|
36
38
|
req_int,
|
|
39
|
+
req_str,
|
|
40
|
+
to_utc,
|
|
41
|
+
utc_datetime_now,
|
|
37
42
|
)
|
|
38
43
|
from chellow.views import chellow_redirect
|
|
39
44
|
|
|
40
45
|
|
|
41
|
-
CATEGORY_ORDER = {None: 0, "unmetered": 1, "nhh": 2, "amr": 3, "hh": 4}
|
|
42
|
-
meter_order = {"hh": 0, "amr": 1, "nhh": 2, "unmetered": 3}
|
|
43
|
-
|
|
44
|
-
|
|
45
46
|
def write_spreadsheet(fl, compressed, site_rows, era_rows):
|
|
46
47
|
fl.seek(0)
|
|
47
48
|
fl.truncate()
|
|
@@ -61,6 +62,7 @@ def _process_era(
|
|
|
61
62
|
g_era_rows,
|
|
62
63
|
vb_titles,
|
|
63
64
|
now,
|
|
65
|
+
summary_titles,
|
|
64
66
|
):
|
|
65
67
|
g_supply = g_era.g_supply
|
|
66
68
|
|
|
@@ -91,28 +93,30 @@ def _process_era(
|
|
|
91
93
|
f"Problem with virtual bill for g_supplier_contrat {contract.id}."
|
|
92
94
|
) from e
|
|
93
95
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
96
|
+
summary_data = {
|
|
97
|
+
"kwh": 0,
|
|
98
|
+
"net_gbp": 0,
|
|
99
|
+
"vat_gbp": 0,
|
|
100
|
+
"gross_gbp": 0,
|
|
101
|
+
"billed_kwh": 0,
|
|
102
|
+
"billed_net_gbp": 0,
|
|
103
|
+
"billed_vat_gbp": 0,
|
|
104
|
+
"billed_gross_gbp": 0,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for key in ("kwh", "net_gbp", "vat_gbp", "gross_gbp"):
|
|
108
|
+
try:
|
|
109
|
+
summary_data[key] += bill[key]
|
|
110
|
+
except KeyError:
|
|
111
|
+
bill["problem"] += (
|
|
112
|
+
f"For the supply {ss.mprn} the virtual bill {bill} "
|
|
113
|
+
f"from the contract {contract.name} does not contain "
|
|
114
|
+
f"the {key} key."
|
|
115
|
+
)
|
|
114
116
|
|
|
115
|
-
|
|
117
|
+
associated_site_codes = {
|
|
118
|
+
s.site.code for s in g_era.site_g_eras if not s.is_physical
|
|
119
|
+
}
|
|
116
120
|
|
|
117
121
|
for g_bill in sess.query(GBill).filter(
|
|
118
122
|
GBill.g_supply == g_supply,
|
|
@@ -126,13 +130,12 @@ def _process_era(
|
|
|
126
130
|
min(bill_finish, ss_finish) - max(bill_start, ss_start)
|
|
127
131
|
).total_seconds() + (30 * 60)
|
|
128
132
|
overlap_proportion = overlap_duration / bill_duration
|
|
129
|
-
billed_kwh += overlap_proportion * float(g_bill.kwh)
|
|
130
|
-
billed_net_gbp += overlap_proportion * float(g_bill.net)
|
|
131
|
-
billed_vat_gbp += overlap_proportion * float(g_bill.vat)
|
|
132
|
-
billed_gross_gbp += overlap_proportion * float(g_bill.gross)
|
|
133
|
+
summary_data["billed_kwh"] += overlap_proportion * float(g_bill.kwh)
|
|
134
|
+
summary_data["billed_net_gbp"] += overlap_proportion * float(g_bill.net)
|
|
135
|
+
summary_data["billed_vat_gbp"] += overlap_proportion * float(g_bill.vat)
|
|
136
|
+
summary_data["billed_gross_gbp"] += overlap_proportion * float(g_bill.gross)
|
|
133
137
|
|
|
134
|
-
|
|
135
|
-
g_era_rows.append(
|
|
138
|
+
g_era_row = (
|
|
136
139
|
[
|
|
137
140
|
make_val(v)
|
|
138
141
|
for v in [
|
|
@@ -145,71 +148,117 @@ def _process_era(
|
|
|
145
148
|
contract.name,
|
|
146
149
|
site.code,
|
|
147
150
|
site.name,
|
|
148
|
-
|
|
151
|
+
associated_site_codes,
|
|
149
152
|
g_era.start_date,
|
|
150
153
|
month_finish,
|
|
151
|
-
kwh,
|
|
152
|
-
gbp,
|
|
153
|
-
billed_kwh,
|
|
154
|
-
billed_net_gbp,
|
|
155
|
-
billed_vat_gbp,
|
|
156
|
-
billed_gross_gbp,
|
|
157
154
|
]
|
|
158
155
|
]
|
|
156
|
+
+ [make_val(summary_data[t]) for t in summary_titles]
|
|
159
157
|
+ [make_val(bill.get(t)) for t in vb_titles]
|
|
160
158
|
)
|
|
161
|
-
|
|
159
|
+
g_era_rows.append(g_era_row)
|
|
160
|
+
return summary_data
|
|
162
161
|
|
|
163
162
|
|
|
164
|
-
def content(
|
|
165
|
-
site_id, g_supply_id, user, compression, finish_year, finish_month, months, now=None
|
|
166
|
-
):
|
|
167
|
-
if now is None:
|
|
168
|
-
now = ct_datetime_now()
|
|
163
|
+
def content(scenario_props, user_id, compression, now, base_name):
|
|
169
164
|
report_context = {}
|
|
170
|
-
month_list = list(
|
|
171
|
-
c_months_u(finish_year=finish_year, finish_month=finish_month, months=months)
|
|
172
|
-
)
|
|
173
|
-
start_date, finish_date = month_list[0][0], month_list[-1][-1]
|
|
174
|
-
|
|
175
165
|
try:
|
|
176
|
-
with
|
|
177
|
-
|
|
178
|
-
|
|
166
|
+
with RSession() as sess:
|
|
167
|
+
start_year = scenario_props["scenario_start_year"]
|
|
168
|
+
start_month = scenario_props["scenario_start_month"]
|
|
169
|
+
months = scenario_props["scenario_duration"]
|
|
170
|
+
|
|
171
|
+
month_pairs = list(
|
|
172
|
+
c_months_u(
|
|
173
|
+
start_year=start_year, start_month=start_month, months=months
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
start_date = month_pairs[0][0]
|
|
177
|
+
finish_date = month_pairs[-1][-1]
|
|
178
|
+
|
|
179
|
+
base_name.append(
|
|
179
180
|
hh_format(start_date)
|
|
180
181
|
.replace(" ", "_")
|
|
181
182
|
.replace(":", "")
|
|
182
|
-
.replace("-", "")
|
|
183
|
-
|
|
184
|
-
str(months),
|
|
185
|
-
"months",
|
|
186
|
-
]
|
|
183
|
+
.replace("-", "")
|
|
184
|
+
)
|
|
187
185
|
|
|
188
|
-
|
|
186
|
+
base_name.append("for")
|
|
187
|
+
base_name.append(str(months))
|
|
188
|
+
base_name.append("months")
|
|
189
|
+
|
|
190
|
+
if "forecast_from" in scenario_props:
|
|
191
|
+
forecast_from = scenario_props["forecast_from"]
|
|
192
|
+
else:
|
|
193
|
+
forecast_from = None
|
|
194
|
+
|
|
195
|
+
if forecast_from is None:
|
|
196
|
+
forecast_from = forecast_date()
|
|
197
|
+
else:
|
|
198
|
+
forecast_from = to_utc(forecast_from)
|
|
199
|
+
|
|
200
|
+
sites = sess.query(Site).distinct().order_by(Site.code)
|
|
201
|
+
|
|
202
|
+
mprns = scenario_props.get("mprns")
|
|
203
|
+
g_supply_ids = None
|
|
204
|
+
if mprns is not None:
|
|
205
|
+
g_supply_ids = []
|
|
206
|
+
for mprn in mprns:
|
|
207
|
+
g_supply = GSupply.get_by_mprn(sess, mprn)
|
|
208
|
+
g_supply_ids.append(g_supply.id)
|
|
209
|
+
|
|
210
|
+
if len(g_supply_ids) == 1:
|
|
211
|
+
base_name.append("g_supply")
|
|
212
|
+
base_name.append(str(g_supply.id))
|
|
213
|
+
else:
|
|
214
|
+
base_name.append("mprns")
|
|
215
|
+
|
|
216
|
+
sites = (
|
|
217
|
+
sites.join(SiteGEra)
|
|
218
|
+
.join(GEra)
|
|
219
|
+
.join(GSupply)
|
|
220
|
+
.where(GSupply.id.in_(g_supply_ids))
|
|
221
|
+
)
|
|
189
222
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if g_supply_id is not None:
|
|
204
|
-
g_supply = GSupply.get_by_id(sess, g_supply_id)
|
|
205
|
-
base_name.append("g_supply")
|
|
206
|
-
base_name.append(str(g_supply.id))
|
|
207
|
-
sites = sites.filter(GEra.g_supply == g_supply)
|
|
208
|
-
|
|
209
|
-
rf = open_file("_".join(base_name) + ".ods", user, mode="wb")
|
|
223
|
+
site_codes = scenario_props.get("site_codes")
|
|
224
|
+
if site_codes is not None:
|
|
225
|
+
if len(site_codes) == 1:
|
|
226
|
+
base_name.append("site")
|
|
227
|
+
base_name.append(site_codes[0])
|
|
228
|
+
else:
|
|
229
|
+
base_name.append("sitecodes")
|
|
230
|
+
sites = sites.where(Site.code.in_(site_codes))
|
|
231
|
+
|
|
232
|
+
user = User.get_by_id(sess, user_id)
|
|
233
|
+
fname = "_".join(base_name) + ".ods"
|
|
234
|
+
rf = open_file(fname, user, mode="wb")
|
|
235
|
+
org_rows = []
|
|
210
236
|
site_rows = []
|
|
211
237
|
g_era_rows = []
|
|
212
238
|
|
|
239
|
+
org_header_titles = [
|
|
240
|
+
"creation_date",
|
|
241
|
+
"month",
|
|
242
|
+
]
|
|
243
|
+
summary_titles = [
|
|
244
|
+
"kwh",
|
|
245
|
+
"net_gbp",
|
|
246
|
+
"vat_gbp",
|
|
247
|
+
"gross_gbp",
|
|
248
|
+
"billed_kwh",
|
|
249
|
+
"billed_net_gbp",
|
|
250
|
+
"billed_vat_gbp",
|
|
251
|
+
"billed_gross_gbp",
|
|
252
|
+
]
|
|
253
|
+
org_titles = org_header_titles + summary_titles
|
|
254
|
+
site_header_titles = [
|
|
255
|
+
"creation_date",
|
|
256
|
+
"site_code",
|
|
257
|
+
"site_name",
|
|
258
|
+
"associated_site_codes",
|
|
259
|
+
"month",
|
|
260
|
+
]
|
|
261
|
+
site_titles = site_header_titles + summary_titles
|
|
213
262
|
era_header_titles = [
|
|
214
263
|
"creation_date",
|
|
215
264
|
"mprn",
|
|
@@ -218,27 +267,12 @@ def content(
|
|
|
218
267
|
"msn",
|
|
219
268
|
"unit",
|
|
220
269
|
"contract",
|
|
221
|
-
"
|
|
270
|
+
"site_code",
|
|
222
271
|
"site_name",
|
|
223
|
-
"
|
|
272
|
+
"associated_site_codes",
|
|
224
273
|
"era-start",
|
|
225
274
|
"month",
|
|
226
275
|
]
|
|
227
|
-
site_header_titles = [
|
|
228
|
-
"creation_date",
|
|
229
|
-
"site_id",
|
|
230
|
-
"site_name",
|
|
231
|
-
"associated_site_ids",
|
|
232
|
-
"month",
|
|
233
|
-
]
|
|
234
|
-
summary_titles = [
|
|
235
|
-
"kwh",
|
|
236
|
-
"gbp",
|
|
237
|
-
"billed_kwh",
|
|
238
|
-
"billed_net_gbp",
|
|
239
|
-
"billed_vat_gbp",
|
|
240
|
-
"billed_gross_gbp",
|
|
241
|
-
]
|
|
242
276
|
|
|
243
277
|
vb_titles = []
|
|
244
278
|
conts = (
|
|
@@ -252,8 +286,8 @@ def content(
|
|
|
252
286
|
.distinct()
|
|
253
287
|
.order_by(GContract.id)
|
|
254
288
|
)
|
|
255
|
-
if
|
|
256
|
-
conts = conts.
|
|
289
|
+
if g_supply_ids is not None:
|
|
290
|
+
conts = conts.where(GEra.g_supply_id.in_(g_supply_ids))
|
|
257
291
|
for cont in conts:
|
|
258
292
|
title_func = chellow.e.computer.contract_func(
|
|
259
293
|
report_context, cont, "virtual_bill_titles"
|
|
@@ -267,16 +301,47 @@ def content(
|
|
|
267
301
|
if title not in vb_titles:
|
|
268
302
|
vb_titles.append(title)
|
|
269
303
|
|
|
270
|
-
|
|
304
|
+
org_rows.append(org_header_titles + summary_titles)
|
|
271
305
|
site_rows.append(site_header_titles + summary_titles)
|
|
306
|
+
g_era_rows.append(era_header_titles + summary_titles + vb_titles)
|
|
272
307
|
|
|
273
|
-
for month_start, month_finish in
|
|
308
|
+
for month_start, month_finish in month_pairs:
|
|
309
|
+
org_row = {
|
|
310
|
+
"creation_date": now,
|
|
311
|
+
"month": month_start,
|
|
312
|
+
"kwh": 0,
|
|
313
|
+
"net_gbp": 0,
|
|
314
|
+
"vat_gbp": 0,
|
|
315
|
+
"gross_gbp": 0,
|
|
316
|
+
"billed_kwh": 0,
|
|
317
|
+
"billed_net_gbp": 0,
|
|
318
|
+
"billed_vat_gbp": 0,
|
|
319
|
+
"billed_gross_gbp": 0,
|
|
320
|
+
}
|
|
274
321
|
for site in sites.filter(
|
|
275
322
|
GEra.start_date <= month_finish,
|
|
276
323
|
or_(GEra.finish_date == null(), GEra.finish_date >= month_start),
|
|
277
324
|
):
|
|
278
|
-
|
|
279
|
-
|
|
325
|
+
linked_sites = {
|
|
326
|
+
s.code
|
|
327
|
+
for s in site.find_linked_sites(sess, month_start, month_finish)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
site_row = {
|
|
331
|
+
"creation_date": now,
|
|
332
|
+
"site_code": site.code,
|
|
333
|
+
"site_name": site.name,
|
|
334
|
+
"associated_site_codes": linked_sites,
|
|
335
|
+
"month": month_finish,
|
|
336
|
+
"kwh": 0,
|
|
337
|
+
"net_gbp": 0,
|
|
338
|
+
"vat_gbp": 0,
|
|
339
|
+
"gross_gbp": 0,
|
|
340
|
+
"billed_kwh": 0,
|
|
341
|
+
"billed_net_gbp": 0,
|
|
342
|
+
"billed_vat_gbp": 0,
|
|
343
|
+
"billed_gross_gbp": 0,
|
|
344
|
+
}
|
|
280
345
|
|
|
281
346
|
g_eras_q = (
|
|
282
347
|
select(GEra)
|
|
@@ -297,19 +362,12 @@ def content(
|
|
|
297
362
|
)
|
|
298
363
|
.order_by(GEra.id)
|
|
299
364
|
)
|
|
300
|
-
if
|
|
301
|
-
g_eras_q = g_eras_q.where(GEra.g_supply_id
|
|
365
|
+
if g_supply_ids is not None:
|
|
366
|
+
g_eras_q = g_eras_q.where(GEra.g_supply_id.in_(g_supply_ids))
|
|
302
367
|
|
|
303
368
|
for g_era in sess.scalars(g_eras_q):
|
|
304
369
|
try:
|
|
305
|
-
(
|
|
306
|
-
kwh,
|
|
307
|
-
gbp,
|
|
308
|
-
billed_kwh,
|
|
309
|
-
billed_net_gbp,
|
|
310
|
-
billed_vat_gbp,
|
|
311
|
-
billed_gross_gbp,
|
|
312
|
-
) = _process_era(
|
|
370
|
+
summary_data = _process_era(
|
|
313
371
|
report_context,
|
|
314
372
|
sess,
|
|
315
373
|
site,
|
|
@@ -320,47 +378,39 @@ def content(
|
|
|
320
378
|
g_era_rows,
|
|
321
379
|
vb_titles,
|
|
322
380
|
now,
|
|
381
|
+
summary_titles,
|
|
323
382
|
)
|
|
324
|
-
site_kwh += kwh
|
|
325
|
-
site_gbp += gbp
|
|
326
|
-
site_billed_kwh += billed_kwh
|
|
327
|
-
site_billed_net_gbp += billed_net_gbp
|
|
328
|
-
site_billed_vat_gbp += billed_vat_gbp
|
|
329
|
-
site_billed_gross_gbp += billed_gross_gbp
|
|
330
383
|
except BadRequest as e:
|
|
331
384
|
raise BadRequest(
|
|
332
385
|
f"Problem with g_era {g_era.id}: {e.description}"
|
|
333
386
|
)
|
|
387
|
+
for k, v in summary_data.items():
|
|
388
|
+
org_row[k] += v
|
|
389
|
+
site_row[k] += v
|
|
334
390
|
|
|
335
|
-
|
|
336
|
-
s.code
|
|
337
|
-
for s in site.find_linked_sites(sess, month_start, month_finish)
|
|
338
|
-
)
|
|
339
|
-
|
|
340
|
-
site_rows.append(
|
|
341
|
-
[
|
|
342
|
-
make_val(v)
|
|
343
|
-
for v in [
|
|
344
|
-
now,
|
|
345
|
-
site.code,
|
|
346
|
-
site.name,
|
|
347
|
-
linked_sites,
|
|
348
|
-
month_finish,
|
|
349
|
-
site_kwh,
|
|
350
|
-
site_gbp,
|
|
351
|
-
site_billed_kwh,
|
|
352
|
-
site_billed_net_gbp,
|
|
353
|
-
site_billed_vat_gbp,
|
|
354
|
-
site_billed_gross_gbp,
|
|
355
|
-
]
|
|
356
|
-
]
|
|
357
|
-
)
|
|
391
|
+
site_rows.append([make_val(site_row[t]) for t in site_titles])
|
|
358
392
|
sess.rollback()
|
|
393
|
+
org_rows.append([make_val(org_row[t]) for t in org_titles])
|
|
359
394
|
write_spreadsheet(rf, compression, site_rows, g_era_rows)
|
|
360
395
|
|
|
396
|
+
if scenario_props.get("save_report_run", False):
|
|
397
|
+
report_run_id = ReportRun.w_insert(
|
|
398
|
+
"g_monthly_duration", user_id, fname, {"scenario": scenario_props}
|
|
399
|
+
)
|
|
400
|
+
for tab, rows in (
|
|
401
|
+
("org", org_rows),
|
|
402
|
+
("site", site_rows),
|
|
403
|
+
("era", g_era_rows),
|
|
404
|
+
):
|
|
405
|
+
titles = rows[0]
|
|
406
|
+
for row in rows[1:]:
|
|
407
|
+
values = dict(zip(titles, row))
|
|
408
|
+
ReportRun.w_insert_row(report_run_id, tab, titles, values, {})
|
|
409
|
+
ReportRun.w_update(report_run_id, "finished")
|
|
410
|
+
|
|
361
411
|
except BaseException:
|
|
362
412
|
msg = traceback.format_exc()
|
|
363
|
-
|
|
413
|
+
print(msg)
|
|
364
414
|
site_rows.append(["Problem " + msg])
|
|
365
415
|
write_spreadsheet(rf, compression, site_rows, g_era_rows)
|
|
366
416
|
finally:
|
|
@@ -374,24 +424,55 @@ def content(
|
|
|
374
424
|
|
|
375
425
|
|
|
376
426
|
def do_get(sess):
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
427
|
+
now = utc_datetime_now()
|
|
428
|
+
base_name = []
|
|
429
|
+
if "scenario_id" in request.values:
|
|
430
|
+
scenario_id = req_int("scenario_id")
|
|
431
|
+
scenario = Scenario.get_by_id(sess, scenario_id)
|
|
432
|
+
scenario_props = scenario.props
|
|
433
|
+
base_name.append(scenario.name)
|
|
434
|
+
else:
|
|
435
|
+
scenario_props = {}
|
|
436
|
+
base_name.append("g_monthly_duration")
|
|
437
|
+
|
|
438
|
+
if "finish_year" in request.values:
|
|
439
|
+
year = req_int("finish_year")
|
|
440
|
+
month = req_int("finish_month")
|
|
441
|
+
months = req_int("months")
|
|
442
|
+
start_date, _ = next(
|
|
443
|
+
c_months_c(finish_year=year, finish_month=month, months=months)
|
|
444
|
+
)
|
|
445
|
+
scenario_props["scenario_start_year"] = start_date.year
|
|
446
|
+
scenario_props["scenario_start_month"] = start_date.month
|
|
447
|
+
scenario_props["scenario_duration"] = months
|
|
380
448
|
|
|
381
|
-
|
|
449
|
+
if "site_id" in request.values:
|
|
450
|
+
site_id = req_int("site_id")
|
|
451
|
+
scenario_props["site_codes"] = [Site.get_by_id(sess, site_id).code]
|
|
452
|
+
|
|
453
|
+
if "site_codes" in request.values:
|
|
454
|
+
site_codes_raw_str = req_str("site_codes")
|
|
455
|
+
site_codes_str = site_codes_raw_str.strip()
|
|
456
|
+
if len(site_codes_str) > 0:
|
|
457
|
+
site_codes = []
|
|
458
|
+
|
|
459
|
+
for site_code in site_codes_str.splitlines():
|
|
460
|
+
Site.get_by_code(sess, site_code) # Check valid
|
|
461
|
+
site_codes.append(site_code)
|
|
462
|
+
|
|
463
|
+
scenario_props["site_codes"] = site_codes
|
|
382
464
|
|
|
383
465
|
if "g_supply_id" in request.values:
|
|
384
466
|
g_supply_id = req_int("g_supply_id")
|
|
385
|
-
|
|
386
|
-
|
|
467
|
+
g_supply = GSupply.get_by_id(sess, g_supply_id)
|
|
468
|
+
scenario_props["mprns"] = [g_supply.mprn]
|
|
387
469
|
|
|
388
470
|
if "compression" in request.values:
|
|
389
471
|
compression = req_bool("compression")
|
|
390
472
|
else:
|
|
391
473
|
compression = True
|
|
392
474
|
|
|
393
|
-
|
|
394
|
-
args = (site_id, g_supply_id, user, compression, finish_year, finish_month, months)
|
|
475
|
+
args = scenario_props, g.user.id, compression, now, base_name
|
|
395
476
|
|
|
396
477
|
threading.Thread(target=content, args=args).start()
|
|
397
478
|
return chellow_redirect("/downloads", 303)
|
chellow/templates/base.html
CHANGED
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
>Edit Local Reports</a>
|
|
73
73
|
</li>
|
|
74
74
|
<li><a href="/e/site_snags" title="Site Snags">Site Snags</a></li>
|
|
75
|
-
<li><a href="/
|
|
75
|
+
<li><a href="/scenarios" title="Scenarios">Scenarios</a></li>
|
|
76
76
|
<li><a href="/reports/batches">Batches</a></li>
|
|
77
77
|
<li><a href="/edi_viewer" title="EDI Viewer">EDI Viewer</a></li>
|
|
78
78
|
<li>
|
chellow/templates/home.html
CHANGED
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
<li><a href="/user_roles">Users Roles</a></li>
|
|
222
222
|
<li><a href="/system">System</a></li>
|
|
223
223
|
<li><a href="/edi_viewer">EDI Viewer</a></li>
|
|
224
|
-
<li><a href="/
|
|
224
|
+
<li><a href="/scenarios">Scenarios</a></li>
|
|
225
225
|
<li><a href="/reports/batches">Batches</a></li>
|
|
226
226
|
<li><a href="/tester">Tester</a></li>
|
|
227
227
|
<li><a href="/e/site_snags">Site Snags</a></li>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}
|
|
4
|
+
» Scenarios » {{scenario.name}}
|
|
5
|
+
{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block nav %}
|
|
8
|
+
<a href="/scenarios">Scenarios</a> » {{scenario.name}}
|
|
9
|
+
[<a href="/scenarios/{{scenario.id}}/edit">edit</a>]
|
|
10
|
+
{% endblock %}
|
|
11
|
+
|
|
12
|
+
{% block content %}
|
|
13
|
+
{% if scenario_props.get('utility') == 'gas' %}
|
|
14
|
+
<form action="/reports/g_monthly_duration">
|
|
15
|
+
<legend>Run With Monthly Duration</legend>
|
|
16
|
+
<fieldset>
|
|
17
|
+
<input type="hidden" name="scenario_id" value="{{scenario.id}}">
|
|
18
|
+
<label>Months</label> {{input_text('months', '1', 2, 2)}}
|
|
19
|
+
<label>Finish Month</label>
|
|
20
|
+
{{input_date('finish', month_finish, resolution='month')}}
|
|
21
|
+
<input type="submit" value="Run">
|
|
22
|
+
</fieldset>
|
|
23
|
+
</form>
|
|
24
|
+
{% else %}
|
|
25
|
+
<form action="/reports/247" method="post">
|
|
26
|
+
<fieldset>
|
|
27
|
+
<legend>Run With Monthly Duration</legend>
|
|
28
|
+
<input type="hidden" name="scenario_id" value="{{scenario.id}}">
|
|
29
|
+
<label>Months</label> {{input_text('months', initial=scenario_duration, size=2, maxlength=2)}}
|
|
30
|
+
<label>Finish month</label>
|
|
31
|
+
{{input_date('finish', scenario_finish_date, resolution='month')}}
|
|
32
|
+
<label>Site Codes</label>
|
|
33
|
+
{{input_textarea('site_codes', '', 5, 40,
|
|
34
|
+
placeholder='One on each line, includes all if left blank')}}
|
|
35
|
+
<input type="submit" value="Run">
|
|
36
|
+
</fieldset>
|
|
37
|
+
</form>
|
|
38
|
+
|
|
39
|
+
<form action="/reports/59" method="post">
|
|
40
|
+
<fieldset>
|
|
41
|
+
<legend>Run With Duration</legend>
|
|
42
|
+
<input type="hidden" name="scenario_id" value="{{scenario.id}}">
|
|
43
|
+
<label>Start Date</label>
|
|
44
|
+
{{ input_date('start', scenario_start_date) }}
|
|
45
|
+
<label>Finish Date</label>
|
|
46
|
+
{{ input_date('finish', scenario_finish_date) }}
|
|
47
|
+
<label>Site Codes</label>
|
|
48
|
+
{{input_textarea('site_codes', site_codes, 5, 40,
|
|
49
|
+
placeholder='One on each line, includes all if left blank')}}
|
|
50
|
+
<input type="submit" value="Run">
|
|
51
|
+
</fieldset>
|
|
52
|
+
</form>
|
|
53
|
+
{% endif %}
|
|
54
|
+
|
|
55
|
+
<h2>Properties</h2>
|
|
56
|
+
|
|
57
|
+
<pre>{{scenario.properties}}</pre>
|
|
58
|
+
|
|
59
|
+
{% include "/scenario_docs.html" %}
|
|
60
|
+
|
|
61
|
+
{% endblock %}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{% extends "base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}
|
|
4
|
+
» Scenarios » Add
|
|
5
|
+
{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block nav %}
|
|
8
|
+
<a href="/scenarios">Scenarios</a> » Add
|
|
9
|
+
{% endblock %}
|
|
10
|
+
|
|
11
|
+
{% block content %}
|
|
12
|
+
<form action="/scenarios/add" method="post">
|
|
13
|
+
<fieldset>
|
|
14
|
+
<legend>Add a scenario</legend>
|
|
15
|
+
<label>Name</label> {{input_text('name')}}
|
|
16
|
+
<label>Properties</label>
|
|
17
|
+
{{input_textarea('properties', initial_props, 20, 80, show_pos=True)}}
|
|
18
|
+
<input type="submit" value="Add">
|
|
19
|
+
</fieldset>
|
|
20
|
+
</form>
|
|
21
|
+
{% endblock %}
|