chellow 1710934022.0.0__py3-none-any.whl → 1712589951.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/__init__.py +4 -3
- chellow/dloads.py +5 -3
- chellow/e/views.py +5 -1
- chellow/models.py +14 -6
- chellow/reports/report_181.py +10 -9
- chellow/reports/report_241.py +23 -32
- chellow/reports/report_asset_comparison.py +9 -11
- chellow/reports/report_csv_llfcs.py +10 -9
- chellow/reports/report_csv_site_snags.py +9 -13
- chellow/reports/report_g_virtual_bills.py +10 -13
- chellow/reports/report_sscs.py +3 -8
- chellow/reports/report_supply_contacts.py +3 -14
- {chellow-1710934022.0.0.dist-info → chellow-1712589951.0.0.dist-info}/METADATA +1 -1
- {chellow-1710934022.0.0.dist-info → chellow-1712589951.0.0.dist-info}/RECORD +15 -17
- {chellow-1710934022.0.0.dist-info → chellow-1712589951.0.0.dist-info}/WHEEL +1 -1
- chellow/reports/report_177.py +0 -285
- chellow/reports/report_215.py +0 -176
chellow/__init__.py
CHANGED
|
@@ -63,8 +63,8 @@ def get_importer_modules():
|
|
|
63
63
|
)
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
def create_app(testing=False):
|
|
67
|
-
app = Flask("chellow", instance_relative_config=True)
|
|
66
|
+
def create_app(testing=False, instance_path=None):
|
|
67
|
+
app = Flask("chellow", instance_relative_config=True, instance_path=instance_path)
|
|
68
68
|
app.wsgi_app = MsProxy(app.wsgi_app)
|
|
69
69
|
app.secret_key = os.urandom(24)
|
|
70
70
|
start_sqlalchemy()
|
|
@@ -79,7 +79,6 @@ def create_app(testing=False):
|
|
|
79
79
|
|
|
80
80
|
if not testing:
|
|
81
81
|
db_upgrade(app.root_path)
|
|
82
|
-
chellow.dloads.startup(Path(app.instance_path))
|
|
83
82
|
chellow.e.hh_importer.startup()
|
|
84
83
|
|
|
85
84
|
with Session() as sess:
|
|
@@ -90,6 +89,8 @@ def create_app(testing=False):
|
|
|
90
89
|
api_props = props.get("api", {})
|
|
91
90
|
api.description = api_props.get("description", "Access Chellow data")
|
|
92
91
|
|
|
92
|
+
chellow.dloads.startup(Path(app.instance_path), run_deleter=(not testing))
|
|
93
|
+
|
|
93
94
|
for module in get_importer_modules():
|
|
94
95
|
if not testing:
|
|
95
96
|
module.startup()
|
chellow/dloads.py
CHANGED
|
@@ -20,12 +20,14 @@ download_path = None
|
|
|
20
20
|
SERIAL_DIGITS = 5
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def startup(instance_path):
|
|
23
|
+
def startup(instance_path, run_deleter=True):
|
|
24
24
|
global file_deleter
|
|
25
25
|
global download_id
|
|
26
26
|
global download_path
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
if run_deleter:
|
|
29
|
+
file_deleter = FileDeleter()
|
|
30
|
+
file_deleter.start()
|
|
29
31
|
|
|
30
32
|
download_path = instance_path / "downloads"
|
|
31
33
|
download_path.mkdir(parents=True, exist_ok=True)
|
chellow/e/views.py
CHANGED
|
@@ -1569,7 +1569,6 @@ def era_edit_form_get(era_id):
|
|
|
1569
1569
|
try:
|
|
1570
1570
|
era = Era.get_by_id(g.sess, era_id)
|
|
1571
1571
|
ct_now = ct_datetime_now()
|
|
1572
|
-
cops = g.sess.scalars(select(Cop).order_by(Cop.code))
|
|
1573
1572
|
comms = g.sess.scalars(select(Comm).order_by(Comm.code))
|
|
1574
1573
|
energisation_statuses = g.sess.scalars(
|
|
1575
1574
|
select(EnergisationStatus).order_by(EnergisationStatus.code)
|
|
@@ -1781,6 +1780,11 @@ def era_edit_form_get(era_id):
|
|
|
1781
1780
|
else:
|
|
1782
1781
|
mtc_participant = None
|
|
1783
1782
|
|
|
1783
|
+
if mtc_participant is None:
|
|
1784
|
+
cops = g.sess.scalars(select(Cop).order_by(Cop.code))
|
|
1785
|
+
else:
|
|
1786
|
+
cops = Cop.get_valid(g.sess, mtc_participant.meter_type)
|
|
1787
|
+
|
|
1784
1788
|
if pc.code == "00":
|
|
1785
1789
|
imp_llfcs_q = (
|
|
1786
1790
|
select(Llfc)
|
chellow/models.py
CHANGED
|
@@ -510,6 +510,17 @@ class Cop(Base, PersistentClass):
|
|
|
510
510
|
raise BadRequest(f"The CoP with code {code} can't be found.")
|
|
511
511
|
return typ
|
|
512
512
|
|
|
513
|
+
@staticmethod
|
|
514
|
+
def get_valid(sess, meter_type):
|
|
515
|
+
|
|
516
|
+
if meter_type.code == "C5":
|
|
517
|
+
q = select(Cop).where(Cop.code.in_(["1", "2", "3", "4", "5"]))
|
|
518
|
+
elif meter_type.code in ["6A", "6B", "6C", "6D"]:
|
|
519
|
+
q = select(Cop).where(Cop.code == meter_type.code.lower())
|
|
520
|
+
else:
|
|
521
|
+
q = select(Cop)
|
|
522
|
+
return sess.scalars(q.order_by(Cop.code))
|
|
523
|
+
|
|
513
524
|
__tablename__ = "cop"
|
|
514
525
|
id = Column(Integer, primary_key=True)
|
|
515
526
|
code = Column(String, unique=True, nullable=False)
|
|
@@ -3700,12 +3711,9 @@ class Era(Base, PersistentClass):
|
|
|
3700
3711
|
f"{hh_format(finish_date)}."
|
|
3701
3712
|
)
|
|
3702
3713
|
|
|
3703
|
-
if
|
|
3704
|
-
self.mtc_participant.meter_type
|
|
3705
|
-
|
|
3706
|
-
or self.mtc_participant.meter_type.code in ["6A", "6B", "6C", "6D"]
|
|
3707
|
-
and cop.code.upper() != self.mtc_participant.meter_type.code
|
|
3708
|
-
):
|
|
3714
|
+
if cop.code not in [
|
|
3715
|
+
c.code for c in Cop.get_valid(sess, self.mtc_participant.meter_type)
|
|
3716
|
+
]:
|
|
3709
3717
|
raise BadRequest(
|
|
3710
3718
|
f"The CoP of {cop.code} is not compatible with the meter type code "
|
|
3711
3719
|
f"of {self.mtc_participant.meter_type.code}."
|
chellow/reports/report_181.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import csv
|
|
2
|
-
import os
|
|
3
2
|
import threading
|
|
4
3
|
import traceback
|
|
5
4
|
|
|
@@ -10,11 +9,11 @@ from sqlalchemy.sql.expression import null
|
|
|
10
9
|
|
|
11
10
|
from werkzeug.exceptions import BadRequest
|
|
12
11
|
|
|
13
|
-
import chellow.dloads
|
|
14
12
|
import chellow.e.computer
|
|
15
13
|
import chellow.e.duos
|
|
16
14
|
import chellow.e.tnuos
|
|
17
|
-
from chellow.
|
|
15
|
+
from chellow.dloads import open_file
|
|
16
|
+
from chellow.models import Era, Pc, Session, Site, SiteEra, Source, Supply, User
|
|
18
17
|
from chellow.utils import (
|
|
19
18
|
HH,
|
|
20
19
|
c_months_u,
|
|
@@ -144,28 +143,30 @@ def _write_sites(sess, caches, writer, year, site_id):
|
|
|
144
143
|
sess.rollback()
|
|
145
144
|
|
|
146
145
|
|
|
147
|
-
def content(year, site_id,
|
|
146
|
+
def content(year, site_id, user_id):
|
|
148
147
|
caches = {}
|
|
149
148
|
f = writer = None
|
|
150
149
|
try:
|
|
151
150
|
with Session() as sess:
|
|
152
|
-
|
|
153
|
-
f =
|
|
151
|
+
user = User.get_by_id(sess, user_id)
|
|
152
|
+
f = open_file("output.csv", user, mode="w", newline="")
|
|
154
153
|
writer = csv.writer(f, lineterminator="\n")
|
|
155
154
|
_write_sites(sess, caches, writer, year, site_id)
|
|
156
155
|
|
|
157
156
|
except BadRequest as e:
|
|
158
157
|
writer.writerow([e.description])
|
|
159
158
|
except BaseException:
|
|
160
|
-
|
|
159
|
+
msg = traceback.format_exc()
|
|
160
|
+
print(msg)
|
|
161
|
+
if writer is not None:
|
|
162
|
+
writer.writerow([msg])
|
|
161
163
|
finally:
|
|
162
164
|
if f is not None:
|
|
163
165
|
f.close()
|
|
164
|
-
os.rename(running_name, finished_name)
|
|
165
166
|
|
|
166
167
|
|
|
167
168
|
def do_get(sess):
|
|
168
169
|
site_id = req_int("site_id") if "site_id" in request.values else None
|
|
169
170
|
year = req_int("year")
|
|
170
|
-
threading.Thread(target=content, args=(year, site_id, g.user)).start()
|
|
171
|
+
threading.Thread(target=content, args=(year, site_id, g.user.id)).start()
|
|
171
172
|
return chellow_redirect("/downloads", 303)
|
chellow/reports/report_241.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import csv
|
|
2
|
-
import os
|
|
3
2
|
import threading
|
|
4
3
|
import traceback
|
|
5
4
|
from datetime import datetime as Datetime
|
|
@@ -14,8 +13,9 @@ from sqlalchemy.sql.expression import null, or_, true
|
|
|
14
13
|
|
|
15
14
|
from werkzeug.exceptions import BadRequest
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
from chellow.
|
|
16
|
+
from chellow.dloads import open_file
|
|
17
|
+
from chellow.e.computer import SupplySource, contract_func, forecast_date
|
|
18
|
+
from chellow.models import Era, Session, Site, SiteEra, Supply, User
|
|
19
19
|
from chellow.utils import HH, csv_make_val, hh_format, hh_max, hh_min, req_bool, req_int
|
|
20
20
|
from chellow.views import chellow_redirect
|
|
21
21
|
|
|
@@ -29,15 +29,13 @@ def content(
|
|
|
29
29
|
finish_day,
|
|
30
30
|
is_import,
|
|
31
31
|
supply_id,
|
|
32
|
-
|
|
32
|
+
user_id,
|
|
33
33
|
):
|
|
34
34
|
caches = {}
|
|
35
35
|
try:
|
|
36
36
|
with Session() as sess:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
40
|
-
f = open(running_name, mode="w", newline="")
|
|
37
|
+
user = User.get_by_id(sess, user_id)
|
|
38
|
+
f = open_file("daily_supplier_virtual_bill.csv", user, mode="w", newline="")
|
|
41
39
|
writer = csv.writer(f, lineterminator="\n")
|
|
42
40
|
start_date = Datetime(start_year, start_month, start_day, tzinfo=pytz.utc)
|
|
43
41
|
finish_date = (
|
|
@@ -47,7 +45,7 @@ def content(
|
|
|
47
45
|
)
|
|
48
46
|
|
|
49
47
|
supply = Supply.get_by_id(sess, supply_id)
|
|
50
|
-
|
|
48
|
+
fd = forecast_date()
|
|
51
49
|
day_start = start_date
|
|
52
50
|
header_titles = [
|
|
53
51
|
"MPAN Core",
|
|
@@ -71,9 +69,7 @@ def content(
|
|
|
71
69
|
else:
|
|
72
70
|
cont = era.exp_supplier_contract
|
|
73
71
|
|
|
74
|
-
for title in
|
|
75
|
-
caches, cont, "virtual_bill_titles"
|
|
76
|
-
)():
|
|
72
|
+
for title in contract_func(caches, cont, "virtual_bill_titles")():
|
|
77
73
|
if title not in bill_titles:
|
|
78
74
|
bill_titles.append(title)
|
|
79
75
|
|
|
@@ -94,11 +90,11 @@ def content(
|
|
|
94
90
|
chunk_start = hh_max(era.start_date, day_start)
|
|
95
91
|
chunk_finish = hh_min(era.finish_date, day_finish)
|
|
96
92
|
|
|
97
|
-
ss =
|
|
93
|
+
ss = SupplySource(
|
|
98
94
|
sess,
|
|
99
95
|
chunk_start,
|
|
100
96
|
chunk_finish,
|
|
101
|
-
|
|
97
|
+
fd,
|
|
102
98
|
era,
|
|
103
99
|
is_import,
|
|
104
100
|
caches,
|
|
@@ -120,9 +116,7 @@ def content(
|
|
|
120
116
|
ss.years_back > 0,
|
|
121
117
|
]
|
|
122
118
|
|
|
123
|
-
|
|
124
|
-
caches, ss.supplier_contract, "virtual_bill"
|
|
125
|
-
)(ss)
|
|
119
|
+
contract_func(caches, ss.supplier_contract, "virtual_bill")(ss)
|
|
126
120
|
bill = ss.supplier_bill
|
|
127
121
|
for title in bill_titles:
|
|
128
122
|
if title in bill:
|
|
@@ -144,7 +138,6 @@ def content(
|
|
|
144
138
|
finally:
|
|
145
139
|
if f is not None:
|
|
146
140
|
f.close()
|
|
147
|
-
os.rename(running_name, finished_name)
|
|
148
141
|
|
|
149
142
|
|
|
150
143
|
def do_get(sess):
|
|
@@ -159,18 +152,16 @@ def do_get(sess):
|
|
|
159
152
|
is_import = req_bool("is_import")
|
|
160
153
|
supply_id = req_int("supply_id")
|
|
161
154
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
),
|
|
175
|
-
).start()
|
|
155
|
+
args = (
|
|
156
|
+
start_year,
|
|
157
|
+
start_month,
|
|
158
|
+
start_day,
|
|
159
|
+
finish_year,
|
|
160
|
+
finish_month,
|
|
161
|
+
finish_day,
|
|
162
|
+
is_import,
|
|
163
|
+
supply_id,
|
|
164
|
+
g.user.id,
|
|
165
|
+
)
|
|
166
|
+
threading.Thread(target=content, args=args).start()
|
|
176
167
|
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
|
|
@@ -13,8 +12,8 @@ from sqlalchemy.sql.expression import null
|
|
|
13
12
|
|
|
14
13
|
from werkzeug.exceptions import BadRequest
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
from chellow.models import Contract, Era, ReportRun, Session, Site, SiteEra
|
|
15
|
+
from chellow.dloads import open_file
|
|
16
|
+
from chellow.models import Contract, Era, ReportRun, Session, Site, SiteEra, User
|
|
18
17
|
from chellow.views import chellow_redirect
|
|
19
18
|
|
|
20
19
|
STATUSES_ACTIVE = ("IN USE / IN SERVICE", "STORED SPARE")
|
|
@@ -147,13 +146,12 @@ def _process_sites(sess, file_like, writer, props, report_run):
|
|
|
147
146
|
FNAME = "asset_comparison"
|
|
148
147
|
|
|
149
148
|
|
|
150
|
-
def content(
|
|
149
|
+
def content(user_id, file_like, report_run_id):
|
|
150
|
+
f = report_run = writer = None
|
|
151
151
|
try:
|
|
152
152
|
with Session() as sess:
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
)
|
|
156
|
-
f = open(running_name, mode="w", newline="")
|
|
153
|
+
user = User.get_by_id(sess, user_id)
|
|
154
|
+
f = open_file(f"{FNAME}.csv", user, mode="w", newline="")
|
|
157
155
|
writer = csv.writer(f, lineterminator="\n")
|
|
158
156
|
report_run = ReportRun.get_by_id(sess, report_run_id)
|
|
159
157
|
|
|
@@ -171,11 +169,11 @@ def content(user, file_like, report_run_id):
|
|
|
171
169
|
report_run.insert_row(sess, "", ["error"], {"error": msg}, {})
|
|
172
170
|
sess.commit()
|
|
173
171
|
sys.stderr.write(msg)
|
|
174
|
-
writer
|
|
172
|
+
if writer is not None:
|
|
173
|
+
writer.writerow([msg])
|
|
175
174
|
finally:
|
|
176
175
|
if f is not None:
|
|
177
176
|
f.close()
|
|
178
|
-
os.rename(running_name, finished_name)
|
|
179
177
|
|
|
180
178
|
|
|
181
179
|
def do_post(sess):
|
|
@@ -194,6 +192,6 @@ def do_post(sess):
|
|
|
194
192
|
},
|
|
195
193
|
)
|
|
196
194
|
sess.commit()
|
|
197
|
-
args = user, StringIO(file_item.read().decode("utf8")), report_run.id
|
|
195
|
+
args = user.id, StringIO(file_item.read().decode("utf8")), report_run.id
|
|
198
196
|
threading.Thread(target=content, args=args).start()
|
|
199
197
|
return chellow_redirect(f"/report_runs/{report_run.id}", 303)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import csv
|
|
2
|
-
import os
|
|
3
2
|
import threading
|
|
4
3
|
import traceback
|
|
5
4
|
|
|
@@ -7,18 +6,18 @@ from flask import g
|
|
|
7
6
|
|
|
8
7
|
from sqlalchemy.orm import joinedload
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
from chellow.models import Llfc, Session
|
|
9
|
+
from chellow.dloads import open_file
|
|
10
|
+
from chellow.models import Llfc, Session, User
|
|
12
11
|
from chellow.utils import hh_format
|
|
13
12
|
from chellow.views import chellow_redirect
|
|
14
13
|
|
|
15
14
|
|
|
16
|
-
def content(
|
|
15
|
+
def content(user_id):
|
|
17
16
|
f = writer = None
|
|
18
17
|
try:
|
|
19
18
|
with Session() as sess:
|
|
20
|
-
|
|
21
|
-
f =
|
|
19
|
+
user = User.get_by_id(sess, user_id)
|
|
20
|
+
f = open_file("llfcs.csv", user, mode="w", newline="")
|
|
22
21
|
writer = csv.writer(f, lineterminator="\n")
|
|
23
22
|
writer.writerow(
|
|
24
23
|
(
|
|
@@ -53,14 +52,16 @@ def content(user):
|
|
|
53
52
|
)
|
|
54
53
|
)
|
|
55
54
|
except BaseException:
|
|
56
|
-
|
|
55
|
+
msg = traceback.format_exc()
|
|
56
|
+
print(msg)
|
|
57
|
+
if writer is not None:
|
|
58
|
+
writer.writerow([msg])
|
|
57
59
|
finally:
|
|
58
60
|
if f is not None:
|
|
59
61
|
f.close()
|
|
60
|
-
os.rename(running_name, finished_name)
|
|
61
62
|
|
|
62
63
|
|
|
63
64
|
def do_get(sess):
|
|
64
|
-
args = (g.user,)
|
|
65
|
+
args = (g.user.id,)
|
|
65
66
|
threading.Thread(target=content, args=args).start()
|
|
66
67
|
return chellow_redirect("/downloads", 303)
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import csv
|
|
2
|
-
import os
|
|
3
|
-
import sys
|
|
4
2
|
import threading
|
|
5
3
|
import traceback
|
|
6
4
|
from datetime import datetime as Datetime, timedelta as Timedelta
|
|
@@ -12,20 +10,18 @@ import pytz
|
|
|
12
10
|
from sqlalchemy.orm import joinedload
|
|
13
11
|
from sqlalchemy.sql.expression import null
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
from chellow.models import Session, Site, Snag
|
|
13
|
+
from chellow.dloads import open_file
|
|
14
|
+
from chellow.models import Session, Site, Snag, User
|
|
17
15
|
from chellow.utils import hh_format
|
|
18
16
|
from chellow.views import chellow_redirect
|
|
19
17
|
|
|
20
18
|
|
|
21
|
-
def content(
|
|
19
|
+
def content(user_id):
|
|
22
20
|
f = writer = None
|
|
23
21
|
try:
|
|
24
22
|
with Session() as sess:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
28
|
-
f = open(running_name, mode="w", newline="")
|
|
23
|
+
user = User.get_by_id(sess, user_id)
|
|
24
|
+
f = open_file("site_snags.csv", user, mode="w", newline="")
|
|
29
25
|
writer = csv.writer(f, lineterminator="\n")
|
|
30
26
|
writer.writerow(
|
|
31
27
|
(
|
|
@@ -74,15 +70,15 @@ def content(user):
|
|
|
74
70
|
)
|
|
75
71
|
except BaseException:
|
|
76
72
|
msg = traceback.format_exc()
|
|
77
|
-
|
|
78
|
-
writer
|
|
73
|
+
print(msg)
|
|
74
|
+
if writer is not None:
|
|
75
|
+
writer.writerow([msg])
|
|
79
76
|
finally:
|
|
80
77
|
if f is not None:
|
|
81
78
|
f.close()
|
|
82
|
-
os.rename(running_name, finished_name)
|
|
83
79
|
|
|
84
80
|
|
|
85
81
|
def do_get(sess):
|
|
86
|
-
args = (g.user,)
|
|
82
|
+
args = (g.user.id,)
|
|
87
83
|
threading.Thread(target=content, args=args).start()
|
|
88
84
|
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,10 +11,10 @@ from sqlalchemy.sql.expression import null, true
|
|
|
12
11
|
|
|
13
12
|
from werkzeug.exceptions import BadRequest
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
from chellow.dloads import open_file
|
|
16
15
|
from chellow.e.computer import contract_func, forecast_date
|
|
17
16
|
from chellow.gas.engine import GDataSource
|
|
18
|
-
from chellow.models import GContract, GEra, Session, Site, SiteGEra
|
|
17
|
+
from chellow.models import GContract, GEra, Session, Site, SiteGEra, User
|
|
19
18
|
from chellow.utils import (
|
|
20
19
|
c_months_u,
|
|
21
20
|
hh_format,
|
|
@@ -29,14 +28,13 @@ from chellow.utils import (
|
|
|
29
28
|
from chellow.views import chellow_redirect
|
|
30
29
|
|
|
31
30
|
|
|
32
|
-
def content(start_date, finish_date, g_contract_id,
|
|
31
|
+
def content(start_date, finish_date, g_contract_id, user_id):
|
|
33
32
|
report_context = {}
|
|
33
|
+
f = writer = None
|
|
34
34
|
try:
|
|
35
35
|
with Session() as sess:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
)
|
|
39
|
-
f = open(running_name, mode="w", newline="")
|
|
36
|
+
user = User.get_by_id(sess, user_id)
|
|
37
|
+
f = open_file("gas_virtual_bills.csv", user, mode="w", newline="")
|
|
40
38
|
writer = csv.writer(f, lineterminator="\n")
|
|
41
39
|
|
|
42
40
|
g_contract = GContract.get_by_id(sess, g_contract_id)
|
|
@@ -125,11 +123,11 @@ def content(start_date, finish_date, g_contract_id, user):
|
|
|
125
123
|
except BaseException:
|
|
126
124
|
msg = traceback.format_exc()
|
|
127
125
|
sys.stderr.write(msg)
|
|
128
|
-
writer
|
|
126
|
+
if writer is not None:
|
|
127
|
+
writer.writerow([msg])
|
|
129
128
|
finally:
|
|
130
129
|
if f is not None:
|
|
131
130
|
f.close()
|
|
132
|
-
os.rename(running_name, finished_name)
|
|
133
131
|
|
|
134
132
|
|
|
135
133
|
def do_get(sess):
|
|
@@ -137,7 +135,6 @@ def do_get(sess):
|
|
|
137
135
|
finish_date = req_date("finish")
|
|
138
136
|
g_contract_id = req_int("g_contract_id")
|
|
139
137
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
).start()
|
|
138
|
+
args = start_date, finish_date, g_contract_id, g.user.id
|
|
139
|
+
threading.Thread(target=content, args=args).start()
|
|
143
140
|
return chellow_redirect("/downloads", 303)
|
chellow/reports/report_sscs.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import sys
|
|
3
2
|
import threading
|
|
4
3
|
import traceback
|
|
@@ -13,7 +12,7 @@ from sqlalchemy.orm import joinedload
|
|
|
13
12
|
|
|
14
13
|
from werkzeug.exceptions import BadRequest
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
from chellow.dloads import open_file
|
|
17
16
|
from chellow.models import MeasurementRequirement, Session, Ssc, Tpr, User
|
|
18
17
|
from chellow.utils import req_bool
|
|
19
18
|
from chellow.views import chellow_redirect
|
|
@@ -54,9 +53,7 @@ def content(
|
|
|
54
53
|
with Session() as sess:
|
|
55
54
|
user = User.get_by_id(sess, user_id)
|
|
56
55
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
rf = open(running_name, "wb")
|
|
56
|
+
rf = open_file("sscs.ods", user, "wb")
|
|
60
57
|
|
|
61
58
|
for ssc in sess.scalars(select(Ssc).order_by(Ssc.code)):
|
|
62
59
|
ssc_rows.append(
|
|
@@ -100,8 +97,7 @@ def content(
|
|
|
100
97
|
ssc_rows.append(["Problem " + msg])
|
|
101
98
|
if rf is None:
|
|
102
99
|
msg = traceback.format_exc()
|
|
103
|
-
|
|
104
|
-
ef = open(r_name, "w")
|
|
100
|
+
ef = open_file("error.txt", None, "w")
|
|
105
101
|
ef.write(msg + "\n")
|
|
106
102
|
ef.close()
|
|
107
103
|
else:
|
|
@@ -109,7 +105,6 @@ def content(
|
|
|
109
105
|
finally:
|
|
110
106
|
if rf is not None:
|
|
111
107
|
rf.close()
|
|
112
|
-
os.rename(running_name, finished_name)
|
|
113
108
|
|
|
114
109
|
|
|
115
110
|
def do_get(sess):
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import csv
|
|
2
|
-
import os
|
|
3
2
|
import sys
|
|
4
3
|
import threading
|
|
5
4
|
import traceback
|
|
@@ -10,7 +9,7 @@ from sqlalchemy import select
|
|
|
10
9
|
from sqlalchemy.orm import joinedload
|
|
11
10
|
from sqlalchemy.sql.expression import null
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
from chellow.dloads import open_file
|
|
14
13
|
from chellow.models import (
|
|
15
14
|
Contract,
|
|
16
15
|
Era,
|
|
@@ -33,10 +32,7 @@ def content(user_id, report_run_id):
|
|
|
33
32
|
try:
|
|
34
33
|
with Session() as sess:
|
|
35
34
|
user = User.get_by_id(sess, user_id)
|
|
36
|
-
|
|
37
|
-
f"{FNAME}.csv", user
|
|
38
|
-
)
|
|
39
|
-
f = open(running_name, mode="w", newline="")
|
|
35
|
+
f = open_file(f"{FNAME}.csv", user, mode="w", newline="")
|
|
40
36
|
report_run = ReportRun.get_by_id(sess, report_run_id)
|
|
41
37
|
|
|
42
38
|
_process(sess, f, report_run)
|
|
@@ -56,7 +52,6 @@ def content(user_id, report_run_id):
|
|
|
56
52
|
finally:
|
|
57
53
|
if f is not None:
|
|
58
54
|
f.close()
|
|
59
|
-
os.rename(running_name, finished_name)
|
|
60
55
|
|
|
61
56
|
|
|
62
57
|
def _process(sess, f, report_run):
|
|
@@ -129,13 +124,7 @@ def _process(sess, f, report_run):
|
|
|
129
124
|
|
|
130
125
|
|
|
131
126
|
def do_get(sess):
|
|
132
|
-
report_run = ReportRun.insert(
|
|
133
|
-
sess,
|
|
134
|
-
FNAME,
|
|
135
|
-
g.user,
|
|
136
|
-
FNAME,
|
|
137
|
-
{},
|
|
138
|
-
)
|
|
127
|
+
report_run = ReportRun.insert(sess, FNAME, g.user, FNAME, {})
|
|
139
128
|
sess.commit()
|
|
140
129
|
threading.Thread(target=content, args=(g.user.id, report_run.id)).start()
|
|
141
130
|
return chellow_redirect(f"/report_runs/{report_run.id}", 303)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: chellow
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1712589951.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)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
chellow/__init__.py,sha256=
|
|
1
|
+
chellow/__init__.py,sha256=A6gh-jVJBhuCFmfquLEa8uf-kQhsRSFficE1SlnHnAg,10200
|
|
2
2
|
chellow/api.py,sha256=mk17TfweR76DPFC8lX2SArTjai6y6YshASxqO1w-_-s,11036
|
|
3
3
|
chellow/bank_holidays.py,sha256=T_utYMwe_g1dz5X-aOTdIPryg49SvB7QsWM1yphlqG8,4423
|
|
4
4
|
chellow/commands.py,sha256=ESBe9ZWj1c3vdZgqMZ9gFvYAB3hRag2R1PzOwuw9yFo,1302
|
|
5
|
-
chellow/dloads.py,sha256=
|
|
5
|
+
chellow/dloads.py,sha256=5SmP-0QPK6xCkd_wjIWh_8FAzN5OxNHCzyEQ1Xb-Y-M,5256
|
|
6
6
|
chellow/edi_lib.py,sha256=het3R0DBGtXEo-Sy1zvXQuX9EWQ1X6Y33G4l1hYYuds,51859
|
|
7
7
|
chellow/general_import.py,sha256=4LduwzNipxOiHYHQLb0x96_m3RPuDnQMbJzOFDbOqTg,65039
|
|
8
|
-
chellow/models.py,sha256=
|
|
8
|
+
chellow/models.py,sha256=j26jxohyZ09tWVOAnWRFl0k0QUVRX0nDthIIDJpo7cE,237327
|
|
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=vNuKzlr0lkAzZ4zG7zboStoo92_6iLKAxbw1yZ-ucII,5626
|
|
@@ -38,7 +38,7 @@ chellow/e/system_price.py,sha256=3cPWohHmmBI9v7fENLBzXQkpAeC3r0s5xV29Nmr6k_E,583
|
|
|
38
38
|
chellow/e/tlms.py,sha256=kHAy2A2d1Mma7x4GdNDyrzscJd5DpJtDBYiZEg241Dw,8538
|
|
39
39
|
chellow/e/tnuos.py,sha256=KoMPJDIXfE4zwhSDuywGF1ooxjTYLVjtF7BkSFm6X24,4158
|
|
40
40
|
chellow/e/triad.py,sha256=S6LEMHvUKhAZe0-yfLIRciYDZ8IKMn1jh1TmmsbQD3s,13588
|
|
41
|
-
chellow/e/views.py,sha256=
|
|
41
|
+
chellow/e/views.py,sha256=p-zQa24HtNVLTHILqfiZ8UrixuljHSC163SrJuLQ3Ik,212590
|
|
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
|
|
@@ -69,15 +69,13 @@ chellow/reports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
69
69
|
chellow/reports/report_109.py,sha256=S8fsOwh-jVWGL0RsgyYLdqn00BAvlkBbi4VfTSGI-Mc,11181
|
|
70
70
|
chellow/reports/report_111.py,sha256=qU5MYPQzZ_cEvuERE8bxq93D-dN1yd4oML6FIqd0Jdk,28278
|
|
71
71
|
chellow/reports/report_169.py,sha256=tnTiHmhigcgZ7E8rUSfgzsVYUCW947xBZZq04-KqfK8,9287
|
|
72
|
-
chellow/reports/
|
|
73
|
-
chellow/reports/report_181.py,sha256=Fm2kgqjZvTVU31H6KVBVg3bqcGPHomJG82KXa7I7k4E,4989
|
|
72
|
+
chellow/reports/report_181.py,sha256=mCL6vXfrj8r0kL-LilDS0SnSu5tJOzCq7eMJVx9zpEw,4999
|
|
74
73
|
chellow/reports/report_183.py,sha256=DZX-hHJPl_Tbgkt31C_cuLZg_5L2b6iCPQ5foOZizR0,8817
|
|
75
74
|
chellow/reports/report_187.py,sha256=UvpaYHjyJFNV5puYq8_KxfzoBtVrwFgIGUOmC5oGA9A,9956
|
|
76
|
-
chellow/reports/report_215.py,sha256=_HZO_MhL51ttzmG6IrT8YVG6WmJMkRNWsXOW7AL7GWs,6766
|
|
77
75
|
chellow/reports/report_219.py,sha256=o2eEg3mX9_raP2b4gjc2Gu4vqnMqcvvJBYQ1oQjxvpE,6637
|
|
78
76
|
chellow/reports/report_231.py,sha256=gOb1AkXZQvwVpRg5cIenO7iR7Se1_zsWnJp9l2BlgpA,5008
|
|
79
77
|
chellow/reports/report_233.py,sha256=DLAmkoHFKH-N8OEIoX4jeCxAaCfJK0e7ssjFJJpPqzw,4334
|
|
80
|
-
chellow/reports/report_241.py,sha256=
|
|
78
|
+
chellow/reports/report_241.py,sha256=AlFmSHnfG2HWv_ICmWX7fNpPwLHjq7mo1QtOTjSKO3k,5384
|
|
81
79
|
chellow/reports/report_247.py,sha256=ozgCcee8XeqYbOpZCyU2STJKaz6h2x7TYQogagTaYLw,46626
|
|
82
80
|
chellow/reports/report_29.py,sha256=KDFjgrLBv4WbG9efCdu_geMR7gT_QV9N97Wfdt7aDc4,2736
|
|
83
81
|
chellow/reports/report_291.py,sha256=rqBXy6s7hMeYWw-yNX6w_L5t2yz6rNEeos_4xO7wf90,7519
|
|
@@ -88,20 +86,20 @@ chellow/reports/report_429.py,sha256=0GCc0rQnOSG0fusw69yMMOCxnWApBd3P2sGWIg1py9M
|
|
|
88
86
|
chellow/reports/report_59.py,sha256=21uNlcuYQCOAvrRir241HR-6SsuL9bWEPVCcU_jOxfE,44731
|
|
89
87
|
chellow/reports/report_81.py,sha256=UYr0Dm4TmCCYUbIWw3hWNI0GdQRhH27vwVk3Ytdsrcg,5288
|
|
90
88
|
chellow/reports/report_87.py,sha256=ZadBo40rUORN0Fi926-dDHeTFn6L-fBzp3b4k7v5MdY,6802
|
|
91
|
-
chellow/reports/report_asset_comparison.py,sha256=
|
|
89
|
+
chellow/reports/report_asset_comparison.py,sha256=UN298MHuzyUDUiiZr7F_Ua6SrdVOlFLjgKjnIbrA-14,6118
|
|
92
90
|
chellow/reports/report_batches.py,sha256=7O5TcB9W1sPKS0LQMsC6sUDzx73X5iyoZE0O3zK91zs,4798
|
|
93
91
|
chellow/reports/report_bills.py,sha256=AHW6tiZAOE0gXDfencPvemE4zqK6eTqfN8_bWQ4RT5o,3323
|
|
94
|
-
chellow/reports/report_csv_llfcs.py,sha256=
|
|
92
|
+
chellow/reports/report_csv_llfcs.py,sha256=OHSbP64lQ6dlAMcQYgvdANlA4lQyF0iBlwk7V9c9nuo,1944
|
|
95
93
|
chellow/reports/report_csv_site_hh_data.py,sha256=T-clGDmYdn0ej7zZfL3kDp4Vyd82WzptxEzxx9KqAZg,4270
|
|
96
|
-
chellow/reports/report_csv_site_snags.py,sha256=
|
|
94
|
+
chellow/reports/report_csv_site_snags.py,sha256=gG2sYQrLoIBwCoMUC8rhmAL7Kffh_rvNb9UOX7cYDko,2668
|
|
97
95
|
chellow/reports/report_ecoes_comparison.py,sha256=bTkbcvNB__UcNQtHncC41_Ql222vvPTJTnyVJbgjylM,21313
|
|
98
96
|
chellow/reports/report_g_monthly_duration.py,sha256=vI5FKAU8_oThjR5oflPZont7Z7sVAunr0qlMfJsaPJI,12004
|
|
99
97
|
chellow/reports/report_g_supplies_snapshot.py,sha256=0M0x_0o0985Hu45gUJJJwzfx0DDOAuXBJ1UVUDbQ36g,4718
|
|
100
98
|
chellow/reports/report_g_supply_virtual_bill.py,sha256=x_KtQ02dwgmXvAEUXJ1poK0BRwqxa-GcbJ5pddEina0,3694
|
|
101
|
-
chellow/reports/report_g_virtual_bills.py,sha256=
|
|
99
|
+
chellow/reports/report_g_virtual_bills.py,sha256=t3hmTiURk1E_mPucIboCdPBlSLapDIUdHYRpVTFtJgw,4569
|
|
102
100
|
chellow/reports/report_g_virtual_bills_hh.py,sha256=5crgu7oUrOSR9GAA1uhb8lJNn4gCUSBAaXci1gOuohE,3457
|
|
103
|
-
chellow/reports/report_sscs.py,sha256=
|
|
104
|
-
chellow/reports/report_supply_contacts.py,sha256=
|
|
101
|
+
chellow/reports/report_sscs.py,sha256=beCzKpaQaeeiyMGpX6o-gbl1tCS6ArdF1o4GeIQE67s,3255
|
|
102
|
+
chellow/reports/report_supply_contacts.py,sha256=vyA3mLWqYISwOuRhzRIYQIWmvWXS1Vv_rJClq2IFBiw,3640
|
|
105
103
|
chellow/static/css/chellow.css,sha256=mcLjqKMo0qtdQWY7AnXEL8Bvx2B-Pu8kcGO58bUXOpY,5372
|
|
106
104
|
chellow/static/images/favicon.svg,sha256=ySFHoVJYmr-xU93QrE-jLYn-ZNythh2vsemnR8dkvg0,2339
|
|
107
105
|
chellow/static/images/favicon_test.svg,sha256=HnLS_BjNt8M0Ikko5Z-f_E2aed7y6RRU6j3K6XADciE,2346
|
|
@@ -363,6 +361,6 @@ chellow/templates/g/supply_note_edit.html,sha256=6UQf_qbhFDys3cVsTp-c7ABWZpggW9R
|
|
|
363
361
|
chellow/templates/g/supply_notes.html,sha256=WR3YwGh_qqTklSJ7JqWX6BKBc9rk_jMff4RiWZiF2CM,936
|
|
364
362
|
chellow/templates/g/unit.html,sha256=KouNVU0-i84afANkLQ_heJ0uDfJ9H5A05PuLqb8iCN8,438
|
|
365
363
|
chellow/templates/g/units.html,sha256=p5Nd-lAIboKPEOO6N451hx1bcKxMg4BDODnZ-43MmJc,441
|
|
366
|
-
chellow-
|
|
367
|
-
chellow-
|
|
368
|
-
chellow-
|
|
364
|
+
chellow-1712589951.0.0.dist-info/METADATA,sha256=7i4xrwuQ86GNArcYRVjMgd8c2k9pbTy5yW8XWSKvrTY,12203
|
|
365
|
+
chellow-1712589951.0.0.dist-info/WHEEL,sha256=as-1oFTWSeWBgyzh0O_qF439xqBe6AbBgt4MfYe5zwY,87
|
|
366
|
+
chellow-1712589951.0.0.dist-info/RECORD,,
|
chellow/reports/report_177.py
DELETED
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import threading
|
|
3
|
-
import time
|
|
4
|
-
import traceback
|
|
5
|
-
from datetime import datetime as Datetime
|
|
6
|
-
|
|
7
|
-
from dateutil.relativedelta import relativedelta
|
|
8
|
-
|
|
9
|
-
from flask import g, request
|
|
10
|
-
|
|
11
|
-
import pytz
|
|
12
|
-
|
|
13
|
-
from sqlalchemy import Float, cast, func, or_
|
|
14
|
-
from sqlalchemy.orm import joinedload
|
|
15
|
-
from sqlalchemy.sql.expression import null, true
|
|
16
|
-
|
|
17
|
-
import chellow.computer
|
|
18
|
-
import chellow.dloads
|
|
19
|
-
from chellow.models import Bill, Channel, Era, HhDatum, Session, Site, SiteEra, Supply
|
|
20
|
-
from chellow.utils import HH, hh_format, hh_max, hh_min, req_int
|
|
21
|
-
from chellow.views import chellow_redirect
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def _content(sess, tmp_file, year, month, months, supply_id, user):
|
|
25
|
-
supplies = (
|
|
26
|
-
sess.query(Supply)
|
|
27
|
-
.join(Era)
|
|
28
|
-
.distinct()
|
|
29
|
-
.options(joinedload(Supply.generator_type))
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
if supply_id is not None:
|
|
33
|
-
supply = Supply.get_by_id(sess, supply_id)
|
|
34
|
-
supplies = supplies.filter(Supply.id == supply.id)
|
|
35
|
-
|
|
36
|
-
caches = {}
|
|
37
|
-
|
|
38
|
-
start_date = Datetime(year, month, 1, tzinfo=pytz.utc) - relativedelta(
|
|
39
|
-
months=months - 1
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
field_names = (
|
|
43
|
-
"supply-name",
|
|
44
|
-
"source-code",
|
|
45
|
-
"generator-type",
|
|
46
|
-
"month",
|
|
47
|
-
"pc-code",
|
|
48
|
-
"msn",
|
|
49
|
-
"site-code",
|
|
50
|
-
"site-name",
|
|
51
|
-
"metering-type",
|
|
52
|
-
"import-mpan-core",
|
|
53
|
-
"metered-import-kwh",
|
|
54
|
-
"metered-import-net-gbp",
|
|
55
|
-
"metered-import-estimated-kwh",
|
|
56
|
-
"billed-import-kwh",
|
|
57
|
-
"billed-import-net-gbp",
|
|
58
|
-
"export-mpan-core",
|
|
59
|
-
"metered-export-kwh",
|
|
60
|
-
"metered-export-estimated-kwh",
|
|
61
|
-
"billed-export-kwh",
|
|
62
|
-
"billed-export-net-gbp",
|
|
63
|
-
"problem",
|
|
64
|
-
"timestamp",
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
tmp_file.write("supply-id," + ",".join(field_names) + "\n")
|
|
68
|
-
|
|
69
|
-
forecast_date = chellow.computer.forecast_date()
|
|
70
|
-
|
|
71
|
-
for i in range(months):
|
|
72
|
-
month_start = start_date + relativedelta(months=i)
|
|
73
|
-
month_finish = month_start + relativedelta(months=1) - HH
|
|
74
|
-
|
|
75
|
-
for supply in supplies.filter(
|
|
76
|
-
Era.start_date <= month_finish,
|
|
77
|
-
or_(Era.finish_date == null(), Era.finish_date >= month_start),
|
|
78
|
-
):
|
|
79
|
-
generator_type = supply.generator_type
|
|
80
|
-
if generator_type is None:
|
|
81
|
-
generator_type = ""
|
|
82
|
-
else:
|
|
83
|
-
generator_type = generator_type.code
|
|
84
|
-
|
|
85
|
-
source_code = supply.source.code
|
|
86
|
-
eras = supply.find_eras(sess, month_start, month_finish)
|
|
87
|
-
era = eras[-1]
|
|
88
|
-
metering_type = era.meter_category
|
|
89
|
-
|
|
90
|
-
site = (
|
|
91
|
-
sess.query(Site)
|
|
92
|
-
.join(SiteEra)
|
|
93
|
-
.filter(SiteEra.era == era, SiteEra.is_physical == true())
|
|
94
|
-
.one()
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
values = {
|
|
98
|
-
"supply-name": supply.name,
|
|
99
|
-
"source-code": source_code,
|
|
100
|
-
"generator-type": generator_type,
|
|
101
|
-
"month": hh_format(month_finish),
|
|
102
|
-
"pc-code": era.pc.code,
|
|
103
|
-
"msn": era.msn,
|
|
104
|
-
"site-code": site.code,
|
|
105
|
-
"site-name": site.name,
|
|
106
|
-
"metering-type": metering_type,
|
|
107
|
-
"problem": "",
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
tmp_file.write(str(supply.id) + ",")
|
|
111
|
-
|
|
112
|
-
for is_import, pol_name in [(True, "import"), (False, "export")]:
|
|
113
|
-
if is_import:
|
|
114
|
-
mpan_core = era.imp_mpan_core
|
|
115
|
-
else:
|
|
116
|
-
mpan_core = era.exp_mpan_core
|
|
117
|
-
|
|
118
|
-
values[pol_name + "-mpan-core"] = mpan_core
|
|
119
|
-
kwh = 0
|
|
120
|
-
est_kwh = 0
|
|
121
|
-
|
|
122
|
-
if metering_type in ["hh", "amr"]:
|
|
123
|
-
est_kwh = (
|
|
124
|
-
sess.query(HhDatum.value)
|
|
125
|
-
.join(Channel)
|
|
126
|
-
.join(Era)
|
|
127
|
-
.filter(
|
|
128
|
-
HhDatum.status == "E",
|
|
129
|
-
Era.supply_id == supply.id,
|
|
130
|
-
Channel.channel_type == "ACTIVE",
|
|
131
|
-
Channel.imp_related == is_import,
|
|
132
|
-
HhDatum.start_date >= month_start,
|
|
133
|
-
HhDatum.start_date <= month_finish,
|
|
134
|
-
)
|
|
135
|
-
.first()
|
|
136
|
-
)
|
|
137
|
-
if est_kwh is None:
|
|
138
|
-
est_kwh = 0
|
|
139
|
-
else:
|
|
140
|
-
est_kwh = est_kwh[0]
|
|
141
|
-
|
|
142
|
-
if not (is_import and source_code in ("net", "gen-net")):
|
|
143
|
-
kwh_sum = (
|
|
144
|
-
sess.query(cast(func.sum(HhDatum.value), Float))
|
|
145
|
-
.join(Channel)
|
|
146
|
-
.join(Era)
|
|
147
|
-
.filter(
|
|
148
|
-
Era.supply_id == supply.id,
|
|
149
|
-
Channel.channel_type == "ACTIVE",
|
|
150
|
-
Channel.imp_related == is_import,
|
|
151
|
-
HhDatum.start_date >= month_start,
|
|
152
|
-
HhDatum.start_date <= month_finish,
|
|
153
|
-
)
|
|
154
|
-
.one()[0]
|
|
155
|
-
)
|
|
156
|
-
if kwh_sum is not None:
|
|
157
|
-
kwh += kwh_sum
|
|
158
|
-
|
|
159
|
-
values["metered-" + pol_name + "-estimated-kwh"] = est_kwh
|
|
160
|
-
values["metered-" + pol_name + "-kwh"] = kwh
|
|
161
|
-
values["metered-" + pol_name + "-net-gbp"] = 0
|
|
162
|
-
values["billed-" + pol_name + "-kwh"] = 0
|
|
163
|
-
values["billed-" + pol_name + "-net-gbp"] = 0
|
|
164
|
-
values["billed-" + pol_name + "-apportioned-kwh"] = 0
|
|
165
|
-
values["billed-" + pol_name + "-apportioned-net-gbp"] = 0
|
|
166
|
-
values["billed-" + pol_name + "-raw-kwh"] = 0
|
|
167
|
-
values["billed-" + pol_name + "-raw-net-gbp"] = 0
|
|
168
|
-
|
|
169
|
-
for bill in sess.query(Bill).filter(
|
|
170
|
-
Bill.supply == supply,
|
|
171
|
-
Bill.start_date <= month_finish,
|
|
172
|
-
Bill.finish_date >= month_start,
|
|
173
|
-
):
|
|
174
|
-
bill_start = bill.start_date
|
|
175
|
-
bill_finish = bill.finish_date
|
|
176
|
-
bill_duration = (bill_finish - bill_start).total_seconds() + 30 * 60
|
|
177
|
-
overlap_duration = (
|
|
178
|
-
min(bill_finish, month_finish) - max(bill_start, month_start)
|
|
179
|
-
).total_seconds() + 30 * 60
|
|
180
|
-
overlap_proportion = float(overlap_duration) / float(bill_duration)
|
|
181
|
-
values["billed-import-net-gbp"] += overlap_proportion * float(bill.net)
|
|
182
|
-
values["billed-import-kwh"] += overlap_proportion * float(bill.kwh)
|
|
183
|
-
|
|
184
|
-
for era in eras:
|
|
185
|
-
chunk_start = hh_max(era.start_date, month_start)
|
|
186
|
-
chunk_finish = hh_min(era.finish_date, month_finish)
|
|
187
|
-
|
|
188
|
-
import_mpan_core = era.imp_mpan_core
|
|
189
|
-
if import_mpan_core is None:
|
|
190
|
-
continue
|
|
191
|
-
|
|
192
|
-
supplier_contract = era.imp_supplier_contract
|
|
193
|
-
|
|
194
|
-
if source_code in ["net", "gen-net", "3rd-party"]:
|
|
195
|
-
supply_source = chellow.computer.SupplySource(
|
|
196
|
-
sess,
|
|
197
|
-
chunk_start,
|
|
198
|
-
chunk_finish,
|
|
199
|
-
forecast_date,
|
|
200
|
-
era,
|
|
201
|
-
True,
|
|
202
|
-
caches,
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
values["metered-import-kwh"] += sum(
|
|
206
|
-
datum["msp-kwh"] for datum in supply_source.hh_data
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
import_vb_function = supply_source.contract_func(
|
|
210
|
-
supplier_contract, "virtual_bill"
|
|
211
|
-
)
|
|
212
|
-
if import_vb_function is None:
|
|
213
|
-
values["problem"] += (
|
|
214
|
-
"Can't find the "
|
|
215
|
-
"virtual_bill function in the supplier "
|
|
216
|
-
"contract. "
|
|
217
|
-
)
|
|
218
|
-
else:
|
|
219
|
-
import_vb_function(supply_source)
|
|
220
|
-
values["metered-import-net-gbp"] += supply_source.supplier_bill[
|
|
221
|
-
"net-gbp"
|
|
222
|
-
]
|
|
223
|
-
|
|
224
|
-
supply_source.contract_func(era.dc_contract, "virtual_bill")(
|
|
225
|
-
supply_source
|
|
226
|
-
)
|
|
227
|
-
values["metered-import-net-gbp"] += supply_source.dc_bill["net-gbp"]
|
|
228
|
-
|
|
229
|
-
mop_func = supply_source.contract_func(
|
|
230
|
-
era.mop_contract, "virtual_bill"
|
|
231
|
-
)
|
|
232
|
-
if mop_func is None:
|
|
233
|
-
values["problem"] += (
|
|
234
|
-
" MOP virtual_bill " "function can't be found."
|
|
235
|
-
)
|
|
236
|
-
else:
|
|
237
|
-
mop_func(supply_source)
|
|
238
|
-
mop_bill = supply_source.mop_bill
|
|
239
|
-
values["metered-import-net-gbp"] += mop_bill["net-gbp"]
|
|
240
|
-
if len(mop_bill["problem"]) > 0:
|
|
241
|
-
values["problem"] += (
|
|
242
|
-
" MOP virtual bill problem: " + mop_bill["problem"]
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
values["timestamp"] = int(time.time() * 1000)
|
|
246
|
-
tmp_file.write(
|
|
247
|
-
",".join('"' + str(values[name]) + '"' for name in field_names) + "\n"
|
|
248
|
-
)
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
def content(year, month, months, supply_id, user):
|
|
252
|
-
tmp_file = None
|
|
253
|
-
try:
|
|
254
|
-
with Session() as sess:
|
|
255
|
-
if supply_id is None:
|
|
256
|
-
base_name = (
|
|
257
|
-
f"supplies_monthly_duration_for_all_supplies_for_{months}_to_"
|
|
258
|
-
f"{year}_{month}.csv"
|
|
259
|
-
)
|
|
260
|
-
else:
|
|
261
|
-
base_name = (
|
|
262
|
-
f"supplies_monthly_duration_for_{supply_id}_{months}_to_{year}_"
|
|
263
|
-
f"{month}.csv"
|
|
264
|
-
)
|
|
265
|
-
running_name, finished_name = chellow.dloads.make_names(base_name, user)
|
|
266
|
-
|
|
267
|
-
tmp_file = open(running_name, "w")
|
|
268
|
-
_content(sess, tmp_file, year, month, months, supply_id, user)
|
|
269
|
-
except BaseException:
|
|
270
|
-
tmp_file.write(traceback.format_exc())
|
|
271
|
-
finally:
|
|
272
|
-
tmp_file.close()
|
|
273
|
-
os.rename(running_name, finished_name)
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
def do_get(sess):
|
|
277
|
-
year = req_int("end_year")
|
|
278
|
-
month = req_int("end_month")
|
|
279
|
-
months = req_int("months")
|
|
280
|
-
supply_id = req_int("supply_id") if "supply_id" in request.values else None
|
|
281
|
-
user = g.user
|
|
282
|
-
threading.Thread(
|
|
283
|
-
target=content, args=(year, month, months, supply_id, user)
|
|
284
|
-
).start()
|
|
285
|
-
return chellow_redirect("/downloads", 303)
|
chellow/reports/report_215.py
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import csv
|
|
2
|
-
import os
|
|
3
|
-
import sys
|
|
4
|
-
import threading
|
|
5
|
-
import traceback
|
|
6
|
-
from datetime import datetime
|
|
7
|
-
|
|
8
|
-
from flask import g, request
|
|
9
|
-
|
|
10
|
-
import pytz
|
|
11
|
-
|
|
12
|
-
from sqlalchemy import or_
|
|
13
|
-
from sqlalchemy.sql.expression import null, true
|
|
14
|
-
|
|
15
|
-
import chellow.dloads
|
|
16
|
-
from chellow.models import Era, Session, Site, SiteEra, Source, Supply
|
|
17
|
-
from chellow.utils import hh_after, hh_before, prev_hh, req_int
|
|
18
|
-
from chellow.views import chellow_redirect
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def content(year, supply_id, user):
|
|
22
|
-
f = writer = None
|
|
23
|
-
try:
|
|
24
|
-
with Session() as sess:
|
|
25
|
-
running_name, finished_name = chellow.dloads.make_names(
|
|
26
|
-
"crc_special_events.csv", user
|
|
27
|
-
)
|
|
28
|
-
f = open(running_name, mode="w", newline="")
|
|
29
|
-
writer = csv.writer(f, lineterminator="\n")
|
|
30
|
-
writer.writerow(("MPAN Core", "Site Id", "Site Name", "Date", "Event"))
|
|
31
|
-
|
|
32
|
-
year_start = datetime(year, 4, 1, tzinfo=pytz.utc)
|
|
33
|
-
year_finish = prev_hh(datetime(year + 1, 4, 1, tzinfo=pytz.utc))
|
|
34
|
-
|
|
35
|
-
def add_event(events, date, code, era=None, mpan_core=None):
|
|
36
|
-
if era is None:
|
|
37
|
-
mpan_cores = [mpan_core]
|
|
38
|
-
else:
|
|
39
|
-
mpan_cores = []
|
|
40
|
-
if era.imp_mpan_core is not None:
|
|
41
|
-
mpan_cores.append(era.imp_mpan_core)
|
|
42
|
-
if era.exp_mpan_core is not None:
|
|
43
|
-
mpan_cores.append(era.exp_mpan_core)
|
|
44
|
-
|
|
45
|
-
for mpan_core in mpan_cores:
|
|
46
|
-
events.append({"date": date, "code": code, "mpan-core": mpan_core})
|
|
47
|
-
|
|
48
|
-
if supply_id is None:
|
|
49
|
-
supplies = (
|
|
50
|
-
sess.query(Supply)
|
|
51
|
-
.join(Source)
|
|
52
|
-
.join(Era)
|
|
53
|
-
.filter(
|
|
54
|
-
Source.code.in_(("net", "gen-net", "gen")),
|
|
55
|
-
Era.start_date <= year_finish,
|
|
56
|
-
or_(Era.finish_date == null(), Era.finish_date >= year_start),
|
|
57
|
-
)
|
|
58
|
-
.distinct()
|
|
59
|
-
)
|
|
60
|
-
else:
|
|
61
|
-
supply = Supply.get_by_id(supply_id)
|
|
62
|
-
supplies = sess.query(Supply).filter(Supply.id == supply.id)
|
|
63
|
-
|
|
64
|
-
for supply in supplies:
|
|
65
|
-
eras = (
|
|
66
|
-
sess.query(Era)
|
|
67
|
-
.filter(
|
|
68
|
-
Era.supply == supply,
|
|
69
|
-
Era.start_date <= year_finish,
|
|
70
|
-
or_(Era.finish_date == null(), Era.finish_date >= year_start),
|
|
71
|
-
)
|
|
72
|
-
.order_by(Era.start_date)
|
|
73
|
-
.all()
|
|
74
|
-
)
|
|
75
|
-
events = []
|
|
76
|
-
first_era = eras[0]
|
|
77
|
-
first_era_start = first_era.start_date
|
|
78
|
-
if hh_after(first_era_start, year_start):
|
|
79
|
-
add_event(events, first_era_start, "New Supply", first_era)
|
|
80
|
-
|
|
81
|
-
last_era = eras[-1]
|
|
82
|
-
last_era_finish = last_era.finish_date
|
|
83
|
-
if hh_before(last_era_finish, year_finish):
|
|
84
|
-
add_event(events, last_era_finish, "Disconnection", last_era)
|
|
85
|
-
|
|
86
|
-
prev_era = first_era
|
|
87
|
-
for era in eras[1:]:
|
|
88
|
-
if era.msn != prev_era.msn:
|
|
89
|
-
add_event(events, era.start_date, "Meter Change", era)
|
|
90
|
-
if era.pc.code != prev_era.pc.code:
|
|
91
|
-
add_event(
|
|
92
|
-
events, era.start_date, "Change Of Profile Class", era
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
if era.mop_contract_id != prev_era.mop_contract_id:
|
|
96
|
-
add_event(events, era.start_date, "Change Of MOP", era)
|
|
97
|
-
|
|
98
|
-
if era.dc_contract_id != prev_era.dc_contract_id:
|
|
99
|
-
add_event(events, era.start_date, "Change Of DC", era)
|
|
100
|
-
|
|
101
|
-
for is_import in [True, False]:
|
|
102
|
-
if era.imp_mpan_core is None:
|
|
103
|
-
mpan_core = era.exp_mpan_core
|
|
104
|
-
else:
|
|
105
|
-
mpan_core = era.imp_mpan_core
|
|
106
|
-
|
|
107
|
-
if is_import:
|
|
108
|
-
cur_sup = era.imp_supplier_contract
|
|
109
|
-
prev_sup = prev_era.imp_supplier_contract
|
|
110
|
-
else:
|
|
111
|
-
cur_sup = era.exp_supplier_contract
|
|
112
|
-
prev_sup = prev_era.exp_supplier_contract
|
|
113
|
-
|
|
114
|
-
if cur_sup is None and prev_sup is not None:
|
|
115
|
-
add_event(
|
|
116
|
-
events, era.start_date, "End of supply", mpan_core
|
|
117
|
-
)
|
|
118
|
-
elif cur_sup is not None and prev_sup is None:
|
|
119
|
-
add_event(
|
|
120
|
-
events,
|
|
121
|
-
era.start_date,
|
|
122
|
-
"Start of supply",
|
|
123
|
-
None,
|
|
124
|
-
mpan_core,
|
|
125
|
-
)
|
|
126
|
-
elif (
|
|
127
|
-
cur_sup is not None
|
|
128
|
-
and prev_sup is not None
|
|
129
|
-
and cur_sup != prev_sup
|
|
130
|
-
):
|
|
131
|
-
add_event(
|
|
132
|
-
events,
|
|
133
|
-
era.start_date,
|
|
134
|
-
"Change Of Supplier",
|
|
135
|
-
None,
|
|
136
|
-
mpan_core,
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
prev_era = era
|
|
140
|
-
|
|
141
|
-
if len(events) > 0:
|
|
142
|
-
site = (
|
|
143
|
-
sess.query(Site)
|
|
144
|
-
.join(SiteEra)
|
|
145
|
-
.filter(SiteEra.is_physical == true(), SiteEra.era == last_era)
|
|
146
|
-
.one()
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
for event in events:
|
|
150
|
-
vals = [
|
|
151
|
-
event["mpan-core"],
|
|
152
|
-
site.code,
|
|
153
|
-
site.name,
|
|
154
|
-
event["date"].strftime("%Y-%m-%d %H:%M"),
|
|
155
|
-
event["code"],
|
|
156
|
-
]
|
|
157
|
-
writer.writerow(vals)
|
|
158
|
-
|
|
159
|
-
# Avoid a long-running transaction
|
|
160
|
-
sess.rollback()
|
|
161
|
-
except BaseException:
|
|
162
|
-
msg = traceback.format_exc()
|
|
163
|
-
sys.stderr.write(msg)
|
|
164
|
-
writer.writerow([msg])
|
|
165
|
-
finally:
|
|
166
|
-
if f is not None:
|
|
167
|
-
f.close()
|
|
168
|
-
os.rename(running_name, finished_name)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
def do_get(sess):
|
|
172
|
-
year = req_int("year")
|
|
173
|
-
supply_id = req_int("supply_id") if "supply_id" in request.values else None
|
|
174
|
-
|
|
175
|
-
threading.Thread(target=content, args=(year, supply_id, g.user)).start()
|
|
176
|
-
return chellow_redirect("/downloads", 303)
|