core.offlinemeter.OfflineMeterClone.on_post()   F
last analyzed

Complexity

Conditions 16

Size

Total Lines 97
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 74
dl 0
loc 97
rs 2.4
c 0
b 0
f 0
cc 16
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like core.offlinemeter.OfflineMeterClone.on_post() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import uuid
2
from datetime import datetime, timedelta
3
import falcon
4
import mysql.connector
5
import simplejson as json
6
from core.useractivity import user_logger, admin_control, access_control, api_key_control
7
import config
8
9
10
class OfflineMeterCollection:
11
    def __init__(self):
12
        """Initializes OfflineMeterCollection"""
13
        pass
14
15
    @staticmethod
16
    def on_options(req, resp):
17
        _ = req
18
        resp.status = falcon.HTTP_200
19
20
    @staticmethod
21
    def on_get(req, resp):
22
        if 'API-KEY' not in req.headers or \
23
                not isinstance(req.headers['API-KEY'], str) or \
24
                len(str.strip(req.headers['API-KEY'])) == 0:
25
            access_control(req)
26
        else:
27
            api_key_control(req)
28
        cnx = mysql.connector.connect(**config.myems_system_db)
29
        cursor = cnx.cursor()
30
31
        query = (" SELECT id, name, uuid "
32
                 " FROM tbl_energy_categories ")
33
        cursor.execute(query)
34
        rows_energy_categories = cursor.fetchall()
35
36
        energy_category_dict = dict()
37
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
38
            for row in rows_energy_categories:
39
                energy_category_dict[row[0]] = {"id": row[0],
40
                                                "name": row[1],
41
                                                "uuid": row[2]}
42
43
        query = (" SELECT id, name, uuid "
44
                 " FROM tbl_energy_items ")
45
        cursor.execute(query)
46
        rows_energy_items = cursor.fetchall()
47
48
        energy_item_dict = dict()
49
        if rows_energy_items is not None and len(rows_energy_items) > 0:
50
            for row in rows_energy_items:
51
                energy_item_dict[row[0]] = {"id": row[0],
52
                                            "name": row[1],
53
                                            "uuid": row[2]}
54
55
        query = (" SELECT id, name, uuid "
56
                 " FROM tbl_cost_centers ")
57
        cursor.execute(query)
58
        rows_cost_centers = cursor.fetchall()
59
60
        cost_center_dict = dict()
61
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
62
            for row in rows_cost_centers:
63
                cost_center_dict[row[0]] = {"id": row[0],
64
                                            "name": row[1],
65
                                            "uuid": row[2]}
66
67
        query = (" SELECT id, name, uuid, energy_category_id, "
68
                 "        is_counted, hourly_low_limit, hourly_high_limit, "
69
                 "        energy_item_id, cost_center_id, description "
70
                 " FROM tbl_offline_meters "
71
                 " ORDER BY id ")
72
        cursor.execute(query)
73
        rows_meters = cursor.fetchall()
74
75
        result = list()
76 View Code Duplication
        if rows_meters is not None and len(rows_meters) > 0:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
77
            for row in rows_meters:
78
                meta_result = {"id": row[0],
79
                               "name": row[1],
80
                               "uuid": row[2],
81
                               "energy_category": energy_category_dict.get(row[3], None),
82
                               "is_counted": True if row[4] else False,
83
                               "hourly_low_limit": row[5],
84
                               "hourly_high_limit": row[6],
85
                               "energy_item": energy_item_dict.get(row[7], None),
86
                               "cost_center": cost_center_dict.get(row[8], None),
87
                               "description": row[9]}
88
                result.append(meta_result)
89
90
        cursor.close()
91
        cnx.close()
92
        resp.text = json.dumps(result)
93
94
    @staticmethod
95
    @user_logger
96
    def on_post(req, resp):
97
        """Handles POST requests"""
98
        admin_control(req)
99
        try:
100
            raw_json = req.stream.read().decode('utf-8')
101
        except Exception as ex:
102
            print(str(ex))
103
            raise falcon.HTTPError(status=falcon.HTTP_400,
104
                                   title='API.BAD_REQUEST',
105
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
106
107
        new_values = json.loads(raw_json)
108
109
        if 'name' not in new_values['data'].keys() or \
110
                not isinstance(new_values['data']['name'], str) or \
111
                len(str.strip(new_values['data']['name'])) == 0:
112
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
113
                                   description='API.INVALID_OFFLINE_METER_NAME')
114
        name = str.strip(new_values['data']['name'])
115
116
        if 'energy_category_id' not in new_values['data'].keys() or \
117
                not isinstance(new_values['data']['energy_category_id'], int) or \
118
                new_values['data']['energy_category_id'] <= 0:
119
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
120
                                   description='API.INVALID_ENERGY_CATEGORY_ID')
121
        energy_category_id = new_values['data']['energy_category_id']
122
123
        if 'is_counted' not in new_values['data'].keys() or \
124
                not isinstance(new_values['data']['is_counted'], bool):
125
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
126
                                   description='API.INVALID_IS_COUNTED_VALUE')
127
        is_counted = new_values['data']['is_counted']
128
129
        if 'hourly_low_limit' not in new_values['data'].keys() or \
