chellow 1707995667.0.0__py3-none-any.whl → 1708358861.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.

@@ -1,5 +1,4 @@
1
1
  import csv
2
- import os
3
2
  import sys
4
3
  import threading
5
4
  import traceback
@@ -10,20 +9,28 @@ from flask import g
10
9
 
11
10
  from sqlalchemy.sql.expression import true
12
11
 
13
- import chellow.dloads
14
- from chellow.models import Channel, Contract, Era, Session, Site, SiteEra, Snag, Supply
12
+ from chellow.dloads import open_file
13
+ from chellow.models import (
14
+ Channel,
15
+ Contract,
16
+ Era,
17
+ Session,
18
+ Site,
19
+ SiteEra,
20
+ Snag,
21
+ Supply,
22
+ User,
23
+ )
15
24
  from chellow.utils import csv_make_val, hh_before, req_int, utc_datetime_now
16
25
  from chellow.views import chellow_redirect
17
26
 
18
27
 
19
- def content(contract_id, days_hidden, user):
28
+ def content(contract_id, days_hidden, user_id):
20
29
  f = writer = None
21
30
  try:
22
31
  with Session() as sess:
23
- running_name, finished_name = chellow.dloads.make_names(
24
- "channel_snags.csv", user
25
- )
26
- f = open(running_name, mode="w", newline="")
32
+ user = User.get_by_id(sess, user_id)
33
+ f = open_file("channel_snags.csv", user, mode="w", newline="")
27
34
  writer = csv.writer(f, lineterminator="\n")
