core.offlinemeter.OfflineMeterItem.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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