130
                not (isinstance(new_values['data']['hourly_low_limit'], float) or
131
                     isinstance(new_values['data']['hourly_low_limit'], int)):
132
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
133
                                   description='API.INVALID_HOURLY_LOW_LIMIT_VALUE')
134
        hourly_low_limit = new_values['data']['hourly_low_limit']
135
136
        if 'hourly_high_limit' not in new_values['data'].keys() or \
137
                not (isinstance(new_values['data']['hourly_high_limit'], float) or
138
                     isinstance(new_values['data']['hourly_high_limit'], int)):
139
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
140
                                   description='API.INVALID_HOURLY_HIGH_LIMIT_VALUE')
141
        hourly_high_limit = new_values['data']['hourly_high_limit']
142
143
        if 'cost_center_id' not in new_values['data'].keys() or \
144
                not isinstance(new_values['data']['cost_center_id'], int) or \
145
                new_values['data']['cost_center_id'] <= 0:
146
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
147
                                   description='API.INVALID_COST_CENTER_ID')
148
149
        cost_center_id = new_values['data']['cost_center_id']
150
151
        if 'energy_item_id' in new_values['data'].keys() and \
152
                new_values['data']['energy_item_id'] is not None:
153
            if not isinstance(new_values['data']['energy_item_id'], int) or \
154
                    new_values['data']['energy_item_id'] <= 0:
155
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
156
                                       description='API.INVALID_ENERGY_ITEM_ID')
157
            energy_item_id = new_values['data']['energy_item_id']
158
        else:
159
            energy_item_id = None
160
161
        if 'description' in new_values['data'].keys() and \
162
                new_values['data']['description'] is not None and \
163
                len(str(new_values['data']['description'])) > 0:
164
            description = str.strip(new_values['data']['description'])
165
        else:
166
            description = None
167
168
        cnx = mysql.connector.connect(**config.myems_system_db)
169
        cursor = cnx.cursor()
170
171
        cursor.execute(" SELECT name "
172
                       " FROM tbl_offline_meters "
173
                       " WHERE name = %s ", (name,))
174
        if cursor.fetchone() is not None:
175
            cursor.close()
176
            cnx.close()
177
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
178
                                   description='API.OFFLINE_METER_NAME_IS_ALREADY_IN_USE')
179
180
        cursor.execute(" SELECT name "
181
                       " FROM tbl_energy_categories "
182
                       " WHERE id = %s ",
183
                       (new_values['data']['energy_category_id'],))
184
        if cursor.fetchone() is None:
185
            cursor.close()
186
            cnx.close()
187
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
188
                                   description='API.ENERGY_CATEGORY_NOT_FOUND')
189 View Code Duplication
        if energy_item_id is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
190
            cursor.execute(" SELECT name, energy_category_id "
191
                           " FROM tbl_energy_items "
192
                           " WHERE id = %s ",
193
                           (new_values['data']['energy_item_id'],))
194
            row = cursor.fetchone()
195
            if row is None:
196
                cursor.close()
197
                cnx.close()
198
                raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
199
                                       description='API.ENERGY_ITEM_NOT_FOUND')
200
            else:
201
                if row[1] != energy_category_id:
202
                    cursor.close()
203
                    cnx.close()
204
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.BAD_REQUEST',
205
                                           description='API.ENERGY_ITEM_IS_NOT_BELONG_TO_ENERGY_CATEGORY')
206
207
        cursor.execute(" SELECT name "
208
                       " FROM tbl_cost_centers "
209
                       " WHERE id = %s ",
210
                       (new_values['data']['cost_center_id'],))
211
        row = cursor.fetchone()
212
        if row is None:
213
            cursor.close()
214
            cnx.close()
215
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
216
                                   description='API.COST_CENTER_NOT_FOUND')
217
218
        add_values = (" INSERT INTO tbl_offline_meters "
219
                      "    (name, uuid, energy_category_id, "
220
                      "     is_counted, hourly_low_limit, hourly_high_limit, "
221
                      "     cost_center_id, energy_item_id, description) "
222
                      " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) ")
223
        cursor.execute(add_values, (name,
224
                                    str(uuid.uuid4()),
225
                                    energy_category_id,
226
                                    is_counted,
227
                                    hourly_low_limit,
228
                                    hourly_high_limit,
229
                                    cost_center_id,
230
                                    energy_item_id,
231
                                    description))
232
        new_id = cursor.lastrowid
233
        cnx.commit()
234
        cursor.close()
235
        cnx.close()
236
237
        resp.status = falcon.HTTP_201
238
        resp.location = '/offlinemeters/' + str(new_id)
239
240
241
class OfflineMeterItem:
242
    def __init__(self):
243
        """Initializes OfflineMeterItem"""
244
        pass
245
246
    @staticmethod
247
    def on_options(req, resp, id_):
248
        _ = req
249
        resp.status = falcon.HTTP_200
250
        _ = id_
251
252 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
253
    def on_get(req, resp, id_):
254
        if 'API-KEY' not in req.headers or \
255
                not isinstance(req.headers['API-KEY'], str) or \
256
                len(str.strip(req.headers['API-KEY'])) == 0:
257
            access_control(req)
258
        else:
259
            api_key_control(req)
260
        if not id_.isdigit() or int(id_) <= 0:
261
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
262
                                   description='API.INVALID_OFFLINE_METER_ID')
263
264
        cnx = mysql.connector.connect(**config.myems_system_db)
265
        cursor = cnx.cursor()
266
267
        query = (" SELECT id, name, uuid "
268
                 " FROM tbl_energy_categories ")
269
        cursor.execute(query)
270
        rows_energy_categories = cursor.fetchall()
271
272
        energy_category_dict = dict()
273
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
274
            for row in rows_energy_categories:
275
                energy_category_dict[row[0]] = {"id": row[0],
276
                                                "name": row[1],
277
                                                "uuid": row[2]}
278
279
        query = (" SELECT id, name, uuid "
280
                 " FROM tbl_energy_items ")
281
        cursor.execute(query)
282
        rows_energy_items = cursor.fetchall()
283
284
        energy_item_dict = dict()
285
        if rows_energy_items is not None and len(rows_energy_items) > 0:
286
            for row in rows_energy_items:
287
                energy_item_dict[row[0]] = {"id": row[0],
288
                                            "name": row[1],
289
                                            "uuid": row[2]}
290
291
        query = (" SELECT id, name, uuid "
292
                 " FROM tbl_cost_centers ")
293
        cursor.execute(query)
294
        rows_cost_centers = cursor.fetchall()
295
296
        cost_center_dict = dict()
297
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
298
            for row in rows_cost_centers:
299
                cost_center_dict[row[0]] = {"id": row[0],
300
                                            "name": row[1],
301
                                            "uuid": row[2]}
302
303
        query = (" SELECT id, name, uuid, energy_category_id, "
304
                 "        is_counted, hourly_low_limit, hourly_high_limit, "
305
                 "        energy_item_id, cost_center_id, description "
306
                 " FROM tbl_offline_meters "
307
                 " WHERE id = %s ")
308
        cursor.execute(query, (id_,))
309
        row = cursor.fetchone()
310
        cursor.close()
311
        cnx.close()
312
313
        if row is None:
314
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
315
                                   description='API.OFFLINE_METER_NOT_FOUND')
316
        else:
317
            meta_result = {"id": row[0],
318
                           "name": row[1],
319
                           "uuid": row[2],
320
                           "energy_category": energy_category_dict.get(row[3], None),
321
                           "is_counted": True if row[4] else False,
322
                           "hourly_low_limit": row[5],
323
                           "hourly_high_limit": row[6],
324
                           "energy_item": energy_item_dict.get(row[7], None),
325
                           "cost_center": cost_center_dict.get(row[8], None),
326
                           "description": row[9]}
327
328
        resp.text = json.dumps(meta_result)
329
330
    @staticmethod
331
    @user_logger
332
    def on_delete(req, resp, id_):
333
        admin_control(req)
334
        if not id_.isdigit() or int(id_) <= 0:
335
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
336
                                   description='API.INVALID_OFFLINE_METER_ID')
337
338
        cnx = mysql.connector.connect(**config.myems_system_db)
339
        cursor = cnx.cursor()
340
341
        cursor.execute(" SELECT uuid "
342
                       " FROM tbl_offline_meters "
343
                       " WHERE id = %s ", (id_,))
344
        row = cursor.fetchone()
345
        if row is None:
346
            cursor.close()
347
            cnx.close()
348
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
349
                                   description='API.OFFLINE_METER_NOT_FOUND')
350
        else:
351
            offline_meter_uuid = row[0]
352
353
        # check if this offline meter is being used by virtual meters
354
        cursor.execute(" SELECT vm.name "
355
                       " FROM tbl_variables va, tbl_virtual_meters vm "
356
                       " WHERE va.meter_id = %s AND va.meter_type = 'offline_meter' AND va.virtual_meter_id = vm.id ",
357
                       (id_,))
358
        row_virtual_meter = cursor.fetchone()
359
        if row_virtual_meter is not None:
360
            cursor.close()
361
            cnx.close()
362
            raise falcon.HTTPError(status=falcon.HTTP_400,
363
                                   title='API.BAD_REQUEST',
364
                                   description='API.THIS_OFFLINE_METER_IS_BEING_USED_BY_A_VIRTUAL_METER')
365
366
        # check relation with spaces
367
        cursor.execute(" SELECT id "
368
                       " FROM tbl_spaces_offline_meters "
369
                       " WHERE offline_meter_id = %s ", (id_,))
370
        rows_companies = cursor.fetchall()
371
        if rows_companies is not None and len(rows_companies) > 0:
372
            cursor.close()
373
            cnx.close()
374
            raise falcon.HTTPError(status=falcon.HTTP_400,
375
                                   title='API.BAD_REQUEST',
376
                                   description='API.THERE_IS_RELATION_WITH_SPACES')
377
378
        # check relation with combined equipments
379
        cursor.execute(" SELECT combined_equipment_id "
380
                       " FROM tbl_combined_equipments_offline_meters "
381
                       " WHERE offline_meter_id = %s ",
382
                       (id_,))
383
        rows_combined_equipments = cursor.fetchall()