28
35
  titles = (
29
36
  "Hidden Days",
@@ -111,13 +118,12 @@ def content(contract_id, days_hidden, user):
111
118
  finally:
112
119
  if f is not None:
113
120
  f.close()
114
- os.rename(running_name, finished_name)
115
121
 
116
122
 
117
123
  def do_get(sess):
118
124
  contract_id = req_int("dc_contract_id")
119
125
  days_hidden = req_int("days_hidden")
120
126
 
121
- args = (contract_id, days_hidden, g.user)
127
+ args = contract_id, days_hidden, g.user.id
122
128
  threading.Thread(target=content, args=args).start()
123
129
  return chellow_redirect("/downloads", 303)
@@ -1,5 +1,4 @@
1
1
  import csv
2
- import os
3
2
  import sys
4
3
  import threading
5
4
  import traceback
@@ -12,7 +11,12 @@ from sqlalchemy import or_, text
12
11
  from sqlalchemy.orm import joinedload
13
12
  from sqlalchemy.sql.expression import func, null
14
13
 
15
- import chellow.dloads
14
+ from werkzeug.exceptions import BadRequest
15
+
16
+ import chellow.e.duos
17
+ import chellow.e.tnuos
18
+ from chellow.dloads import open_file
19
+ from chellow.e.computer import SupplySource
16
20
  from chellow.models import (
17
21
  Batch,
18
22
  Bill,
@@ -25,6 +29,7 @@ from chellow.models import (
25
29
  Session,
26
30
  SiteEra,
27
31
  Supply,
32
+ User,
28
33
  )
29
34
  from chellow.utils import (
30
35
  CHANNEL_TYPES,
@@ -40,10 +45,11 @@ from chellow.utils import (
40
45
  from chellow.views import chellow_redirect
41
46
 
42
47
 
43
- def content(running_name, finished_name, date, supply_id, mpan_cores):
48
+ def content(user_id, date, supply_id, mpan_cores):
44
49
  try:
45
50
  with Session() as sess:
46
- f = open(running_name, mode="w", newline="")
51
+ user = User.get_by_id(sess, user_id)
52
+ f = open_file("supplies_snapshot.csv", user, mode="w", newline="")
47
53
  _process(sess, f, date, supply_id, mpan_cores)
48
54
  except BaseException:
49
55
  msg = traceback.format_exc()
@@ -52,7 +58,354 @@ def content(running_name, finished_name, date, supply_id, mpan_cores):
52
58
  finally:
53
59
  if f is not None:
54
60
  f.close()
55
- os.rename(running_name, finished_name)
61
+
62
+
63
+ def _process_era(caches, sess, era_id, date, year_start):
64
+ NORMAL_READ_TYPES = ("N", "C", "N3")
65
+
66
+ era, supply, generator_type = (
67
+ sess.query(Era, Supply, GeneratorType)
68
+ .join(Supply, Era.supply_id == Supply.id)
69
+ .outerjoin(GeneratorType, Supply.generator_type_id == GeneratorType.id)
70
+ .filter(Era.id == era_id)
71
+ .options(
72
+ joinedload(Era.channels),
73
+ joinedload(Era.cop),
74
+ joinedload(Era.comm),
75
+ joinedload(Era.dc_contract),
76
+ joinedload(Era.exp_llfc),
77
+ joinedload(Era.exp_supplier_contract),
78
+ joinedload(Era.imp_llfc),
79
+ joinedload(Era.imp_supplier_contract),
80
+ joinedload(Era.mop_contract),
81
+ joinedload(Era.mtc_participant).joinedload(MtcParticipant.mtc),
82
+ joinedload(Era.mtc_participant).joinedload(MtcParticipant.meter_type),
83
+ joinedload(Era.pc),
84
+ joinedload(Era.site_eras).joinedload(SiteEra.site),
85
+ joinedload(Era.ssc),
86
+ joinedload(Era.energisation_status),
87
+ joinedload(Era.supply).joinedload(Supply.source),
88
+ joinedload(Era.supply).joinedload(Supply.gsp_group),
89
+ joinedload(Era.supply).joinedload(Supply.dno),
90
+ )
91
+ .one()
92
+ )
93
+
94
+ site_codes = []
95
+ site_names = []
96
+ for site_era in era.site_eras:
97
+ if site_era.is_physical:
98
+ physical_site = site_era.site
99
+ else:
100
+ site = site_era.site
101
+ site_codes.append(site.code)
102
+ site_names.append(site.name)
103
+
104
+ sup_eras = (
105
+ sess.query(Era).filter(Era.supply == supply).order_by(Era.start_date).all()
106
+ )
107
+ supply_start_date = sup_eras[0].start_date
108
+ supply_finish_date = sup_eras[-1].finish_date
109
+
110
+ if era.imp_mpan_core is None:
111
+ voltage_level_code = era.exp_llfc.voltage_level.code
112
+ is_substation = era.exp_llfc.is_substation
113
+ else:
114
+ voltage_level_code = era.imp_llfc.voltage_level.code
115
+ is_substation = era.imp_llfc.is_substation
116
+
117
+ if generator_type is None:
118
+ generator_type_str = ""
119
+ else:
120
+ generator_type_str = generator_type.code
121
+
122
+ metering_type = era.meter_category
123
+
124
+ if metering_type in ("nhh", "amr"):
125
+ latest_prev_normal_read = (
126
+ sess.query(RegisterRead)
127
+ .join(Bill)
128
+ .join(RegisterRead.previous_type)
129
+ .filter(
130
+ ReadType.code.in_(NORMAL_READ_TYPES),
131
+ RegisterRead.previous_date <= date,
132
+ Bill.supply_id == supply.id,
133
+ )
134
+ .order_by(RegisterRead.previous_date.desc())
135
+ .options(joinedload(RegisterRead.previous_type))
136
+ .first()
137
+ )
138
+
139
+ latest_pres_normal_read = (
140
+ sess.query(RegisterRead)
141
+ .join(Bill)
142
+ .join(RegisterRead.present_type)
143
+ .filter(
144
+ ReadType.code.in_(NORMAL_READ_TYPES),
145
+ RegisterRead.present_date <= date,
146
+ Bill.supply == supply,
147
+ )
148
+ .order_by(RegisterRead.present_date.desc())
149
+ .options(joinedload(RegisterRead.present_type))
150
+ .first()
151
+ )
152
+
153
+ if latest_prev_normal_read is None and latest_pres_normal_read is None:
154
+ latest_normal_read_date = None
155
+ latest_normal_read_type = None
156
+ elif latest_pres_normal_read is not None and latest_prev_normal_read is None:
157
+ latest_normal_read_date = latest_pres_normal_read.present_date
158
+ latest_normal_read_type = latest_pres_normal_read.present_type.code
159
+ elif latest_pres_normal_read is None and latest_prev_normal_read is not None:
160
+ latest_normal_read_date = latest_prev_normal_read.previous_date
161
+ latest_normal_read_type = latest_prev_normal_read.previous_type.code
162
+ elif (
163
+ latest_pres_normal_read.present_date > latest_prev_normal_read.previous_date
164
+ ):
165
+ latest_normal_read_date = latest_pres_normal_read.present_date
166
+ latest_normal_read_type = latest_pres_normal_read.present_type.code
167
+ else:
168
+ latest_normal_read_date = latest_prev_normal_read.previous_date
169
+ latest_normal_read_type = latest_prev_normal_read.previous_type.code
170
+ if latest_normal_read_date is not None:
171
+ latest_normal_read_date = hh_format(latest_normal_read_date)
172
+
173
+ else:
174
+ latest_normal_read_date = metering_type
175
+ latest_normal_read_type = None
176
+
177
+ mop_contract = era.mop_contract
178
+ mop_contract_name = mop_contract.name
179
+ mop_account = era.mop_account
180
+ latest_mop_bill_date = (
181
+ sess.query(Bill.finish_date)
182
+ .join(Batch)
183
+ .filter(
184
+ Bill.start_date <= date,
185
+ Bill.supply == supply,
186
+ Batch.contract == mop_contract,
187
+ )
188
+ .order_by(Bill.finish_date.desc())
189
+ .first()
190
+ )
191
+
192
+ if latest_mop_bill_date is not None:
193
+ latest_mop_bill_date = hh_format(latest_mop_bill_date[0])
194
+
195
+ dc_contract = era.dc_contract
196
+ dc_contract_name = dc_contract.name
197
+ dc_account = era.dc_account
198
+ latest_dc_bill_date = (
199
+ sess.query(Bill.finish_date)
200
+ .join(Batch)
201
+ .filter(
202
+ Bill.start_date <= date,
203
+ Bill.supply == supply,
204
+ Batch.contract == dc_contract,
205
+ )
206
+ .order_by(Bill.finish_date.desc())
207
+ .first()
208
+ )
209
+
210
+ if latest_dc_bill_date is not None:
211
+ latest_dc_bill_date = hh_format(latest_dc_bill_date[0])
212
+
213
+ channel_values = []
214
+ for imp_related in [True, False]:
215
+ for channel_type in CHANNEL_TYPES:
216
+ if era.find_channel(sess, imp_related, channel_type) is None:
217
+ channel_values.append("false")
218
+ else:
219
+ channel_values.append("true")
220
+
221
+ imp_avg_months = None
222
+ exp_avg_months = None
223
+ for is_import in [True, False]:
224
+ if metering_type == "nhh":
225
+ continue
226
+
227
+ params = {
228
+ "supply_id": supply.id,
229
+ "year_start": year_start,
230
+ "year_finish": date,
231
+ "is_import": is_import,
232
+ }
233
+ month_mds = tuple(
234
+ md[0] * 2
235
+ for md in sess.execute(
236
+ text(
237
+ """
238
+
239
+ select max(hh_datum.value) as md
240
+ from hh_datum join channel on (hh_datum.channel_id = channel.id)
241
+ join era on (channel.era_id = era.id)
242
+ where era.supply_id = :supply_id and hh_datum.start_date >= :year_start
243
+ and hh_datum.start_date <= :year_finish
244
+ and channel.channel_type = 'ACTIVE'
245
+ and channel.imp_related = :is_import
246
+ group by extract(month from (hh_datum.start_date at time zone 'utc'))
247
+ order by md desc
248
+ limit 3
249
+
250
+ """
251
+ ),
252
+ params=params,
253
+ )
254
+ )
255
+
256
+ avg_months = sum(month_mds)
257
+ if len(month_mds) > 0:
258
+ avg_months /= len(month_mds)
259
+ if is_import:
260
+ imp_avg_months = avg_months
261
+ else:
262
+ exp_avg_months = avg_months
263
+
264
+ if (imp_avg_months is not None and imp_avg_months > 100) or (
265
+ exp_avg_months is not None and exp_avg_months > 100
266
+ ):
267
+ mandatory_hh = "yes"
268
+ else:
269
+ mandatory_hh = "no"
270
+
271
+ imp_latest_supplier_bill_date = None
272
+ exp_latest_supplier_bill_date = None
273
+ imp_tnuos_band = None
274
+ for is_import in (True, False):
275
+ for er in (
276
+ sess.query(Era)
277
+ .filter(Era.supply == era.supply, Era.start_date <= date)
278
+ .order_by(Era.start_date.desc())
279
+ ):
280
+ if is_import:
281
+ if er.imp_mpan_core is None:
282
+ break
283
+ else:
284
+ supplier_contract = er.imp_supplier_contract
285
+ if era.energisation_status.code == "E":
286
+ imp_ss = SupplySource(
287
+ sess, date, date, date + HH, era, True, caches
288
+ )
289
+ chellow.e.duos.duos_vb(imp_ss)
290
+ hh = imp_ss.hh_data[0]
291
+ if hh["start-date"] >= chellow.e.tnuos.BANDED_START:
292
+ imp_tnuos_band = chellow.e.tnuos.BAND_LOOKUP[
293
+ hh["duos-description"]
294
+ ]
295
+ else:
296
+ if er.exp_mpan_core is None:
297
+ break
298
+ else:
299
+ supplier_contract = er.exp_supplier_contract
300
+
301
+ latest_bill_date = (
302
+ sess.query(Bill.finish_date)
303
+ .join(Batch)
304
+ .filter(
305
+ Bill.finish_date >= er.start_date,
306
+ Bill.finish_date <= hh_min(er.finish_date, date),
307
+ Bill.supply == supply,
308
+ Batch.contract == supplier_contract,
309
+ )
310
+ .order_by(Bill.finish_date.desc())
311
+ .first()
312
+ )
313
+
314
+ if latest_bill_date is not None:
315
+ latest_bill_date = hh_format(latest_bill_date[0])
316
+
317
+ if is_import:
318
+ imp_latest_supplier_bill_date = latest_bill_date
319
+ else:
320
+ exp_latest_supplier_bill_date = latest_bill_date
321
+ break
322
+
323
+ meter_installation_date = (
324
+ sess.query(func.min(Era.start_date))
325
+ .filter(Era.supply == era.supply, Era.msn == era.msn)
326
+ .one()[0]
327
+ )
328
+
329
+ ssc = era.ssc
330
+ if ssc is None:
331
+ ssc_code = ssc_description = num_registers = None
332
+ else:
333
+ ssc_code, ssc_description = ssc.code, ssc.description
334
+ num_registers = (
335
+ sess.query(MeasurementRequirement)
336
+ .filter(MeasurementRequirement.ssc == ssc)
337
+ .count()
338
+ )
339
+
340
+ return (
341
+ [
342
+ date,
343
+ era.imp_mpan_core,
344
+ era.exp_mpan_core,
345
+ physical_site.code,
346
+ physical_site.name,
347
+ ", ".join(site_codes),
348
+ ", ".join(site_names),
349
+ supply.id,
350
+ supply.source.code,
351
+ generator_type_str,
352
+ supply.gsp_group.code,
353
+ supply.dno.dno_code,
354
+ voltage_level_code,
355
+ is_substation,
356
+ metering_type,
357
+ mandatory_hh,
358
+ era.pc.code,
359
+ era.mtc_participant.mtc.code,
360
+ era.cop.code,
361
+ era.comm.code,
362
+ ssc_code,
363
+ ssc_description,
364
+ era.energisation_status.code,
365
+ num_registers,
366
+ mop_contract_name,
367
+ mop_account,
368
+ dc_contract_name,
369
+ dc_account,
370
+ era.msn,
371
+ meter_installation_date,
372
+ latest_normal_read_date,
373
+ latest_normal_read_type,
374
+ latest_dc_bill_date,
375
+ latest_mop_bill_date,
376
+ supply_start_date,
377
+ supply_finish_date,
378
+ era.properties,
379
+ imp_tnuos_band,
380
+ ]
381
+ + channel_values
382
+ + [
383
+ era.imp_sc,
384
+ None if era.imp_llfc is None else era.imp_llfc.code,
385
+ None if era.imp_llfc is None else era.imp_llfc.description,
386
+ (
387
+ None
388
+ if era.imp_supplier_contract is None
389
+ else era.imp_supplier_contract.name
390
+ ),
391
+ era.imp_supplier_account,
392
+ imp_avg_months,
393
+ imp_latest_supplier_bill_date,
394
+ ]
395
+ + [
396
+ era.exp_sc,
397
+ None if era.exp_llfc is None else era.exp_llfc.code,
398
+ None if era.exp_llfc is None else era.exp_llfc.description,
399
+ (
400
+ None
401
+ if era.exp_supplier_contract is None
402
+ else era.exp_supplier_contract.name
403
+ ),
404
+ era.exp_supplier_account,
405
+ exp_avg_months,
406
+ exp_latest_supplier_bill_date,
407
+ ]
408
+ )
56
409
 
57
410
 
58
411
  def _process(sess, f, date, supply_id, mpan_cores):
@@ -95,6 +448,7 @@ def _process(sess, f, date, supply_id, mpan_cores):
95
448
  "Supply Start Date",
96
449
  "Supply Finish Date",
97
450
  "Properties",
451
+ "tnuos_band",
98
452
  "Import ACTIVE?",
99
453
  "Import REACTIVE_IMPORT?",
100
454
  "Import REACTIVE_EXPORT?",
@@ -118,8 +472,8 @@ def _process(sess, f, date, supply_id, mpan_cores):
118
472
  )
119
473
  writer.writerow(titles)
120
474
 
121
- NORMAL_READ_TYPES = ("N", "C", "N3")
122
475
  year_start = date + HH - relativedelta(years=1)
476
+ caches = {}
123
477
 
124
478
  era_ids = (
125
479
  sess.query(Era.id)
@@ -141,342 +495,12 @@ def _process(sess, f, date, supply_id, mpan_cores):
141
495
  )
142
496
 
143
497
  for (era_id,) in era_ids:
144
- era, supply, generator_type = (
145
- sess.query(Era, Supply, GeneratorType)
146
- .join(Supply, Era.supply_id == Supply.id)
147
- .outerjoin(GeneratorType, Supply.generator_type_id == GeneratorType.id)
148
- .filter(Era.id == era_id)
149
- .options(
150
- joinedload(Era.channels),
151
- joinedload(Era.cop),
152
- joinedload(Era.comm),
153
- joinedload(Era.dc_contract),
154
- joinedload(Era.exp_llfc),
155
- joinedload(Era.exp_supplier_contract),
156
- joinedload(Era.imp_llfc),
157
- joinedload(Era.imp_supplier_contract),
158
- joinedload(Era.mop_contract),
159
- joinedload(Era.mtc_participant).joinedload(MtcParticipant.mtc),
160
- joinedload(Era.mtc_participant).joinedload(MtcParticipant.meter_type),
161
- joinedload(Era.pc),
162
- joinedload(Era.site_eras).joinedload(SiteEra.site),
163
- joinedload(Era.ssc),
164
- joinedload(Era.energisation_status),
165
- joinedload(Era.supply).joinedload(Supply.source),
166
- joinedload(Era.supply).joinedload(Supply.gsp_group),
167
- joinedload(Era.supply).joinedload(Supply.dno),
168
- )
169
- .one()
170
- )
171
-
172
- site_codes = []
173
- site_names = []
174
- for site_era in era.site_eras:
175
- if site_era.is_physical:
176
- physical_site = site_era.site
177
- else:
178
- site = site_era.site
179
- site_codes.append(site.code)
180
- site_names.append(site.name)
181
-
182
- sup_eras = (
183
- sess.query(Era).filter(Era.supply == supply).order_by(Era.start_date).all()
184
- )
185
- supply_start_date = sup_eras[0].start_date
186
- supply_finish_date = sup_eras[-1].finish_date
187
-
188
- if era.imp_mpan_core is None:
189
- voltage_level_code = era.exp_llfc.voltage_level.code
190
- is_substation = era.exp_llfc.is_substation
191
- else:
192
- voltage_level_code = era.imp_llfc.voltage_level.code
193
- is_substation = era.imp_llfc.is_substation
194
-
195
- if generator_type is None:
196
- generator_type_str = ""
197
- else:
198
- generator_type_str = generator_type.code
199
-
200
- metering_type = era.meter_category
201
-
202
- if metering_type in ("nhh", "amr"):
203
- latest_prev_normal_read = (
204
- sess.query(RegisterRead)
205
- .join(Bill)
206
- .join(RegisterRead.previous_type)
207
- .filter(
208
- ReadType.code.in_(NORMAL_READ_TYPES),
209
- RegisterRead.previous_date <= date,
210
- Bill.supply_id == supply.id,
211
- )
212
- .order_by(RegisterRead.previous_date.desc())
213
- .options(joinedload(RegisterRead.previous_type))
214
- .first()
215
- )
216
-
217
- latest_pres_normal_read = (
218
- sess.query(RegisterRead)
219
- .join(Bill)
220
- .join(RegisterRead.present_type)
221
- .filter(
222
- ReadType.code.in_(NORMAL_READ_TYPES),
223
- RegisterRead.present_date <= date,
224
- Bill.supply == supply,
225
- )
226
- .order_by(RegisterRead.present_date.desc())
227
- .options(joinedload(RegisterRead.present_type))
228
- .first()
229
- )
230
-
231
- if latest_prev_normal_read is None and latest_pres_normal_read is None:
232
- latest_normal_read_date = None
233
- latest_normal_read_type = None
234
- elif (
235
- latest_pres_normal_read is not None and latest_prev_normal_read is None
236
- ):
237
- latest_normal_read_date = latest_pres_normal_read.present_date
238
- latest_normal_read_type = latest_pres_normal_read.present_type.code
239
- elif (
240
- latest_pres_normal_read is None and latest_prev_normal_read is not None
241
- ):
242
- latest_normal_read_date = latest_prev_normal_read.previous_date
243
- latest_normal_read_type = latest_prev_normal_read.previous_type.code
244
- elif (
245
- latest_pres_normal_read.present_date
246
- > latest_prev_normal_read.previous_date
247
- ):
248
- latest_normal_read_date = latest_pres_normal_read.present_date
249
- latest_normal_read_type = latest_pres_normal_read.present_type.code
250
- else:
251
- latest_normal_read_date = latest_prev_normal_read.previous_date
252
- latest_normal_read_type = latest_prev_normal_read.previous_type.code
253
- if latest_normal_read_date is not None:
254
- latest_normal_read_date = hh_format(latest_normal_read_date)
255
-
256
- else:
257
- latest_normal_read_date = metering_type
258
- latest_normal_read_type = None
259
-
260
- mop_contract = era.mop_contract
261
- mop_contract_name = mop_contract.name
262
- mop_account = era.mop_account
263
- latest_mop_bill_date = (
264
- sess.query(Bill.finish_date)
265
- .join(Batch)
266
- .filter(
267
- Bill.start_date <= date,
268
- Bill.supply == supply,
269
- Batch.contract == mop_contract,
270
- )
271
- .order_by(Bill.finish_date.desc())
272
- .first()
273
- )
274
-
275
- if latest_mop_bill_date is not None:
276
- latest_mop_bill_date = hh_format(latest_mop_bill_date[0])
277
-
278
- dc_contract = era.dc_contract
279
- dc_contract_name = dc_contract.name
280
- dc_account = era.dc_account
281
- latest_dc_bill_date = (
282
- sess.query(Bill.finish_date)
283
- .join(Batch)
284
- .filter(
285
- Bill.start_date <= date,
286
- Bill.supply == supply,
287
- Batch.contract == dc_contract,
288
- )
289
- .order_by(Bill.finish_date.desc())
290
- .first()
291
- )
292
-
293
- if latest_dc_bill_date is not None:
294
- latest_dc_bill_date = hh_format(latest_dc_bill_date[0])
295
-
296
- channel_values = []
297
- for imp_related in [True, False]:
298
- for channel_type in CHANNEL_TYPES:
299
- if era.find_channel(sess, imp_related, channel_type) is None:
300
- channel_values.append("false")
301
- else:
302
- channel_values.append("true")
303
-
304
- imp_avg_months = None
305
- exp_avg_months = None
306
- for is_import in [True, False]:
307
- if metering_type == "nhh":
308
- continue
309
-
310
- params = {
311
- "supply_id": supply.id,
312
- "year_start": year_start,
313
- "year_finish": date,
314
- "is_import": is_import,
315
- }
316
- month_mds = tuple(
317
- md[0] * 2
318
- for md in sess.execute(
319
- text(
320
- """
321
-
322
- select max(hh_datum.value) as md
323
- from hh_datum join channel on (hh_datum.channel_id = channel.id)
324
- join era on (channel.era_id = era.id)
325
- where era.supply_id = :supply_id and hh_datum.start_date >= :year_start
326
- and hh_datum.start_date <= :year_finish
327
- and channel.channel_type = 'ACTIVE'
328
- and channel.imp_related = :is_import
329
- group by extract(month from (hh_datum.start_date at time zone 'utc'))
330
- order by md desc
331
- limit 3
332
-
333
- """
334
- ),
335
- params=params,
336
- )
337
- )
338
-
339
- avg_months = sum(month_mds)
340
- if len(month_mds) > 0:
341
- avg_months /= len(month_mds)
342
- if is_import:
343
- imp_avg_months = avg_months
344
- else:
345
- exp_avg_months = avg_months
346
-
347
- if (imp_avg_months is not None and imp_avg_months > 100) or (
348
- exp_avg_months is not None and exp_avg_months > 100
349
- ):
350
- mandatory_hh = "yes"
351
- else:
352
- mandatory_hh = "no"
353
-
354
- imp_latest_supplier_bill_date = None
355
- exp_latest_supplier_bill_date = None
356
- for is_import in (True, False):
357
- for er in (
358
- sess.query(Era)
359
- .filter(Era.supply == era.supply, Era.start_date <= date)
360
- .order_by(Era.start_date.desc())
361
- ):
362
- if is_import:
363
- if er.imp_mpan_core is None:
364
- break
365
- else:
366
- supplier_contract = er.imp_supplier_contract
367
- else:
368
- if er.exp_mpan_core is None:
369
- break
370
- else:
371
- supplier_contract = er.exp_supplier_contract
372
-
373
- latest_bill_date = (
374
- sess.query(Bill.finish_date)
375
- .join(Batch)
376
- .filter(
377
- Bill.finish_date >= er.start_date,
378
- Bill.finish_date <= hh_min(er.finish_date, date),
379
- Bill.supply == supply,
380
- Batch.contract == supplier_contract,
381
- )
382
- .order_by(Bill.finish_date.desc())
383
- .first()
384
- )
385
-
386
- if latest_bill_date is not None:
387
- latest_bill_date = hh_format(latest_bill_date[0])
388
-
389
- if is_import:
390
- imp_latest_supplier_bill_date = latest_bill_date
391
- else:
392
- exp_latest_supplier_bill_date = latest_bill_date
393
- break
394
-
395
- meter_installation_date = (
396
- sess.query(func.min(Era.start_date))
397
- .filter(Era.supply == era.supply, Era.msn == era.msn)
398
- .one()[0]
399
- )
400
-
401
- ssc = era.ssc
402
- if ssc is None:
403
- ssc_code = ssc_description = num_registers = None
404
- else:
405
- ssc_code, ssc_description = ssc.code, ssc.description
406
- num_registers = (
407
- sess.query(MeasurementRequirement)
408
- .filter(MeasurementRequirement.ssc == ssc)
409
- .count()
410
- )
411
-
412
- vals = (
413
- [
414
- date,
415
- era.imp_mpan_core,
416
- era.exp_mpan_core,
417
- physical_site.code,
418
- physical_site.name,
419
- ", ".join(site_codes),
420
- ", ".join(site_names),
421
- supply.id,
422
- supply.source.code,
423
- generator_type_str,
424
- supply.gsp_group.code,
425
- supply.dno.dno_code,
426
- voltage_level_code,
427
- is_substation,
428
- metering_type,
429
- mandatory_hh,
430
- era.pc.code,
431
- era.mtc_participant.mtc.code,
432
- era.cop.code,
433
- era.comm.code,
434
- ssc_code,
435
- ssc_description,
436
- era.energisation_status.code,
437
- num_registers,
438
- mop_contract_name,
439
- mop_account,
440
- dc_contract_name,
441
- dc_account,
442
- era.msn,
443
- meter_installation_date,
444
- latest_normal_read_date,
445
- latest_normal_read_type,
446
- latest_dc_bill_date,
447
- latest_mop_bill_date,
448
- supply_start_date,
449
- supply_finish_date,
450
- era.properties,
451
- ]
452
- + channel_values
453
- + [
454
- era.imp_sc,
455
- None if era.imp_llfc is None else era.imp_llfc.code,
456
- None if era.imp_llfc is None else era.imp_llfc.description,
457
- (
458
- None
459
- if era.imp_supplier_contract is None
460
- else era.imp_supplier_contract.name
461
- ),
462
- era.imp_supplier_account,
463
- imp_avg_months,
464
- imp_latest_supplier_bill_date,
465
- ]
466
- + [
467
- era.exp_sc,
468
- None if era.exp_llfc is None else era.exp_llfc.code,
469
- None if era.exp_llfc is None else era.exp_llfc.description,
470
- (
471
- None
472
- if era.exp_supplier_contract is None
473
- else era.exp_supplier_contract.name
474
- ),
475
- era.exp_supplier_account,
476
- exp_avg_months,
477
- exp_latest_supplier_bill_date,
478
- ]
479
- )
498
+ try:
499
+ vals = _process_era(caches, sess, era_id, date, year_start)
500
+ except BaseException as e:
501
+ raise BadRequest(f"Problem with era {era_id}: {e}") from e
502
+ except BadRequest as e:
503
+ raise BadRequest(f"Problem with era {era_id}: {e.description}")
480
504
  writer.writerow([csv_make_val(v) for v in vals])
481
505
 
482
506
  # Avoid a long-running transaction
@@ -502,10 +526,6 @@ def do_get(session):
502
526
  else:
503
527
  mpan_cores = None
504
528
 
505
- running_name, finished_name = chellow.dloads.make_names(
506
- "supplies_snapshot.csv", user
507
- )
508
-
509
- args = (running_name, finished_name, date, supply_id, mpan_cores)
529
+ args = user.id, date, supply_id, mpan_cores
510
530
  threading.Thread(target=content, args=args).start()
511
531
  return chellow_redirect("/downloads", 303)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: chellow
3
- Version: 1707995667.0.0
3
+ Version: 1708358861.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)
@@ -76,12 +76,12 @@ chellow/reports/report_187.py,sha256=UvpaYHjyJFNV5puYq8_KxfzoBtVrwFgIGUOmC5oGA9A
76
76
  chellow/reports/report_215.py,sha256=_HZO_MhL51ttzmG6IrT8YVG6WmJMkRNWsXOW7AL7GWs,6766
77
77
  chellow/reports/report_219.py,sha256=o2eEg3mX9_raP2b4gjc2Gu4vqnMqcvvJBYQ1oQjxvpE,6637
78
78
  chellow/reports/report_231.py,sha256=E70sOYFS_Zc52LUfMY7SniQ1c6K3vPvDWvCvwaMUFrA,4210
79
- chellow/reports/report_233.py,sha256=KL9Qd3f-284w1Jj_ksUJ_OrE9Z_3RCz1zhRwZ9gdtLQ,4387
79
+ chellow/reports/report_233.py,sha256=DLAmkoHFKH-N8OEIoX4jeCxAaCfJK0e7ssjFJJpPqzw,4334
80
80
  chellow/reports/report_241.py,sha256=se2V1tb5scvH9-RRuGG3U-IbqUYd-BZcNFwvTRjkbsw,5625
81
81
  chellow/reports/report_247.py,sha256=m2YgZY1YkAkSI2Qn3cNlFe2Gv8ToXfFs1zHiQd9RwbM,41556
82
82
  chellow/reports/report_29.py,sha256=KDFjgrLBv4WbG9efCdu_geMR7gT_QV9N97Wfdt7aDc4,2736
83
83
  chellow/reports/report_291.py,sha256=q04Y9EfMhQuEX4ObpmUs8vJTL76QwdG1A2-2HDVWhHQ,7587
84
- chellow/reports/report_33.py,sha256=LXLpsjfUTbCDuSKEE8o-LVpBLqRADpiGnyeilBgLGA0,16925
84
+ chellow/reports/report_33.py,sha256=3WXPN0xV6PGMKY_Oc5bKR84JuiXirYlYdrghqIgYY_s,16675
85
85
  chellow/reports/report_387.py,sha256=KcClrEOK5IRvePp0Jgbzs1Gwf-_CqYmEtFFlXrr_Z3E,5670
86
86
  chellow/reports/report_41.py,sha256=QQeTshA1Og7N3wPaoZ8ynJzwsvZ1mgSFc7DDkVqIZoM,7447
87
87
  chellow/reports/report_429.py,sha256=0GCc0rQnOSG0fusw69yMMOCxnWApBd3P2sGWIg1py9M,12359
@@ -363,6 +363,6 @@ chellow/templates/g/supply_note_edit.html,sha256=6UQf_qbhFDys3cVsTp-c7ABWZpggW9R
363
363
  chellow/templates/g/supply_notes.html,sha256=WR3YwGh_qqTklSJ7JqWX6BKBc9rk_jMff4RiWZiF2CM,936
364
364
  chellow/templates/g/unit.html,sha256=KouNVU0-i84afANkLQ_heJ0uDfJ9H5A05PuLqb8iCN8,438
365
365
  chellow/templates/g/units.html,sha256=p5Nd-lAIboKPEOO6N451hx1bcKxMg4BDODnZ-43MmJc,441
366
- chellow-1707995667.0.0.dist-info/METADATA,sha256=qAtfNaDLJjw2jkahNM2b5loL8f-MkeEf2NXOo2tun_E,12203
367
- chellow-1707995667.0.0.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
368
- chellow-1707995667.0.0.dist-info/RECORD,,
366
+ chellow-1708358861.0.0.dist-info/METADATA,sha256=_bInYkXY1vjjvC7miNTD-mnFkrdyaxQ9nx3uOCNzYSE,12203
367
+ chellow-1708358861.0.0.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
368
+ chellow-1708358861.0.0.dist-info/RECORD,,