384
        if rows_combined_equipments is not None and len(rows_combined_equipments) > 0:
385
            cursor.close()
386
            cnx.close()
387
            raise falcon.HTTPError(status=falcon.HTTP_400,
388
                                   title='API.BAD_REQUEST',
389
                                   description='API.THERE_IS_RELATION_WITH_COMBINED_EQUIPMENTS')
390
391
        # check relation with combined equipment parameters
392
        cursor.execute(" SELECT combined_equipment_id "
393
                       " FROM tbl_combined_equipments_parameters "
394
                       " WHERE numerator_meter_uuid = %s OR denominator_meter_uuid = %s",
395
                       (offline_meter_uuid, offline_meter_uuid,))
396
        rows_combined_equipments = cursor.fetchall()
397
        if rows_combined_equipments is not None and len(rows_combined_equipments) > 0:
398
            cursor.close()
399
            cnx.close()
400
            raise falcon.HTTPError(status=falcon.HTTP_400,
401
                                   title='API.BAD_REQUEST',
402
                                   description='API.THERE_IS_RELATION_WITH_COMBINED_EQUIPMENT_PARAMETERS')
403
404
        # check relations with tenants
405
        cursor.execute(" SELECT tenant_id "
406
                       " FROM tbl_tenants_offline_meters "
407
                       " WHERE offline_meter_id = %s ", (id_,))
408
        rows_tenants = cursor.fetchall()
409
        if rows_tenants is not None and len(rows_tenants) > 0:
410
            cursor.close()
411
            cnx.close()
412
            raise falcon.HTTPError(status=falcon.HTTP_400,
413
                                   title='API.BAD_REQUEST',
414
                                   description='API.THERE_IS_RELATION_WITH_TENANTS')
415
416
        # check relations with stores
417
        cursor.execute(" SELECT store_id "
418
                       " FROM tbl_stores_offline_meters "
419
                       " WHERE offline_meter_id = %s ", (id_,))
420
        rows_stores = cursor.fetchall()
421
        if rows_stores is not None and len(rows_stores) > 0:
422
            cursor.close()
423
            cnx.close()
424
            raise falcon.HTTPError(status=falcon.HTTP_400,
425
                                   title='API.BAD_REQUEST',
426
                                   description='API.THERE_IS_RELATION_WITH_STORES')
427
428
        # check relations with shopfloors
429
        cursor.execute(" SELECT shopfloor_id "
430
                       " FROM tbl_shopfloors_offline_meters "
431
                       " WHERE offline_meter_id = %s ", (id_,))
432
        rows_shopfloors = cursor.fetchall()
433
        if rows_shopfloors is not None and len(rows_shopfloors) > 0:
434
            cursor.close()
435
            cnx.close()
436
            raise falcon.HTTPError(status=falcon.HTTP_400,
437
                                   title='API.BAD_REQUEST',
438
                                   description='API.THERE_IS_RELATION_WITH_SHOPFLOORS')
439
440
        # check relations with equipments
441
        cursor.execute(" SELECT equipment_id "
442
                       " FROM tbl_equipments_offline_meters "
443
                       " WHERE offline_meter_id = %s ", (id_,))
444
        rows_equipments = cursor.fetchall()
445
        if rows_equipments is not None and len(rows_equipments) > 0:
446
            cursor.close()
447
            cnx.close()
448
            raise falcon.HTTPError(status=falcon.HTTP_400,
449
                                   title='API.BAD_REQUEST',
450
                                   description='API.THERE_IS_RELATION_WITH_EQUIPMENTS')
451
452
        # check relation with equipment parameters
453
        cursor.execute(" SELECT equipment_id "
454
                       " FROM tbl_equipments_parameters "
455
                       " WHERE numerator_meter_uuid = %s OR denominator_meter_uuid = %s",
456
                       (offline_meter_uuid, offline_meter_uuid,))
457
        rows_equipments = cursor.fetchall()
458
        if rows_equipments is not None and len(rows_equipments) > 0:
459
            cursor.close()
460
            cnx.close()
461
            raise falcon.HTTPError(status=falcon.HTTP_400,
462
                                   title='API.BAD_REQUEST',
463
                                   description='API.THERE_IS_RELATION_WITH_EQUIPMENT_PARAMETERS')
464
465
        # check relation with energy flow diagram links
466
        cursor.execute(" SELECT id "
467
                       " FROM tbl_energy_flow_diagrams_links "
468
                       " WHERE meter_uuid = %s ", (offline_meter_uuid,))
469
        rows_links = cursor.fetchall()
470
        if rows_links is not None and len(rows_links) > 0:
471
            cursor.close()
472
            cnx.close()
473
            raise falcon.HTTPError(status=falcon.HTTP_400,
474
                                   title='API.BAD_REQUEST',
475
                                   description='API.THERE_IS_RELATION_WITH_ENERGY_FLOW_DIAGRAM_LINKS')
476
477
        cursor.execute(" DELETE FROM tbl_offline_meters WHERE id = %s ", (id_,))
478
        cnx.commit()
479
480
        cursor.close()
481
        cnx.close()
482
483
        resp.status = falcon.HTTP_204
484
485
    @staticmethod
486
    @user_logger
487
    def on_put(req, resp, id_):
488
        """Handles PUT requests"""
489
        admin_control(req)
490
        try:
491
            raw_json = req.stream.read().decode('utf-8')
492
        except Exception as ex:
493
            print(str(ex))
494
            raise falcon.HTTPError(status=falcon.HTTP_400,
495
                                   title='API.BAD_REQUEST',
496
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
497
498
        if not id_.isdigit() or int(id_) <= 0:
499
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
500
                                   description='API.INVALID_OFFLINE_METER_ID')
501
502
        new_values = json.loads(raw_json)
503
504
        if 'name' not in new_values['data'].keys() or \
505
                not isinstance(new_values['data']['name'], str) or \
506
                len(str.strip(new_values['data']['name'])) == 0:
507
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
508
                                   description='API.INVALID_OFFLINE_METER_NAME')
509
        name = str.strip(new_values['data']['name'])
510
511
        if 'energy_category_id' not in new_values['data'].keys() or \
512
                not isinstance(new_values['data']['energy_category_id'], int) or \
513
                new_values['data']['energy_category_id'] <= 0:
514
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
515
                                   description='API.INVALID_ENERGY_CATEGORY_ID')
516
        energy_category_id = new_values['data']['energy_category_id']
517
518
        if 'is_counted' not in new_values['data'].keys() or \
519
                not isinstance(new_values['data']['is_counted'], bool):
520
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
521
                                   description='API.INVALID_IS_COUNTED_VALUE')
522
        is_counted = new_values['data']['is_counted']
523
524
        if 'hourly_low_limit' not in new_values['data'].keys() or \
525
                not (isinstance(new_values['data']['hourly_low_limit'], float) or
526
                     isinstance(new_values['data']['hourly_low_limit'], int)):
527
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
528
                                   description='API.INVALID_HOURLY_LOW_LIMIT_VALUE')
529
        hourly_low_limit = new_values['data']['hourly_low_limit']
530
531
        if 'hourly_high_limit' not in new_values['data'].keys() or \
532
                not (isinstance(new_values['data']['hourly_high_limit'], float) or
533
                     isinstance(new_values['data']['hourly_high_limit'], int)):
534
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
535
                                   description='API.INVALID_HOURLY_HIGH_LIMIT_VALUE')
536
        hourly_high_limit = new_values['data']['hourly_high_limit']
537
538
        if 'cost_center_id' not in new_values['data'].keys() or \
539
                not isinstance(new_values['data']['cost_center_id'], int) or \
540
                new_values['data']['cost_center_id'] <= 0:
541
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
542
                                   description='API.INVALID_COST_CENTER_ID')
543
544
        cost_center_id = new_values['data']['cost_center_id']
545
546
        if 'energy_item_id' in new_values['data'].keys() and \
547
                new_values['data']['energy_item_id'] is not None:
548
            if not isinstance(new_values['data']['energy_item_id'], int) or \
549
                    new_values['data']['energy_item_id'] <= 0:
550
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
551
                                       description='API.INVALID_ENERGY_ITEM_ID')
552
            energy_item_id = new_values['data']['energy_item_id']
553
        else:
554
            energy_item_id = None
555
556
        if 'description' in new_values['data'].keys() and \
557
                new_values['data']['description'] is not None and \
558
                len(str(new_values['data']['description'])) > 0:
559
            description = str.strip(new_values['data']['description'])
560
        else:
561
            description = None
562
563
        cnx = mysql.connector.connect(**config.myems_system_db)
564
        cursor = cnx.cursor()
565
566
        cursor.execute(" SELECT name "
567
                       " FROM tbl_offline_meters "
568
                       " WHERE id = %s ", (id_,))
569
        if cursor.fetchone() is None:
570
            cursor.close()
571
            cnx.close()
572
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
573
                                   description='API.OFFLINE_METER_NOT_FOUND')
574
575
        cursor.execute(" SELECT name "
576
                       " FROM tbl_offline_meters "
577
                       " WHERE name = %s AND id != %s ", (name, id_))
578
        if cursor.fetchone() is not None:
579
            cursor.close()
580
            cnx.close()
581
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
582
                                   description='API.OFFLINE_METER_NAME_IS_ALREADY_IN_USE')
583
584
        cursor.execute(" SELECT name "
585
                       " FROM tbl_energy_categories "
586
                       " WHERE id = %s ",
587
                       (new_values['data']['energy_category_id'],))
588
        if cursor.fetchone() is None:
589
            cursor.close()
590
            cnx.close()
591
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
592
                                   description='API.ENERGY_CATEGORY_NOT_FOUND')
593
594
        cursor.execute(" SELECT name "
595
                       " FROM tbl_cost_centers "
596
                       " WHERE id = %s ",
597
                       (new_values['data']['cost_center_id'],))
598
        row = cursor.fetchone()
599
        if row is None:
600
            cursor.close()
601
            cnx.close()
602
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
603
                                   description='API.COST_CENTER_NOT_FOUND')
604
605 View Code Duplication
        if energy_item_id is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
606
            cursor.execute(" SELECT name, energy_category_id "
607
                           " FROM tbl_energy_items "
608
                           " WHERE id = %s ",
609
                           (new_values['data']['energy_item_id'],))
610
            row = cursor.fetchone()
611
            if row is None:
612
                cursor.close()
613
                cnx.close()
614
                raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
615
                                       description='API.ENERGY_ITEM_NOT_FOUND')
616
            else:
617
                if row[1] != energy_category_id:
618
                    cursor.close()
619
                    cnx.close()
620
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.BAD_REQUEST',
621
                                           description='API.ENERGY_ITEM_IS_NOT_BELONG_TO_ENERGY_CATEGORY')
622
623
        update_row = (" UPDATE tbl_offline_meters "
624
                      " SET name = %s, energy_category_id = %s,"
625
                      "     is_counted = %s, hourly_low_limit = %s, hourly_high_limit = %s, "
626
                      "     cost_center_id = %s, energy_item_id = %s, description = %s "
627
                      " WHERE id = %s ")
628
        cursor.execute(update_row, (name,
629
                                    energy_category_id,
630
                                    is_counted,
631
                                    hourly_low_limit,
632
                                    hourly_high_limit,
633
                                    cost_center_id,
634
                                    energy_item_id,
635
                                    description,
636
                                    id_,))
637
        cnx.commit()
638
639
        cursor.close()
640
        cnx.close()
641
642
        resp.status = falcon.HTTP_200
643
644
645
class OfflineMeterExport:
646
    def __init__(self):
647
        """Initializes OfflineMeterExport"""
648
        pass
649
650
    @staticmethod
651
    def on_options(req, resp, id_):
652
        _ = req
653
        resp.status = falcon.HTTP_200
654
        _ = id_
655
656 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
657
    def on_get(req, resp, id_):
658
        if 'API-KEY' not in req.headers or \
659
                not isinstance(req.headers['API-KEY'], str) or \
660
                len(str.strip(req.headers['API-KEY'])) == 0:
661
            access_control(req)
662
        else:
663
            api_key_control(req)
664
        if not id_.isdigit() or int(id_) <= 0:
665
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
666
                                   description='API.INVALID_OFFLINE_METER_ID')
667
668
        cnx = mysql.connector.connect(**config.myems_system_db)
669
        cursor = cnx.cursor()
670
671
        query = (" SELECT id, name, uuid "
672
                 " FROM tbl_energy_categories ")
673
        cursor.execute(query)
674
        rows_energy_categories = cursor.fetchall()
675
676
        energy_category_dict = dict()
677
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
678
            for row in rows_energy_categories:
679
                energy_category_dict[row[0]] = {"id": row[0],
680
                                                "name": row[1],
681
                                                "uuid": row[2]}
682
683
        query = (" SELECT id, name, uuid "
684
                 " FROM tbl_energy_items ")
685
        cursor.execute(query)
686
        rows_energy_items = cursor.fetchall()
687
688
        energy_item_dict = dict()
689
        if rows_energy_items is not None and len(rows_energy_items) > 0:
690
            for row in rows_energy_items:
691
                energy_item_dict[row[0]] = {"id": row[0],
692
                                            "name": row[1],
693
                                            "uuid": row[2]}
694
695
        query = (" SELECT id, name, uuid "
696
                 " FROM tbl_cost_centers ")
697
        cursor.execute(query)
698
        rows_cost_centers = cursor.fetchall()
699
700
        cost_center_dict = dict()
701
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
702
            for row in rows_cost_centers:
703
                cost_center_dict[row[0]] = {"id": row[0],
704
                                            "name": row[1],
705
                                            "uuid": row[2]}
706
707
        query = (" SELECT id, name, uuid, energy_category_id, "
708
                 "        is_counted, hourly_low_limit, hourly_high_limit, "
709
                 "        energy_item_id, cost_center_id, description "
710
                 " FROM tbl_offline_meters "
711
                 " WHERE id = %s ")
712
        cursor.execute(query, (id_,))
713
        row = cursor.fetchone()
714
        cursor.close()
715
        cnx.close()
716
717
        if row is None:
718
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
719
                                   description='API.OFFLINE_METER_NOT_FOUND')
720
        else:
721
            meta_result = {"id": row[0],
722
                           "name": row[1],
723
                           "uuid": row[2],
724
                           "energy_category": energy_category_dict.get(row[3], None),
725
                           "is_counted": True if row[4] else False,
726
                           "hourly_low_limit": row[5],
727
                           "hourly_high_limit": row[6],
728
                           "energy_item": energy_item_dict.get(row[7], None),
729
                           "cost_center": cost_center_dict.get(row[8], None),
730
                           "description": row[9]}
731
732
        resp.text = json.dumps(meta_result)
733
734
735
class OfflineMeterImport:
736
    def __init__(self):
737
        """Initializes OfflineMeterImport"""
738
        pass
739
740
    @staticmethod
741
    def on_options(req, resp):
742
        _ = req
743
        resp.status = falcon.HTTP_200
744
745
    @staticmethod
746
    @user_logger
747
    def on_post(req, resp):
748
        """Handles POST requests"""
749
        admin_control(req)
750
        try:
751
            raw_json = req.stream.read().decode('utf-8')
752
        except Exception as ex:
753
            print(str(ex))
754
            raise falcon.HTTPError(status=falcon.HTTP_400,
755
                                   title='API.BAD_REQUEST',
756
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
757
758
        new_values = json.loads(raw_json)
759
760
        if 'name' not in new_values.keys() or \
761
                not isinstance(new_values['name'], str) or \
762
                len(str.strip(new_values['name'])) == 0:
763
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
764
                                   description='API.INVALID_OFFLINE_METER_NAME')
765
        name = str.strip(new_values['name'])
766
767
        if 'energy_category' not in new_values.keys() or \
768
            'id' not in new_values['energy_category'].keys() or \
769
            not isinstance(new_values['energy_category']['id'], int) or \
770
                new_values['energy_category']['id'] <= 0:
771
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
772
                                   description='API.INVALID_ENERGY_CATEGORY_ID')
773
        energy_category_id = new_values['energy_category']['id']
774
775
        if 'is_counted' not in new_values.keys() or \
776
                not isinstance(new_values['is_counted'], bool):
777
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
778
                                   description='API.INVALID_IS_COUNTED_VALUE')
779
        is_counted = new_values['is_counted']
780
781
        if 'hourly_low_limit' not in new_values.keys() or \
782
                not (isinstance(new_values['hourly_low_limit'], float) or
783
                     isinstance(new_values['hourly_low_limit'], int)):
784
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
785
                                   description='API.INVALID_HOURLY_LOW_LIMIT_VALUE')
786
        hourly_low_limit = new_values['hourly_low_limit']
787
788
        if 'hourly_high_limit' not in new_values.keys() or \
789
                not (isinstance(new_values['hourly_high_limit'], float) or
790
                     isinstance(new_values['hourly_high_limit'], int)):
791
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
792
                                   description='API.INVALID_HOURLY_HIGH_LIMIT_VALUE')
793
        hourly_high_limit = new_values['hourly_high_limit']
794
795
        if 'cost_center' not in new_values.keys() or \
796
            new_values['cost_center'] is None or \
797
            'id' not in new_values['cost_center'].keys() or \
798
                not isinstance(new_values['cost_center']['id'], int) or \
799
                new_values['cost_center']['id'] <= 0:
800
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
801
                                   description='API.INVALID_COST_CENTER_ID')
802
803
        cost_center_id = new_values['cost_center']['id']
804
805 View Code Duplication
        if 'energy_item' in new_values.keys() and \
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
806
            new_values['energy_item'] is not None and \
807
                'id' in new_values['energy_item'].keys() and \
808
                new_values['energy_item']['id'] is not None:
809
            if not isinstance(new_values['energy_item']['id'], int) or \
810
                    new_values['energy_item']['id'] <= 0:
811
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
812
                                       description='API.INVALID_ENERGY_ITEM_ID')
813
            energy_item_id = new_values['energy_item']['id']
814
        else:
815
            energy_item_id = None
816
817
        if 'description' in new_values.keys() and \
818
                new_values['description'] is not None and \
819
                len(str(new_values['description'])) > 0:
820
            description = str.strip(new_values['description'])
821
        else:
822
            description = None
823
824
        cnx = mysql.connector.connect(**config.myems_system_db)
825
        cursor = cnx.cursor()
826
827
        cursor.execute(" SELECT name "
828
                       " FROM tbl_offline_meters "
829
                       " WHERE name = %s ", (name,))
830
        if cursor.fetchone() is not None:
831
            cursor.close()
832
            cnx.close()
833
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
834
                                   description='API.OFFLINE_METER_NAME_IS_ALREADY_IN_USE')
835
836
        cursor.execute(" SELECT name "
837
                       " FROM tbl_energy_categories "
838
                       " WHERE id = %s ",
839
                       (new_values['energy_category']['id'],))
840
        if cursor.fetchone() is None:
841
            cursor.close()
842
            cnx.close()
843
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
844
                                   description='API.ENERGY_CATEGORY_NOT_FOUND')
845 View Code Duplication
        if energy_item_id is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
846
            cursor.execute(" SELECT name, energy_category_id "
847
                           " FROM tbl_energy_items "
848
                           " WHERE id = %s ",
849
                           (new_values['energy_item']['id'],))
850
            row = cursor.fetchone()
851
            if row is None:
852
                cursor.close()
853
                cnx.close()
854
                raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
855
                                       description='API.ENERGY_ITEM_NOT_FOUND')
856
            else:
857
                if row[1] != energy_category_id:
858
                    cursor.close()
859
                    cnx.close()
860
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.BAD_REQUEST',
861
                                           description='API.ENERGY_ITEM_IS_NOT_BELONG_TO_ENERGY_CATEGORY')
862
863
        cursor.execute(" SELECT name "
864
                       " FROM tbl_cost_centers "
865
                       " WHERE id = %s ",
866
                       (new_values['cost_center']['id'],))
867
        row = cursor.fetchone()
868
        if row is None:
869
            cursor.close()
870
            cnx.close()
871
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
872
                                   description='API.COST_CENTER_NOT_FOUND')
873
874
        add_values = (" INSERT INTO tbl_offline_meters "
875
                      "    (name, uuid, energy_category_id, "
876
                      "     is_counted, hourly_low_limit, hourly_high_limit, "
877
                      "     cost_center_id, energy_item_id, description) "
878
                      " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) ")
879
        cursor.execute(add_values, (name,
880
                                    str(uuid.uuid4()),
881
                                    energy_category_id,
882
                                    is_counted,
883
                                    hourly_low_limit,
884
                                    hourly_high_limit,
885
                                    cost_center_id,
886
                                    energy_item_id,
887
                                    description))
888
        new_id = cursor.lastrowid
889
        cnx.commit()
890
        cursor.close()
891
        cnx.close()
892
893
        resp.status = falcon.HTTP_201
894
        resp.location = '/offlinemeters/' + str(new_id)
895
896
897
class OfflineMeterClone:
898
    def __init__(self):
899
        """Initializes OfflineMeterClone"""
900
        pass
901
902
    @staticmethod
903
    def on_options(req, resp, id_):
904
        _ = req
905
        resp.status = falcon.HTTP_200
906
        _ = id_
907
908
    @staticmethod
909
    @user_logger
910
    def on_post(req, resp, id_):
911
        admin_control(req)
912
        if not id_.isdigit() or int(id_) <= 0:
913
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
914
                                   description='API.INVALID_OFFLINE_METER_ID')
915
916
        cnx = mysql.connector.connect(**config.myems_system_db)
917
        cursor = cnx.cursor()
918
919
        query = (" SELECT id, name, uuid "
920
                 " FROM tbl_energy_categories ")
921
        cursor.execute(query)
922
        rows_energy_categories = cursor.fetchall()
923
924
        energy_category_dict = dict()
925
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
926
            for row in rows_energy_categories:
927
                energy_category_dict[row[0]] = {"id": row[0],
928
                                                "name": row[1],
929
                                                "uuid": row[2]}
930
931
        query = (" SELECT id, name, uuid "
932
                 " FROM tbl_energy_items ")
933
        cursor.execute(query)
934
        rows_energy_items = cursor.fetchall()
935
936
        energy_item_dict = dict()
937
        if rows_energy_items is not None and len(rows_energy_items) > 0:
938
            for row in rows_energy_items:
939
                energy_item_dict[row[0]] = {"id": row[0],
940
                                            "name": row[1],
941
                                            "uuid": row[2]}
942
943
        query = (" SELECT id, name, uuid "
944
                 " FROM tbl_cost_centers ")
945
        cursor.execute(query)
946
        rows_cost_centers = cursor.fetchall()
947
948
        cost_center_dict = dict()
949
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
950
            for row in rows_cost_centers:
951
                cost_center_dict[row[0]] = {"id": row[0],
952
                                            "name": row[1],
953
                                            "uuid": row[2]}
954
955
        query = (" SELECT id, name, uuid, energy_category_id, "
956
                 "        is_counted, hourly_low_limit, hourly_high_limit, "
957
                 "        energy_item_id, cost_center_id, description "
958
                 " FROM tbl_offline_meters "
959
                 " WHERE id = %s ")
960
        cursor.execute(query, (id_,))
961
        row = cursor.fetchone()
962
963
        if row is None:
964
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
965
                                   description='API.OFFLINE_METER_NOT_FOUND')
966
        else:
967
            meta_result = {"id": row[0],
968
                           "name": row[1],
969
                           "uuid": row[2],
970
                           "energy_category": energy_category_dict.get(row[3], None),
971
                           "is_counted": True if row[4] else False,
972
                           "hourly_low_limit": row[5],
973
                           "hourly_high_limit": row[6],
974
                           "energy_item": energy_item_dict.get(row[7], None),
975
                           "cost_center": cost_center_dict.get(row[8], None),
976
                           "description": row[9]}
977
978
            timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
979
            if config.utc_offset[0] == '-':
980
                timezone_offset = -timezone_offset
981
            new_name = (str.strip(meta_result['name']) +
982
                        (datetime.utcnow() + timedelta(minutes=timezone_offset)).isoformat(sep='-', timespec='seconds'))
983
            energy_item_id = meta_result['energy_item']['id'] if meta_result['energy_item'] is not None else None
984
            add_values = (" INSERT INTO tbl_offline_meters "
985
                          "    (name, uuid, energy_category_id, "
986
                          "     is_counted, hourly_low_limit, hourly_high_limit, "
987
                          "     cost_center_id, energy_item_id, description) "
988
                          " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) ")
989
            cursor.execute(add_values, (new_name,
990
                                        str(uuid.uuid4()),
991
                                        meta_result['energy_category']['id'],
992
                                        meta_result['is_counted'],
993
                                        meta_result['hourly_low_limit'],
994
                                        meta_result['hourly_high_limit'],
995
                                        meta_result['cost_center']['id'],
996
                                        energy_item_id,
997
                                        meta_result['description']))
998
            new_id = cursor.lastrowid
999
            cnx.commit()
1000
            cursor.close()
1001
            cnx.close()
1002
1003
            resp.status = falcon.HTTP_201
1004
            resp.location = '/offlinemeters/' + str(new_id)
1005