core.tenant.TenantCollection.on_post()   F
last analyzed

Complexity

Conditions 44

Size

Total Lines 191
Code Lines 152

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 152
dl 0
loc 191
rs 0
c 0
b 0
f 0
cc 44
nop 2

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.tenant.TenantCollection.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, timezone
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 TenantCollection:
11
    def __init__(self):
12
        """"Initializes TenantCollection"""
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_tenant_types ")
32
        cursor.execute(query)
33
        rows_tenant_types = cursor.fetchall()
34
35
        tenant_type_dict = dict()
36
        if rows_tenant_types is not None and len(rows_tenant_types) > 0:
37
            for row in rows_tenant_types:
38
                tenant_type_dict[row[0]] = {"id": row[0],
39
                                            "name": row[1],
40
                                            "uuid": row[2]}
41
42
        query = (" SELECT id, name, uuid "
43
                 " FROM tbl_contacts ")
44
        cursor.execute(query)
45
        rows_contacts = cursor.fetchall()
46
47
        contact_dict = dict()
48
        if rows_contacts is not None and len(rows_contacts) > 0:
49
            for row in rows_contacts:
50
                contact_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, "
67
                 "        buildings, floors, rooms, area, tenant_type_id, "
68
                 "        is_input_counted, is_key_tenant, "
69
                 "        lease_number, lease_start_datetime_utc, lease_end_datetime_utc, is_in_lease, "
70
                 "        contact_id, cost_center_id, description "
71
                 " FROM tbl_tenants "
72
                 " ORDER BY id ")
73
        cursor.execute(query)
74
        rows_spaces = cursor.fetchall()
75
76
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
77
        if config.utc_offset[0] == '-':
78
            timezone_offset = -timezone_offset
79
80
        result = list()
81
        if rows_spaces is not None and len(rows_spaces) > 0:
82
            for row in rows_spaces:
83
84
                meta_result = {"id": row[0],
85
                               "name": row[1],
86
                               "uuid": row[2],
87
                               "buildings": row[3],
88
                               "floors": row[4],
89
                               "rooms": row[5],
90
                               "area": row[6],
91
                               "tenant_type": tenant_type_dict.get(row[7], None),
92
                               "is_input_counted": bool(row[8]),
93
                               "is_key_tenant": bool(row[9]),
94
                               "lease_number": row[10],
95
                               "lease_start_datetime":
96
                                   (row[11].replace(tzinfo=timezone.utc) +
97
                                    timedelta(minutes=timezone_offset)).isoformat()[0:19],
98
                               "lease_end_datetime": (row[12].replace(tzinfo=timezone.utc) +
99
                                                      timedelta(minutes=timezone_offset)).isoformat()[0:19],
100
                               "is_in_lease": bool(row[13]),
101
                               "contact": contact_dict.get(row[14], None),
102
                               "cost_center": cost_center_dict.get(row[15], None),
103
                               "description": row[16],
104
                               "qrcode": 'tenant:' + row[2]}
105
                result.append(meta_result)
106
107
        cursor.close()
108
        cnx.close()
109
        resp.text = json.dumps(result)
110
111
    @staticmethod
112
    @user_logger
113
    def on_post(req, resp):
114
        """Handles POST requests"""
115
        admin_control(req)
116
        try:
117
            raw_json = req.stream.read().decode('utf-8')
118
        except Exception as ex:
119
            raise falcon.HTTPError(status=falcon.HTTP_400,
120
                                   title='API.BAD_REQUEST',
121
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
122
123
        new_values = json.loads(raw_json)
124
125
        if 'name' not in new_values['data'].keys() or \
126
                not isinstance(new_values['data']['name'], str) or \
127
                len(str.strip(new_values['data']['name'])) == 0:
128
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
129
                                   description='API.INVALID_TENANT_NAME')
130
        name = str.strip(new_values['data']['name'])
131
132
        if 'buildings' not in new_values['data'].keys() or \
133
                not isinstance(new_values['data']['buildings'], str) or \
134
                len(str.strip(new_values['data']['buildings'])) == 0:
135
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
136
                                   description='API.INVALID_BUILDINGS_VALUE')
137
        buildings = str.strip(new_values['data']['buildings'])
138
139
        if 'floors' not in new_values['data'].keys() or \
140
                not isinstance(new_values['data']['floors'], str) or \
141
                len(str.strip(new_values['data']['floors'])) == 0:
142
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
143
                                   description='API.INVALID_FLOORS_VALUE')
144
        floors = str.strip(new_values['data']['floors'])
145
146
        if 'rooms' not in new_values['data'].keys() or \
147
                not isinstance(new_values['data']['rooms'], str) or \
148
                len(str.strip(new_values['data']['rooms'])) == 0:
149
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
150
                                   description='API.INVALID_ROOMS_VALUE')
151
        rooms = str.strip(new_values['data']['rooms'])
152
153
        if 'area' not in new_values['data'].keys() or \
154
                not (isinstance(new_values['data']['area'], float) or
155
                     isinstance(new_values['data']['area'], int)) or \
156
                new_values['data']['area'] <= 0.0:
157
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
158
                                   description='API.INVALID_AREA_VALUE')
159
        area = new_values['data']['area']
160
161
        if 'tenant_type_id' not in new_values['data'].keys() or \
162
                not isinstance(new_values['data']['tenant_type_id'], int) or \
163
                new_values['data']['tenant_type_id'] <= 0:
164
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
165
                                   description='API.INVALID_TENANT_TYPE_ID')
166
        tenant_type_id = new_values['data']['tenant_type_id']
167
168
        if 'is_input_counted' not in new_values['data'].keys() or \
169
                not isinstance(new_values['data']['is_input_counted'], bool):
170
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
171
                                   description='API.INVALID_IS_INPUT_COUNTED_VALUE')
172
        is_input_counted = new_values['data']['is_input_counted']
173
174
        if 'is_key_tenant' not in new_values['data'].keys() or \
175
                not isinstance(new_values['data']['is_key_tenant'], bool):
176
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
177
                                   description='API.INVALID_IS_KEY_TENANT_VALUE')
178
        is_key_tenant = new_values['data']['is_key_tenant']
179
180
        if 'lease_number' not in new_values['data'].keys() or \
181
                not isinstance(new_values['data']['lease_number'], str) or \
182
                len(str.strip(new_values['data']['lease_number'])) == 0:
183
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
184
                                   description='API.INVALID_LEASE_NUMBER_VALUE')
185
        lease_number = str.strip(new_values['data']['lease_number'])
186
187
        if 'is_in_lease' not in new_values['data'].keys() or \
188
                not isinstance(new_values['data']['is_in_lease'], bool):
189
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
190
                                   description='API.INVALID_IS_IN_LEASE_VALUE')
191
        is_in_lease = new_values['data']['is_in_lease']
192
193
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
194
        if config.utc_offset[0] == '-':
195
            timezone_offset = -timezone_offset
196
197
        # todo: validate datetime values
198
        lease_start_datetime_utc = datetime.strptime(new_values['data']['lease_start_datetime'],
199
                                                     '%Y-%m-%dT%H:%M:%S')
200
        lease_start_datetime_utc = lease_start_datetime_utc.replace(tzinfo=timezone.utc)
201
        lease_start_datetime_utc -= timedelta(minutes=timezone_offset)
202
203
        lease_end_datetime_utc = datetime.strptime(new_values['data']['lease_end_datetime'],
204
                                                   '%Y-%m-%dT%H:%M:%S')
205
        lease_end_datetime_utc = lease_end_datetime_utc.replace(tzinfo=timezone.utc)
206
        lease_end_datetime_utc -= timedelta(minutes=timezone_offset)
207
208
        if 'contact_id' not in new_values['data'].keys() or \
209
                not isinstance(new_values['data']['contact_id'], int) or \
210
                new_values['data']['contact_id'] <= 0:
211
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
212
                                   description='API.INVALID_CONTACT_ID')
213
        contact_id = new_values['data']['contact_id']
214
215
        if 'cost_center_id' not in new_values['data'].keys() or \
216
                not isinstance(new_values['data']['cost_center_id'], int) or \
217
                new_values['data']['cost_center_id'] <= 0:
218
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
219
                                   description='API.INVALID_COST_CENTER_ID')
220
        cost_center_id = new_values['data']['cost_center_id']
221
222
        if 'description' in new_values['data'].keys() and \
223
                new_values['data']['description'] is not None and \
224
                len(str(new_values['data']['description'])) > 0:
225
            description = str.strip(new_values['data']['description'])
226
        else:
227
            description = None
228
229
        cnx = mysql.connector.connect(**config.myems_system_db)
230
        cursor = cnx.cursor()
231
232
        cursor.execute(" SELECT name "
233
                       " FROM tbl_tenants "
234
                       " WHERE name = %s ", (name,))
235
        if cursor.fetchone() is not None:
236
            cursor.close()
237
            cnx.close()
238
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
239
                                   description='API.TENANT_NAME_IS_ALREADY_IN_USE')
240
241
        cursor.execute(" SELECT name "
242
                       " FROM tbl_tenant_types "
243
                       " WHERE id = %s ",
244
                       (tenant_type_id,))
245
        if cursor.fetchone() is None:
246
            cursor.close()
247
            cnx.close()
248
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
249
                                   description='API.TENANT_TYPE_NOT_FOUND')
250
251
        cursor.execute(" SELECT name "
252
                       " FROM tbl_contacts "
253
                       " WHERE id = %s ",
254
                       (new_values['data']['contact_id'],))
255
        row = cursor.fetchone()
256
        if row is None:
257
            cursor.close()
258
            cnx.close()
259
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
260
                                   description='API.CONTACT_NOT_FOUND')
261
262
        cursor.execute(" SELECT name "
263
                       " FROM tbl_cost_centers "
264
                       " WHERE id = %s ",
265
                       (new_values['data']['cost_center_id'],))
266
        row = cursor.fetchone()
267
        if row is None:
268
            cursor.close()
269
            cnx.close()
270
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
271
                                   description='API.COST_CENTER_NOT_FOUND')
272
273
        add_values = (" INSERT INTO tbl_tenants "
274
                      "    (name, uuid, buildings, floors, rooms, area, tenant_type_id, "
275
                      "     is_input_counted, is_key_tenant, "
276
                      "     lease_number, lease_start_datetime_utc, lease_end_datetime_utc, is_in_lease, "
277
                      "     contact_id, cost_center_id, description) "
278
                      " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
279
        cursor.execute(add_values, (name,
280
                                    str(uuid.uuid4()),
281
                                    buildings,
282
                                    floors,
283
                                    rooms,
284
                                    area,
285
                                    tenant_type_id,
286
                                    is_input_counted,
287
                                    is_key_tenant,
288
                                    lease_number,
289
                                    lease_start_datetime_utc,
290
                                    lease_end_datetime_utc,
291
                                    is_in_lease,
292
                                    contact_id,
293
                                    cost_center_id,
294
                                    description))
295
        new_id = cursor.lastrowid
296
        cnx.commit()
297
        cursor.close()
298
        cnx.close()
299
300
        resp.status = falcon.HTTP_201
301
        resp.location = '/tenants/' + str(new_id)
302
303
304
class TenantItem:
305
    def __init__(self):
306
        """"Initializes TenantItem"""
307
        pass
308
309
    @staticmethod
310
    def on_options(req, resp, id_):
311
        resp.status = falcon.HTTP_200
312
313
    @staticmethod
314
    def on_get(req, resp, id_):
315
        if 'API-KEY' not in req.headers or \
316
                not isinstance(req.headers['API-KEY'], str) or \
317
                len(str.strip(req.headers['API-KEY'])) == 0:
318
            access_control(req)
319
        else:
320
            api_key_control(req)
321
        if not id_.isdigit() or int(id_) <= 0:
322
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
323
                                   description='API.INVALID_TENANT_ID')
324
325
        cnx = mysql.connector.connect(**config.myems_system_db)
326
        cursor = cnx.cursor()
327
328
        query = (" SELECT id, name, uuid "
329
                 " FROM tbl_tenant_types ")
330
        cursor.execute(query)
331
        rows_tenant_types = cursor.fetchall()
332
333
        tenant_type_dict = dict()
334
        if rows_tenant_types is not None and len(rows_tenant_types) > 0:
335
            for row in rows_tenant_types:
336
                tenant_type_dict[row[0]] = {"id": row[0],
337
                                            "name": row[1],
338
                                            "uuid": row[2]}
339
340
        query = (" SELECT id, name, uuid "
341
                 " FROM tbl_contacts ")
342
        cursor.execute(query)
343
        rows_contacts = cursor.fetchall()
344
345
        contact_dict = dict()
346
        if rows_contacts is not None and len(rows_contacts) > 0:
347
            for row in rows_contacts:
348
                contact_dict[row[0]] = {"id": row[0],
349
                                        "name": row[1],
350
                                        "uuid": row[2]}
351
352
        query = (" SELECT id, name, uuid "
353
                 " FROM tbl_cost_centers ")
354
        cursor.execute(query)
355
        rows_cost_centers = cursor.fetchall()
356
357
        cost_center_dict = dict()
358
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
359
            for row in rows_cost_centers:
360
                cost_center_dict[row[0]] = {"id": row[0],
361
                                            "name": row[1],
362
                                            "uuid": row[2]}
363
364
        query = (" SELECT id, name, uuid, "
365
                 "        buildings, floors, rooms, area, tenant_type_id,"
366
                 "        is_key_tenant, is_input_counted, "
367
                 "        lease_number, lease_start_datetime_utc, lease_end_datetime_utc, is_in_lease, "
368
                 "        contact_id, cost_center_id, description "
369
                 " FROM tbl_tenants "
370
                 " WHERE id = %s ")
371
        cursor.execute(query, (id_,))
372
        row = cursor.fetchone()
373
        cursor.close()
374
        cnx.close()
375
376
        if row is None:
377
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
378
                                   description='API.TENANT_NOT_FOUND')
379
        else:
380
            timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
381
            if config.utc_offset[0] == '-':
382
                timezone_offset = -timezone_offset
383
384
            meta_result = {"id": row[0],
385
                           "name": row[1],
386
                           "uuid": row[2],
387
                           "buildings": row[3],
388
                           "floors": row[4],
389
                           "rooms": row[5],
390
                           "area": row[6],
391
                           "tenant_type": tenant_type_dict.get(row[7], None),
392
                           "is_key_tenant": bool(row[8]),
393
                           "is_input_counted": bool(row[9]),
394
                           "lease_number": row[10],
395
                           "lease_start_datetime": (row[11].replace(tzinfo=timezone.utc) +
396
                                                    timedelta(minutes=timezone_offset)).isoformat()[0:19],
397
                           "lease_end_datetime": (row[12].replace(tzinfo=timezone.utc) +
398
                                                  timedelta(minutes=timezone_offset)).isoformat()[0:19],
399
                           "is_in_lease": bool(row[13]),
400
                           "contact": contact_dict.get(row[14], None),
401
                           "cost_center": cost_center_dict.get(row[15], None),
402
                           "description": row[16],
403
                           "qrcode": 'tenant:' + row[2]}
404
405
        resp.text = json.dumps(meta_result)
406
407 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
408
    @user_logger
409
    def on_delete(req, resp, id_):
410
        admin_control(req)
411
        if not id_.isdigit() or int(id_) <= 0:
412
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
413
                                   description='API.INVALID_TENANT_ID')
414
415
        cnx = mysql.connector.connect(**config.myems_system_db)
416
        cursor = cnx.cursor()
417
418
        cursor.execute(" SELECT name "
419
                       " FROM tbl_tenants "
420
                       " WHERE id = %s ", (id_,))
421
        if cursor.fetchone() is None:
422
            cursor.close()
423
            cnx.close()
424
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
425
                                   description='API.TENANT_NOT_FOUND')
426
427
        # check relation with space
428
        cursor.execute(" SELECT space_id "
429
                       " FROM tbl_spaces_tenants "
430
                       " WHERE tenant_id = %s ",
431
                       (id_,))
432
        rows_spaces = cursor.fetchall()
433
        if rows_spaces is not None and len(rows_spaces) > 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_SPACES')
439
440
        # delete relation with meter
441
        cursor.execute(" DELETE FROM tbl_tenants_meters WHERE tenant_id = %s ", (id_,))
442
443
        # delete relation with offline meter
444
        cursor.execute(" DELETE FROM tbl_tenants_offline_meters WHERE tenant_id = %s ", (id_,))
445
446
        # delete relation with points
447
        cursor.execute(" DELETE FROM tbl_tenants_points WHERE tenant_id = %s ", (id_,))
448
449
        # delete relation with sensor
450
        cursor.execute(" DELETE FROM tbl_tenants_sensors WHERE tenant_id = %s ", (id_,))
451
452
        # delete relation with virtual meter
453
        cursor.execute(" DELETE FROM tbl_tenants_virtual_meters WHERE tenant_id = %s ", (id_,))
454
455
        # delete relation with command
456
        cursor.execute(" DELETE FROM tbl_tenants_commands WHERE tenant_id = %s ", (id_,))
457
458
        # delete relation with working calendar
459
        cursor.execute(" DELETE FROM tbl_tenants_working_calendars WHERE tenant_id = %s ", (id_,))
460
461
        cursor.execute(" DELETE FROM tbl_tenants WHERE id = %s ", (id_,))
462
        cnx.commit()
463
464
        cursor.close()
465
        cnx.close()
466
467
        resp.status = falcon.HTTP_204
468
469
    @staticmethod
470
    @user_logger
471
    def on_put(req, resp, id_):
472
        """Handles PUT requests"""
473
        admin_control(req)
474
        try:
475
            raw_json = req.stream.read().decode('utf-8')
476
        except Exception as ex:
477
            raise falcon.HTTPError(status=falcon.HTTP_400,
478
                                   title='API.BAD_REQUEST',
479
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
480
481
        if not id_.isdigit() or int(id_) <= 0:
482
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
483
                                   description='API.INVALID_TENANT_ID')
484
485
        new_values = json.loads(raw_json)
486
487
        if 'name' not in new_values['data'].keys() or \
488
                not isinstance(new_values['data']['name'], str) or \
489
                len(str.strip(new_values['data']['name'])) == 0:
490
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
491
                                   description='API.INVALID_TENANT_NAME')
492
        name = str.strip(new_values['data']['name'])
493
494
        if 'buildings' not in new_values['data'].keys() or \
495
                not isinstance(new_values['data']['buildings'], str) or \
496
                len(str.strip(new_values['data']['buildings'])) == 0:
497
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
498
                                   description='API.INVALID_BUILDINGS_VALUE')
499
        buildings = str.strip(new_values['data']['buildings'])
500
501
        if 'floors' not in new_values['data'].keys() or \
502
                not isinstance(new_values['data']['floors'], str) or \
503
                len(str.strip(new_values['data']['floors'])) == 0:
504
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
505
                                   description='API.INVALID_FLOORS_VALUE')
506
        floors = str.strip(new_values['data']['floors'])
507
508
        if 'rooms' not in new_values['data'].keys() or \
509
                not isinstance(new_values['data']['rooms'], str) or \
510
                len(str.strip(new_values['data']['rooms'])) == 0:
511
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
512
                                   description='API.INVALID_ROOMS_VALUE')
513
        rooms = str.strip(new_values['data']['rooms'])
514
515
        if 'area' not in new_values['data'].keys() or \
516
                not (isinstance(new_values['data']['area'], float) or
517
                     isinstance(new_values['data']['area'], int)) or \
518
                new_values['data']['area'] <= 0.0:
519
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
520
                                   description='API.INVALID_AREA_VALUE')
521
        area = new_values['data']['area']
522
523
        if 'tenant_type_id' not in new_values['data'].keys() or \
524
                not isinstance(new_values['data']['tenant_type_id'], int) or \
525
                new_values['data']['tenant_type_id'] <= 0:
526
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
527
                                   description='API.INVALID_TENANT_TYPE_ID')
528
        tenant_type_id = new_values['data']['tenant_type_id']
529
530
        if 'is_input_counted' not in new_values['data'].keys() or \
531
                not isinstance(new_values['data']['is_input_counted'], bool):
532
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
533
                                   description='API.INVALID_IS_INPUT_COUNTED_VALUE')
534
        is_input_counted = new_values['data']['is_input_counted']
535
536
        if 'is_key_tenant' not in new_values['data'].keys() or \
537
                not isinstance(new_values['data']['is_key_tenant'], bool):
538
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
539
                                   description='API.INVALID_IS_KEY_TENANT_VALUE')
540
        is_key_tenant = new_values['data']['is_key_tenant']
541
542
        if 'lease_number' not in new_values['data'].keys() or \
543
                not isinstance(new_values['data']['lease_number'], str) or \
544
                len(str.strip(new_values['data']['lease_number'])) == 0:
545
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
546
                                   description='API.INVALID_LEASE_NUMBER_VALUE')
547
        lease_number = str.strip(new_values['data']['lease_number'])
548
549
        if 'is_in_lease' not in new_values['data'].keys() or \
550
                not isinstance(new_values['data']['is_in_lease'], bool):
551
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
552
                                   description='API.INVALID_IS_IN_LEASE_VALUE')
553
        is_in_lease = new_values['data']['is_in_lease']
554
555
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
556
        if config.utc_offset[0] == '-':
557
            timezone_offset = -timezone_offset
558
559
        # todo: validate datetime values
560
        lease_start_datetime_utc = datetime.strptime(new_values['data']['lease_start_datetime'],
561
                                                     '%Y-%m-%dT%H:%M:%S')
562
        lease_start_datetime_utc = lease_start_datetime_utc.replace(tzinfo=timezone.utc)
563
        lease_start_datetime_utc -= timedelta(minutes=timezone_offset)
564
565
        lease_end_datetime_utc = datetime.strptime(new_values['data']['lease_end_datetime'],
566
                                                   '%Y-%m-%dT%H:%M:%S')
567
        lease_end_datetime_utc = lease_end_datetime_utc.replace(tzinfo=timezone.utc)
568
        lease_end_datetime_utc -= timedelta(minutes=timezone_offset)
569
570
        if 'contact_id' not in new_values['data'].keys() or \
571
                not isinstance(new_values['data']['contact_id'], int) or \
572
                new_values['data']['contact_id'] <= 0:
573
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
574
                                   description='API.INVALID_CONTACT_ID')
575
        contact_id = new_values['data']['contact_id']
576
577
        if 'cost_center_id' not in new_values['data'].keys() or \
578
                not isinstance(new_values['data']['cost_center_id'], int) or \
579
                new_values['data']['cost_center_id'] <= 0:
580
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
581
                                   description='API.INVALID_COST_CENTER_ID')
582
        cost_center_id = new_values['data']['cost_center_id']
583
584
        if 'description' in new_values['data'].keys() and \
585
                new_values['data']['description'] is not None and \
586
                len(str(new_values['data']['description'])) > 0:
587
            description = str.strip(new_values['data']['description'])
588
        else:
589
            description = None
590
591
        cnx = mysql.connector.connect(**config.myems_system_db)
592
        cursor = cnx.cursor()
593
594
        cursor.execute(" SELECT name "
595
                       " FROM tbl_tenants "
596
                       " WHERE id = %s ", (id_,))
597
        if cursor.fetchone() is None:
598
            cursor.close()
599
            cnx.close()
600
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
601
                                   description='API.TENANT_NOT_FOUND')
602
603
        cursor.execute(" SELECT name "
604
                       " FROM tbl_tenants "
605
                       " WHERE name = %s AND id != %s ", (name, id_))
606
        if cursor.fetchone() is not None:
607
            cursor.close()
608
            cnx.close()
609
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
610
                                   description='API.TENANT_NAME_IS_ALREADY_IN_USE')
611
612
        cursor.execute(" SELECT name "
613
                       " FROM tbl_tenant_types "
614
                       " WHERE id = %s ",
615
                       (tenant_type_id,))
616
        if cursor.fetchone() is None:
617
            cursor.close()
618
            cnx.close()
619
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
620
                                   description='API.TENANT_TYPE_NOT_FOUND')
621
622
        cursor.execute(" SELECT name "
623
                       " FROM tbl_contacts "
624
                       " WHERE id = %s ",
625
                       (new_values['data']['contact_id'],))
626
        row = cursor.fetchone()
627
        if row is None:
628
            cursor.close()
629
            cnx.close()
630
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
631
                                   description='API.CONTACT_NOT_FOUND')
632
633
        cursor.execute(" SELECT name "
634
                       " FROM tbl_cost_centers "
635
                       " WHERE id = %s ",
636
                       (new_values['data']['cost_center_id'],))
637
        row = cursor.fetchone()
638
        if row is None:
639
            cursor.close()
640
            cnx.close()
641
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
642
                                   description='API.COST_CENTER_NOT_FOUND')
643
644
        update_row = (" UPDATE tbl_tenants "
645
                      " SET name = %s, buildings = %s, floors = %s, rooms = %s, area = %s, "
646
                      "     tenant_type_id = %s, is_input_counted = %s, "
647
                      "     is_key_tenant = %s, lease_number = %s, lease_start_datetime_utc = %s, "
648
                      "     lease_end_datetime_utc = %s, is_in_lease = %s, contact_id = %s, cost_center_id = %s, "
649
                      "     description = %s "
650
                      " WHERE id = %s ")
651
        cursor.execute(update_row, (name,
652
                                    buildings,
653
                                    floors,
654
                                    rooms,
655
                                    area,
656
                                    tenant_type_id,
657
                                    is_input_counted,
658
                                    is_key_tenant,
659
                                    lease_number,
660
                                    lease_start_datetime_utc,
661
                                    lease_end_datetime_utc,
662
                                    is_in_lease,
663
                                    contact_id,
664
                                    cost_center_id,
665
                                    description,
666
                                    id_))
667
        cnx.commit()
668
669
        cursor.close()
670
        cnx.close()
671
672
        resp.status = falcon.HTTP_200
673
674
675 View Code Duplication
class TenantMeterCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
676
    def __init__(self):
677
        """Initializes Class"""
678
        pass
679
680
    @staticmethod
681
    def on_options(req, resp, id_):
682
        resp.status = falcon.HTTP_200
683
684
    @staticmethod
685
    def on_get(req, resp, id_):
686
        if 'API-KEY' not in req.headers or \
687
                not isinstance(req.headers['API-KEY'], str) or \
688
                len(str.strip(req.headers['API-KEY'])) == 0:
689
            access_control(req)
690
        else:
691
            api_key_control(req)
692
        if not id_.isdigit() or int(id_) <= 0:
693
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
694
                                   description='API.INVALID_TENANT_ID')
695
696
        cnx = mysql.connector.connect(**config.myems_system_db)
697
        cursor = cnx.cursor()
698
699
        cursor.execute(" SELECT name "
700
                       " FROM tbl_tenants "
701
                       " WHERE id = %s ", (id_,))
702
        if cursor.fetchone() is None:
703
            cursor.close()
704
            cnx.close()
705
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
706
                                   description='API.TENANT_NOT_FOUND')
707
708
        query = (" SELECT id, name, uuid "
709
                 " FROM tbl_energy_categories ")
710
        cursor.execute(query)
711
        rows_energy_categories = cursor.fetchall()
712
713
        energy_category_dict = dict()
714
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
715
            for row in rows_energy_categories:
716
                energy_category_dict[row[0]] = {"id": row[0],
717
                                                "name": row[1],
718
                                                "uuid": row[2]}
719
720
        query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id "
721
                 " FROM tbl_tenants t, tbl_tenants_meters tm, tbl_meters m "
722
                 " WHERE tm.tenant_id = t.id AND m.id = tm.meter_id AND t.id = %s "
723
                 " ORDER BY m.id ")
724
        cursor.execute(query, (id_,))
725
        rows = cursor.fetchall()
726
727
        result = list()
728
        if rows is not None and len(rows) > 0:
729
            for row in rows:
730
                meta_result = {"id": row[0],
731
                               "name": row[1],
732
                               "uuid": row[2],
733
                               "energy_category": energy_category_dict.get(row[3], None)}
734
                result.append(meta_result)
735
736
        resp.text = json.dumps(result)
737
738
    @staticmethod
739
    @user_logger
740
    def on_post(req, resp, id_):
741
        """Handles POST requests"""
742
        admin_control(req)
743
        try:
744
            raw_json = req.stream.read().decode('utf-8')
745
        except Exception as ex:
746
            raise falcon.HTTPError(status=falcon.HTTP_400,
747
                                   title='API.BAD_REQUEST',
748
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
749
750
        if not id_.isdigit() or int(id_) <= 0:
751
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
752
                                   description='API.INVALID_TENANT_ID')
753
754
        new_values = json.loads(raw_json)
755
756
        if 'meter_id' not in new_values['data'].keys() or \
757
                not isinstance(new_values['data']['meter_id'], int) or \
758
                new_values['data']['meter_id'] <= 0:
759
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
760
                                   description='API.INVALID_METER_ID')
761
        meter_id = new_values['data']['meter_id']
762
763
        cnx = mysql.connector.connect(**config.myems_system_db)
764
        cursor = cnx.cursor()
765
766
        cursor.execute(" SELECT name "
767
                       " from tbl_tenants "
768
                       " WHERE id = %s ", (id_,))
769
        if cursor.fetchone() is None:
770
            cursor.close()
771
            cnx.close()
772
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
773
                                   description='API.TENANT_NOT_FOUND')
774
775
        cursor.execute(" SELECT name "
776
                       " FROM tbl_meters "
777
                       " WHERE id = %s ", (meter_id,))
778
        if cursor.fetchone() is None:
779
            cursor.close()
780
            cnx.close()
781
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
782
                                   description='API.METER_NOT_FOUND')
783
784
        query = (" SELECT id " 
785
                 " FROM tbl_tenants_meters "
786
                 " WHERE tenant_id = %s AND meter_id = %s")
787
        cursor.execute(query, (id_, meter_id,))
788
        if cursor.fetchone() is not None:
789
            cursor.close()
790
            cnx.close()
791
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
792
                                   description='API.TENANT_METER_RELATION_EXISTS')
793
794
        add_row = (" INSERT INTO tbl_tenants_meters (tenant_id, meter_id) "
795
                   " VALUES (%s, %s) ")
796
        cursor.execute(add_row, (id_, meter_id,))
797
        cnx.commit()
798
        cursor.close()
799
        cnx.close()
800
801
        resp.status = falcon.HTTP_201
802
        resp.location = '/tenants/' + str(id_) + '/meters/' + str(meter_id)
803
804
805 View Code Duplication
class TenantMeterItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
806
    def __init__(self):
807
        """Initializes Class"""
808
        pass
809
810
    @staticmethod
811
    def on_options(req, resp, id_, mid):
812
        resp.status = falcon.HTTP_200
813
814
    @staticmethod
815
    @user_logger
816
    def on_delete(req, resp, id_, mid):
817
        admin_control(req)
818
        if not id_.isdigit() or int(id_) <= 0:
819
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
820
                                   description='API.INVALID_TENANT_ID')
821
822
        if not mid.isdigit() or int(mid) <= 0:
823
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
824
                                   description='API.INVALID_METER_ID')
825
826
        cnx = mysql.connector.connect(**config.myems_system_db)
827
        cursor = cnx.cursor()
828
829
        cursor.execute(" SELECT name "
830
                       " FROM tbl_tenants "
831
                       " WHERE id = %s ", (id_,))
832
        if cursor.fetchone() is None:
833
            cursor.close()
834
            cnx.close()
835
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
836
                                   description='API.TENANT_NOT_FOUND')
837
838
        cursor.execute(" SELECT name "
839
                       " FROM tbl_meters "
840
                       " WHERE id = %s ", (mid,))
841
        if cursor.fetchone() is None:
842
            cursor.close()
843
            cnx.close()
844
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
845
                                   description='API.METER_NOT_FOUND')
846
847
        cursor.execute(" SELECT id "
848
                       " FROM tbl_tenants_meters "
849
                       " WHERE tenant_id = %s AND meter_id = %s ", (id_, mid))
850
        if cursor.fetchone() is None:
851
            cursor.close()
852
            cnx.close()
853
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
854
                                   description='API.TENANT_METER_RELATION_NOT_FOUND')
855
856
        cursor.execute(" DELETE FROM tbl_tenants_meters WHERE tenant_id = %s AND meter_id = %s ", (id_, mid))
857
        cnx.commit()
858
859
        cursor.close()
860
        cnx.close()
861
862
        resp.status = falcon.HTTP_204
863
864
865 View Code Duplication
class TenantOfflineMeterCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
866
    def __init__(self):
867
        """Initializes Class"""
868
        pass
869
870
    @staticmethod
871
    def on_options(req, resp, id_):
872
        resp.status = falcon.HTTP_200
873
874
    @staticmethod
875
    def on_get(req, resp, id_):
876
        if 'API-KEY' not in req.headers or \
877
                not isinstance(req.headers['API-KEY'], str) or \
878
                len(str.strip(req.headers['API-KEY'])) == 0:
879
            access_control(req)
880
        else:
881
            api_key_control(req)
882
        if not id_.isdigit() or int(id_) <= 0:
883
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
884
                                   description='API.INVALID_TENANT_ID')
885
886
        cnx = mysql.connector.connect(**config.myems_system_db)
887
        cursor = cnx.cursor()
888
889
        cursor.execute(" SELECT name "
890
                       " FROM tbl_tenants "
891
                       " WHERE id = %s ", (id_,))
892
        if cursor.fetchone() is None:
893
            cursor.close()
894
            cnx.close()
895
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
896
                                   description='API.TENANT_NOT_FOUND')
897
898
        query = (" SELECT id, name, uuid "
899
                 " FROM tbl_energy_categories ")
900
        cursor.execute(query)
901
        rows_energy_categories = cursor.fetchall()
902
903
        energy_category_dict = dict()
904
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
905
            for row in rows_energy_categories:
906
                energy_category_dict[row[0]] = {"id": row[0],
907
                                                "name": row[1],
908
                                                "uuid": row[2]}
909
910
        query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id "
911
                 " FROM tbl_tenants s, tbl_tenants_offline_meters sm, tbl_offline_meters m "
912
                 " WHERE sm.tenant_id = s.id AND m.id = sm.offline_meter_id AND s.id = %s "
913
                 " ORDER BY m.id ")
914
        cursor.execute(query, (id_,))
915
        rows = cursor.fetchall()
916
917
        result = list()
918
        if rows is not None and len(rows) > 0:
919
            for row in rows:
920
                meta_result = {"id": row[0],
921
                               "name": row[1],
922
                               "uuid": row[2],
923
                               "energy_category": energy_category_dict.get(row[3], None)}
924
                result.append(meta_result)
925
926
        resp.text = json.dumps(result)
927
928
    @staticmethod
929
    @user_logger
930
    def on_post(req, resp, id_):
931
        """Handles POST requests"""
932
        admin_control(req)
933
        try:
934
            raw_json = req.stream.read().decode('utf-8')
935
        except Exception as ex:
936
            raise falcon.HTTPError(status=falcon.HTTP_400,
937
                                   title='API.BAD_REQUEST',
938
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
939
940
        if not id_.isdigit() or int(id_) <= 0:
941
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
942
                                   description='API.INVALID_TENANT_ID')
943
944
        new_values = json.loads(raw_json)
945
946
        if 'offline_meter_id' not in new_values['data'].keys() or \
947
                not isinstance(new_values['data']['offline_meter_id'], int) or \
948
                new_values['data']['offline_meter_id'] <= 0:
949
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
950
                                   description='API.INVALID_OFFLINE_METER_ID')
951
        offline_meter_id = new_values['data']['offline_meter_id']
952
953
        cnx = mysql.connector.connect(**config.myems_system_db)
954
        cursor = cnx.cursor()
955
956
        cursor.execute(" SELECT name "
957
                       " from tbl_tenants "
958
                       " WHERE id = %s ", (id_,))
959
        if cursor.fetchone() is None:
960
            cursor.close()
961
            cnx.close()
962
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
963
                                   description='API.TENANT_NOT_FOUND')
964
965
        cursor.execute(" SELECT name "
966
                       " FROM tbl_offline_meters "
967
                       " WHERE id = %s ", (offline_meter_id,))
968
        if cursor.fetchone() is None:
969
            cursor.close()
970
            cnx.close()
971
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
972
                                   description='API.OFFLINE_METER_NOT_FOUND')
973
974
        query = (" SELECT id " 
975
                 " FROM tbl_tenants_offline_meters "
976
                 " WHERE tenant_id = %s AND offline_meter_id = %s")
977
        cursor.execute(query, (id_, offline_meter_id,))
978
        if cursor.fetchone() is not None:
979
            cursor.close()
980
            cnx.close()
981
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
982
                                   description='API.TENANT_OFFLINE_METER_RELATION_EXISTS')
983
984
        add_row = (" INSERT INTO tbl_tenants_offline_meters (tenant_id, offline_meter_id) "
985
                   " VALUES (%s, %s) ")
986
        cursor.execute(add_row, (id_, offline_meter_id,))
987
        cnx.commit()
988
        cursor.close()
989
        cnx.close()
990
991
        resp.status = falcon.HTTP_201
992
        resp.location = '/tenants/' + str(id_) + '/offlinemeters/' + str(offline_meter_id)
993
994
995 View Code Duplication
class TenantOfflineMeterItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
996
    def __init__(self):
997
        """Initializes Class"""
998
        pass
999
1000
    @staticmethod
1001
    def on_options(req, resp, id_, mid):
1002
        resp.status = falcon.HTTP_200
1003
1004
    @staticmethod
1005
    @user_logger
1006
    def on_delete(req, resp, id_, mid):
1007
        admin_control(req)
1008
        if not id_.isdigit() or int(id_) <= 0:
1009
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1010
                                   description='API.INVALID_TENANT_ID')
1011
1012
        if not mid.isdigit() or int(mid) <= 0:
1013
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1014
                                   description='API.INVALID_OFFLINE_METER_ID')
1015
1016
        cnx = mysql.connector.connect(**config.myems_system_db)
1017
        cursor = cnx.cursor()
1018
1019
        cursor.execute(" SELECT name "
1020
                       " FROM tbl_tenants "
1021
                       " WHERE id = %s ", (id_,))
1022
        if cursor.fetchone() is None:
1023
            cursor.close()
1024
            cnx.close()
1025
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1026
                                   description='API.TENANT_NOT_FOUND')
1027
1028
        cursor.execute(" SELECT name "
1029
                       " FROM tbl_offline_meters "
1030
                       " WHERE id = %s ", (mid,))
1031
        if cursor.fetchone() is None:
1032
            cursor.close()
1033
            cnx.close()
1034
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1035
                                   description='API.OFFLINE_METER_NOT_FOUND')
1036
1037
        cursor.execute(" SELECT id "
1038
                       " FROM tbl_tenants_offline_meters "
1039
                       " WHERE tenant_id = %s AND offline_meter_id = %s ", (id_, mid))
1040
        if cursor.fetchone() is None:
1041
            cursor.close()
1042
            cnx.close()
1043
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1044
                                   description='API.TENANT_OFFLINE_METER_RELATION_NOT_FOUND')
1045
1046
        cursor.execute(" DELETE FROM tbl_tenants_offline_meters "
1047
                       " WHERE tenant_id = %s AND offline_meter_id = %s ", (id_, mid))
1048
        cnx.commit()
1049
1050
        cursor.close()
1051
        cnx.close()
1052
1053
        resp.status = falcon.HTTP_204
1054
1055
1056 View Code Duplication
class TenantPointCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1057
    def __init__(self):
1058
        """Initializes Class"""
1059
        pass
1060
1061
    @staticmethod
1062
    def on_options(req, resp, id_):
1063
        resp.status = falcon.HTTP_200
1064
1065
    @staticmethod
1066
    def on_get(req, resp, id_):
1067
        if 'API-KEY' not in req.headers or \
1068
                not isinstance(req.headers['API-KEY'], str) or \
1069
                len(str.strip(req.headers['API-KEY'])) == 0:
1070
            access_control(req)
1071
        else:
1072
            api_key_control(req)
1073
        if not id_.isdigit() or int(id_) <= 0:
1074
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1075
                                   description='API.INVALID_TENANT_ID')
1076
1077
        cnx = mysql.connector.connect(**config.myems_system_db)
1078
        cursor = cnx.cursor()
1079
1080
        cursor.execute(" SELECT name "
1081
                       " FROM tbl_tenants "
1082
                       " WHERE id = %s ", (id_,))
1083
        if cursor.fetchone() is None:
1084
            cursor.close()
1085
            cnx.close()
1086
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1087
                                   description='API.TENANT_NOT_FOUND')
1088
1089
        query = (" SELECT id, name, uuid "
1090
                 " FROM tbl_data_sources ")
1091
        cursor.execute(query)
1092
        rows_data_sources = cursor.fetchall()
1093
1094
        data_source_dict = dict()
1095
        if rows_data_sources is not None and len(rows_data_sources) > 0:
1096
            for row in rows_data_sources:
1097
                data_source_dict[row[0]] = {"id": row[0],
1098
                                            "name": row[1],
1099
                                            "uuid": row[2]}
1100
1101
        query = (" SELECT p.id, p.name, p.data_source_id "
1102
                 " FROM tbl_tenants t, tbl_tenants_points tp, tbl_points p "
1103
                 " WHERE tp.tenant_id = t.id AND p.id = tp.point_id AND t.id = %s "
1104
                 " ORDER BY p.id ")
1105
        cursor.execute(query, (id_,))
1106
        rows = cursor.fetchall()
1107
1108
        result = list()
1109
        if rows is not None and len(rows) > 0:
1110
            for row in rows:
1111
                meta_result = {"id": row[0],
1112
                               "name": row[1],
1113
                               "data_source": data_source_dict.get(row[2], None)}
1114
                result.append(meta_result)
1115
1116
        resp.text = json.dumps(result)
1117
1118
    @staticmethod
1119
    @user_logger
1120
    def on_post(req, resp, id_):
1121
        """Handles POST requests"""
1122
        admin_control(req)
1123
        try:
1124
            raw_json = req.stream.read().decode('utf-8')
1125
        except Exception as ex:
1126
            raise falcon.HTTPError(status=falcon.HTTP_400,
1127
                                   title='API.BAD_REQUEST',
1128
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1129
1130
        if not id_.isdigit() or int(id_) <= 0:
1131
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1132
                                   description='API.INVALID_TENANT_ID')
1133
1134
        new_values = json.loads(raw_json)
1135
1136
        if 'point_id' not in new_values['data'].keys() or \
1137
                not isinstance(new_values['data']['point_id'], int) or \
1138
                new_values['data']['point_id'] <= 0:
1139
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1140
                                   description='API.INVALID_POINT_ID')
1141
        point_id = new_values['data']['point_id']
1142
1143
        cnx = mysql.connector.connect(**config.myems_system_db)
1144
        cursor = cnx.cursor()
1145
1146
        cursor.execute(" SELECT name "
1147
                       " from tbl_tenants "
1148
                       " WHERE id = %s ", (id_,))
1149
        if cursor.fetchone() is None:
1150
            cursor.close()
1151
            cnx.close()
1152
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1153
                                   description='API.TENANT_NOT_FOUND')
1154
1155
        cursor.execute(" SELECT name "
1156
                       " FROM tbl_points "
1157
                       " WHERE id = %s ", (point_id,))
1158
        if cursor.fetchone() is None:
1159
            cursor.close()
1160
            cnx.close()
1161
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1162
                                   description='API.POINT_NOT_FOUND')
1163
1164
        query = (" SELECT id " 
1165
                 " FROM tbl_tenants_points "
1166
                 " WHERE tenant_id = %s AND point_id = %s")
1167
        cursor.execute(query, (id_, point_id,))
1168
        if cursor.fetchone() is not None:
1169
            cursor.close()
1170
            cnx.close()
1171
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
1172
                                   description='API.TENANT_POINT_RELATION_EXISTS')
1173
1174
        add_row = (" INSERT INTO tbl_tenants_points (tenant_id, point_id) "
1175
                   " VALUES (%s, %s) ")
1176
        cursor.execute(add_row, (id_, point_id,))
1177
        cnx.commit()
1178
        cursor.close()
1179
        cnx.close()
1180
1181
        resp.status = falcon.HTTP_201
1182
        resp.location = '/tenants/' + str(id_) + '/points/' + str(point_id)
1183
1184
1185 View Code Duplication
class TenantPointItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1186
    def __init__(self):
1187
        """Initializes Class"""
1188
        pass
1189
1190
    @staticmethod
1191
    def on_options(req, resp, id_, pid):
1192
        resp.status = falcon.HTTP_200
1193
1194
    @staticmethod
1195
    @user_logger
1196
    def on_delete(req, resp, id_, pid):
1197
        admin_control(req)
1198
        if not id_.isdigit() or int(id_) <= 0:
1199
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1200
                                   description='API.INVALID_TENANT_ID')
1201
1202
        if not pid.isdigit() or int(pid) <= 0:
1203
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1204
                                   description='API.INVALID_POINT_ID')
1205
1206
        cnx = mysql.connector.connect(**config.myems_system_db)
1207
        cursor = cnx.cursor()
1208
1209
        cursor.execute(" SELECT name "
1210
                       " FROM tbl_tenants "
1211
                       " WHERE id = %s ", (id_,))
1212
        if cursor.fetchone() is None:
1213
            cursor.close()
1214
            cnx.close()
1215
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1216
                                   description='API.TENANT_NOT_FOUND')
1217
1218
        cursor.execute(" SELECT name "
1219
                       " FROM tbl_points "
1220
                       " WHERE id = %s ", (pid,))
1221
        if cursor.fetchone() is None:
1222
            cursor.close()
1223
            cnx.close()
1224
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1225
                                   description='API.POINT_NOT_FOUND')
1226
1227
        cursor.execute(" SELECT id "
1228
                       " FROM tbl_tenants_points "
1229
                       " WHERE tenant_id = %s AND point_id = %s ", (id_, pid))
1230
        if cursor.fetchone() is None:
1231
            cursor.close()
1232
            cnx.close()
1233
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1234
                                   description='API.TENANT_POINT_RELATION_NOT_FOUND')
1235
1236
        cursor.execute(" DELETE FROM tbl_tenants_points "
1237
                       " WHERE tenant_id = %s AND point_id = %s ", (id_, pid))
1238
        cnx.commit()
1239
1240
        cursor.close()
1241
        cnx.close()
1242
1243
        resp.status = falcon.HTTP_204
1244
1245
1246 View Code Duplication
class TenantSensorCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1247
    def __init__(self):
1248
        """Initializes Class"""
1249
        pass
1250
1251
    @staticmethod
1252
    def on_options(req, resp, id_):
1253
        resp.status = falcon.HTTP_200
1254
1255
    @staticmethod
1256
    def on_get(req, resp, id_):
1257
        if 'API-KEY' not in req.headers or \
1258
                not isinstance(req.headers['API-KEY'], str) or \
1259
                len(str.strip(req.headers['API-KEY'])) == 0:
1260
            access_control(req)
1261
        else:
1262
            api_key_control(req)
1263
        if not id_.isdigit() or int(id_) <= 0:
1264
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1265
                                   description='API.INVALID_TENANT_ID')
1266
1267
        cnx = mysql.connector.connect(**config.myems_system_db)
1268
        cursor = cnx.cursor()
1269
1270
        cursor.execute(" SELECT name "
1271
                       " FROM tbl_tenants "
1272
                       " WHERE id = %s ", (id_,))
1273
        if cursor.fetchone() is None:
1274
            cursor.close()
1275
            cnx.close()
1276
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1277
                                   description='API.TENANT_NOT_FOUND')
1278
1279
        query = (" SELECT s.id, s.name, s.uuid "
1280
                 " FROM tbl_tenants t, tbl_tenants_sensors ts, tbl_sensors s "
1281
                 " WHERE ts.tenant_id = t.id AND s.id = ts.sensor_id AND t.id = %s "
1282
                 " ORDER BY s.id ")
1283
        cursor.execute(query, (id_,))
1284
        rows = cursor.fetchall()
1285
1286
        result = list()
1287
        if rows is not None and len(rows) > 0:
1288
            for row in rows:
1289
                meta_result = {"id": row[0],
1290
                               "name": row[1],
1291
                               "uuid": row[2]}
1292
                result.append(meta_result)
1293
1294
        resp.text = json.dumps(result)
1295
1296
    @staticmethod
1297
    @user_logger
1298
    def on_post(req, resp, id_):
1299
        """Handles POST requests"""
1300
        admin_control(req)
1301
        try:
1302
            raw_json = req.stream.read().decode('utf-8')
1303
        except Exception as ex:
1304
            raise falcon.HTTPError(status=falcon.HTTP_400,
1305
                                   title='API.BAD_REQUEST',
1306
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1307
1308
        if not id_.isdigit() or int(id_) <= 0:
1309
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1310
                                   description='API.INVALID_TENANT_ID')
1311
1312
        new_values = json.loads(raw_json)
1313
1314
        if 'sensor_id' not in new_values['data'].keys() or \
1315
                not isinstance(new_values['data']['sensor_id'], int) or \
1316
                new_values['data']['sensor_id'] <= 0:
1317
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1318
                                   description='API.INVALID_SENSOR_ID')
1319
        sensor_id = new_values['data']['sensor_id']
1320
1321
        cnx = mysql.connector.connect(**config.myems_system_db)
1322
        cursor = cnx.cursor()
1323
1324
        cursor.execute(" SELECT name "
1325
                       " from tbl_tenants "
1326
                       " WHERE id = %s ", (id_,))
1327
        if cursor.fetchone() is None:
1328
            cursor.close()
1329
            cnx.close()
1330
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1331
                                   description='API.TENANT_NOT_FOUND')
1332
1333
        cursor.execute(" SELECT name "
1334
                       " FROM tbl_sensors "
1335
                       " WHERE id = %s ", (sensor_id,))
1336
        if cursor.fetchone() is None:
1337
            cursor.close()
1338
            cnx.close()
1339
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1340
                                   description='API.SENSOR_NOT_FOUND')
1341
1342
        query = (" SELECT id " 
1343
                 " FROM tbl_tenants_sensors "
1344
                 " WHERE tenant_id = %s AND sensor_id = %s")
1345
        cursor.execute(query, (id_, sensor_id,))
1346
        if cursor.fetchone() is not None:
1347
            cursor.close()
1348
            cnx.close()
1349
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
1350
                                   description='API.TENANT_SENSOR_RELATION_EXISTS')
1351
1352
        add_row = (" INSERT INTO tbl_tenants_sensors (tenant_id, sensor_id) "
1353
                   " VALUES (%s, %s) ")
1354
        cursor.execute(add_row, (id_, sensor_id,))
1355
        cnx.commit()
1356
        cursor.close()
1357
        cnx.close()
1358
1359
        resp.status = falcon.HTTP_201
1360
        resp.location = '/tenants/' + str(id_) + '/sensors/' + str(sensor_id)
1361
1362
1363 View Code Duplication
class TenantSensorItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1364
    def __init__(self):
1365
        """Initializes Class"""
1366
        pass
1367
1368
    @staticmethod
1369
    def on_options(req, resp, id_, sid):
1370
        resp.status = falcon.HTTP_200
1371
1372
    @staticmethod
1373
    @user_logger
1374
    def on_delete(req, resp, id_, sid):
1375
        admin_control(req)
1376
        if not id_.isdigit() or int(id_) <= 0:
1377
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1378
                                   description='API.INVALID_TENANT_ID')
1379
1380
        if not sid.isdigit() or int(sid) <= 0:
1381
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1382
                                   description='API.INVALID_SENSOR_ID')
1383
1384
        cnx = mysql.connector.connect(**config.myems_system_db)
1385
        cursor = cnx.cursor()
1386
1387
        cursor.execute(" SELECT name "
1388
                       " FROM tbl_tenants "
1389
                       " WHERE id = %s ", (id_,))
1390
        if cursor.fetchone() is None:
1391
            cursor.close()
1392
            cnx.close()
1393
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1394
                                   description='API.TENANT_NOT_FOUND')
1395
1396
        cursor.execute(" SELECT name "
1397
                       " FROM tbl_sensors "
1398
                       " WHERE id = %s ", (sid,))
1399
        if cursor.fetchone() is None:
1400
            cursor.close()
1401
            cnx.close()
1402
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1403
                                   description='API.SENSOR_NOT_FOUND')
1404
1405
        cursor.execute(" SELECT id "
1406
                       " FROM tbl_tenants_sensors "
1407
                       " WHERE tenant_id = %s AND sensor_id = %s ", (id_, sid))
1408
        if cursor.fetchone() is None:
1409
            cursor.close()
1410
            cnx.close()
1411
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1412
                                   description='API.TENANT_SENSOR_RELATION_NOT_FOUND')
1413
1414
        cursor.execute(" DELETE FROM tbl_tenants_sensors WHERE tenant_id = %s AND sensor_id = %s ", (id_, sid))
1415
        cnx.commit()
1416
1417
        cursor.close()
1418
        cnx.close()
1419
1420
        resp.status = falcon.HTTP_204
1421
1422
1423 View Code Duplication
class TenantVirtualMeterCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1424
    def __init__(self):
1425
        """Initializes Class"""
1426
        pass
1427
1428
    @staticmethod
1429
    def on_options(req, resp, id_):
1430
        resp.status = falcon.HTTP_200
1431
1432
    @staticmethod
1433
    def on_get(req, resp, id_):
1434
        if 'API-KEY' not in req.headers or \
1435
                not isinstance(req.headers['API-KEY'], str) or \
1436
                len(str.strip(req.headers['API-KEY'])) == 0:
1437
            access_control(req)
1438
        else:
1439
            api_key_control(req)
1440
        if not id_.isdigit() or int(id_) <= 0:
1441
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1442
                                   description='API.INVALID_TENANT_ID')
1443
1444
        cnx = mysql.connector.connect(**config.myems_system_db)
1445
        cursor = cnx.cursor()
1446
1447
        cursor.execute(" SELECT name "
1448
                       " FROM tbl_tenants "
1449
                       " WHERE id = %s ", (id_,))
1450
        if cursor.fetchone() is None:
1451
            cursor.close()
1452
            cnx.close()
1453
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1454
                                   description='API.TENANT_NOT_FOUND')
1455
1456
        query = (" SELECT id, name, uuid "
1457
                 " FROM tbl_energy_categories ")
1458
        cursor.execute(query)
1459
        rows_energy_categories = cursor.fetchall()
1460
1461
        energy_category_dict = dict()
1462
        if rows_energy_categories is not None and len(rows_energy_categories) > 0:
1463
            for row in rows_energy_categories:
1464
                energy_category_dict[row[0]] = {"id": row[0],
1465
                                                "name": row[1],
1466
                                                "uuid": row[2]}
1467
1468
        query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id "
1469
                 " FROM tbl_tenants t, tbl_tenants_virtual_meters tm, tbl_virtual_meters m "
1470
                 " WHERE tm.tenant_id = t.id AND m.id = tm.virtual_meter_id AND t.id = %s "
1471
                 " ORDER BY m.id ")
1472
        cursor.execute(query, (id_,))
1473
        rows = cursor.fetchall()
1474
1475
        result = list()
1476
        if rows is not None and len(rows) > 0:
1477
            for row in rows:
1478
                meta_result = {"id": row[0],
1479
                               "name": row[1],
1480
                               "uuid": row[2],
1481
                               "energy_category": energy_category_dict.get(row[3], None)}
1482
                result.append(meta_result)
1483
1484
        resp.text = json.dumps(result)
1485
1486
    @staticmethod
1487
    @user_logger
1488
    def on_post(req, resp, id_):
1489
        """Handles POST requests"""
1490
        admin_control(req)
1491
        try:
1492
            raw_json = req.stream.read().decode('utf-8')
1493
        except Exception as ex:
1494
            raise falcon.HTTPError(status=falcon.HTTP_400,
1495
                                   title='API.BAD_REQUEST',
1496
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1497
1498
        if not id_.isdigit() or int(id_) <= 0:
1499
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1500
                                   description='API.INVALID_TENANT_ID')
1501
1502
        new_values = json.loads(raw_json)
1503
1504
        if 'virtual_meter_id' not in new_values['data'].keys() or \
1505
                not isinstance(new_values['data']['virtual_meter_id'], int) or \
1506
                new_values['data']['virtual_meter_id'] <= 0:
1507
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1508
                                   description='API.INVALID_VIRTUAL_METER_ID')
1509
        virtual_meter_id = new_values['data']['virtual_meter_id']
1510
1511
        cnx = mysql.connector.connect(**config.myems_system_db)
1512
        cursor = cnx.cursor()
1513
1514
        cursor.execute(" SELECT name "
1515
                       " from tbl_tenants "
1516
                       " WHERE id = %s ", (id_,))
1517
        if cursor.fetchone() is None:
1518
            cursor.close()
1519
            cnx.close()
1520
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1521
                                   description='API.TENANT_NOT_FOUND')
1522
1523
        cursor.execute(" SELECT name "
1524
                       " FROM tbl_virtual_meters "
1525
                       " WHERE id = %s ", (virtual_meter_id,))
1526
        if cursor.fetchone() is None:
1527
            cursor.close()
1528
            cnx.close()
1529
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1530
                                   description='API.VIRTUAL_METER_NOT_FOUND')
1531
1532
        query = (" SELECT id " 
1533
                 " FROM tbl_tenants_virtual_meters "
1534
                 " WHERE tenant_id = %s AND virtual_meter_id = %s")
1535
        cursor.execute(query, (id_, virtual_meter_id,))
1536
        if cursor.fetchone() is not None:
1537
            cursor.close()
1538
            cnx.close()
1539
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
1540
                                   description='API.TENANT_VIRTUAL_METER_RELATION_EXISTS')
1541
1542
        add_row = (" INSERT INTO tbl_tenants_virtual_meters (tenant_id, virtual_meter_id) "
1543
                   " VALUES (%s, %s) ")
1544
        cursor.execute(add_row, (id_, virtual_meter_id,))
1545
        cnx.commit()
1546
        cursor.close()
1547
        cnx.close()
1548
1549
        resp.status = falcon.HTTP_201
1550
        resp.location = '/tenants/' + str(id_) + '/virtualmeters/' + str(virtual_meter_id)
1551
1552
1553 View Code Duplication
class TenantVirtualMeterItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1554
    def __init__(self):
1555
        """Initializes Class"""
1556
        pass
1557
1558
    @staticmethod
1559
    def on_options(req, resp, id_, mid):
1560
        resp.status = falcon.HTTP_200
1561
1562
    @staticmethod
1563
    @user_logger
1564
    def on_delete(req, resp, id_, mid):
1565
        admin_control(req)
1566
        if not id_.isdigit() or int(id_) <= 0:
1567
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1568
                                   description='API.INVALID_TENANT_ID')
1569
1570
        if not mid.isdigit() or int(mid) <= 0:
1571
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1572
                                   description='API.INVALID_VIRTUAL_METER_ID')
1573
1574
        cnx = mysql.connector.connect(**config.myems_system_db)
1575
        cursor = cnx.cursor()
1576
1577
        cursor.execute(" SELECT name "
1578
                       " FROM tbl_tenants "
1579
                       " WHERE id = %s ", (id_,))
1580
        if cursor.fetchone() is None:
1581
            cursor.close()
1582
            cnx.close()
1583
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1584
                                   description='API.TENANT_NOT_FOUND')
1585
1586
        cursor.execute(" SELECT name "
1587
                       " FROM tbl_virtual_meters "
1588
                       " WHERE id = %s ", (mid,))
1589
        if cursor.fetchone() is None:
1590
            cursor.close()
1591
            cnx.close()
1592
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1593
                                   description='API.VIRTUAL_METER_NOT_FOUND')
1594
1595
        cursor.execute(" SELECT id "
1596
                       " FROM tbl_tenants_virtual_meters "
1597
                       " WHERE tenant_id = %s AND virtual_meter_id = %s ", (id_, mid))
1598
        if cursor.fetchone() is None:
1599
            cursor.close()
1600
            cnx.close()
1601
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1602
                                   description='API.TENANT_VIRTUAL_METER_RELATION_NOT_FOUND')
1603
1604
        cursor.execute(" DELETE FROM tbl_tenants_virtual_meters "
1605
                       " WHERE tenant_id = %s AND virtual_meter_id = %s ", (id_, mid))
1606
        cnx.commit()
1607
1608
        cursor.close()
1609
        cnx.close()
1610
1611
        resp.status = falcon.HTTP_204
1612
1613
1614 View Code Duplication
class TenantWorkingCalendarCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1615
    def __init__(self):
1616
        """Initializes TenantWorkingCalendarCollection Class"""
1617
        pass
1618
1619
    @staticmethod
1620
    def on_options(req, resp, id_):
1621
        resp.status = falcon.HTTP_200
1622
1623
    @staticmethod
1624
    def on_get(req, resp, id_):
1625
        if 'API-KEY' not in req.headers or \
1626
                not isinstance(req.headers['API-KEY'], str) or \
1627
                len(str.strip(req.headers['API-KEY'])) == 0:
1628
            access_control(req)
1629
        else:
1630
            api_key_control(req)
1631
        if not id_.isdigit() or int(id_) <= 0:
1632
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1633
                                   description='API.INVALID_TENANT_ID')
1634
1635
        cnx = mysql.connector.connect(**config.myems_system_db)
1636
        cursor = cnx.cursor()
1637
1638
        cursor.execute(" SELECT name "
1639
                       " FROM tbl_tenants "
1640
                       " WHERE id = %s ", (id_,))
1641
        if cursor.fetchone() is None:
1642
            cursor.close()
1643
            cnx.close()
1644
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1645
                                   description='API.TENANT_NOT_FOUND')
1646
1647
        query = (" SELECT wc.id, wc.name, wc.description "
1648
                 " FROM tbl_tenants t, tbl_tenants_working_calendars twc, tbl_working_calendars wc "
1649
                 " WHERE twc.tenant_id = t.id AND wc.id = twc.working_calendar_id AND t.id = %s "
1650
                 " ORDER BY wc.id ")
1651
        cursor.execute(query, (id_,))
1652
        rows = cursor.fetchall()
1653
1654
        result = list()
1655
        if rows is not None and len(rows) > 0:
1656
            for row in rows:
1657
                meta_result = {"id": row[0],
1658
                               "name": row[1],
1659
                               "description": row[2]}
1660
                result.append(meta_result)
1661
1662
        resp.text = json.dumps(result)
1663
1664
    @staticmethod
1665
    @user_logger
1666
    def on_post(req, resp, id_):
1667
        """Handles POST requests"""
1668
        admin_control(req)
1669
        try:
1670
            raw_json = req.stream.read().decode('utf-8')
1671
        except Exception as ex:
1672
            raise falcon.HTTPError(status=falcon.HTTP_400,
1673
                                   title='API.BAD_REQUEST',
1674
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1675
1676
        if not id_.isdigit() or int(id_) <= 0:
1677
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1678
                                   description='API.INVALID_TENANT_ID')
1679
1680
        new_values = json.loads(raw_json)
1681
1682
        if 'working_calendar_id' not in new_values['data'].keys() or \
1683
                not isinstance(new_values['data']['working_calendar_id'], int) or \
1684
                new_values['data']['working_calendar_id'] <= 0:
1685
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1686
                                   description='API.INVALID_WORKING_CALENDAR_ID')
1687
        working_calendar_id = new_values['data']['working_calendar_id']
1688
1689
        cnx = mysql.connector.connect(**config.myems_system_db)
1690
        cursor = cnx.cursor()
1691
1692
        cursor.execute(" SELECT name "
1693
                       " from tbl_tenants "
1694
                       " WHERE id = %s ", (id_,))
1695
        if cursor.fetchone() is None:
1696
            cursor.close()
1697
            cnx.close()
1698
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1699
                                   description='API.TENANT_NOT_FOUND')
1700
1701
        cursor.execute(" SELECT name "
1702
                       " FROM tbl_working_calendars "
1703
                       " WHERE id = %s ", (working_calendar_id,))
1704
        if cursor.fetchone() is None:
1705
            cursor.close()
1706
            cnx.close()
1707
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1708
                                   description='API.WORKING_CALENDAR_NOT_FOUND')
1709
1710
        query = (" SELECT id " 
1711
                 " FROM tbl_tenants_working_calendars "
1712
                 " WHERE tenant_id = %s AND working_calendar_id = %s")
1713
        cursor.execute(query, (id_, working_calendar_id,))
1714
        if cursor.fetchone() is not None:
1715
            cursor.close()
1716
            cnx.close()
1717
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
1718
                                   description='API.TENANT_WORKING_CALENDAR_RELATION_EXISTS')
1719
1720
        add_row = (" INSERT INTO tbl_tenants_working_calendars (tenant_id, working_calendar_id) "
1721
                   " VALUES (%s, %s) ")
1722
        cursor.execute(add_row, (id_, working_calendar_id,))
1723
        cnx.commit()
1724
        cursor.close()
1725
        cnx.close()
1726
1727
        resp.status = falcon.HTTP_201
1728
        resp.location = '/tenants/' + str(id_) + '/workingcalendars/' + str(working_calendar_id)
1729
1730
1731 View Code Duplication
class TenantWorkingCalendarItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1732
    def __init__(self):
1733
        """Initializes TenantWorkingCalendarItem Class"""
1734
        pass
1735
1736
    @staticmethod
1737
    def on_options(req, resp, id_, wcid):
1738
        resp.status = falcon.HTTP_200
1739
1740
    @staticmethod
1741
    @user_logger
1742
    def on_delete(req, resp, id_, wcid):
1743
        admin_control(req)
1744
        if not id_.isdigit() or int(id_) <= 0:
1745
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1746
                                   description='API.INVALID_TENANT_ID')
1747
1748
        if not wcid.isdigit() or int(wcid) <= 0:
1749
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1750
                                   description='API.INVALID_WORKING_CALENDAR_ID')
1751
1752
        cnx = mysql.connector.connect(**config.myems_system_db)
1753
        cursor = cnx.cursor()
1754
1755
        cursor.execute(" SELECT name "
1756
                       " FROM tbl_tenants "
1757
                       " WHERE id = %s ", (id_,))
1758
        if cursor.fetchone() is None:
1759
            cursor.close()
1760
            cnx.close()
1761
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1762
                                   description='API.TENANT_NOT_FOUND')
1763
1764
        cursor.execute(" SELECT name "
1765
                       " FROM tbl_working_calendars "
1766
                       " WHERE id = %s ", (wcid,))
1767
        if cursor.fetchone() is None:
1768
            cursor.close()
1769
            cnx.close()
1770
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1771
                                   description='API.WORKING_CALENDAR_NOT_FOUND')
1772
1773
        cursor.execute(" SELECT id "
1774
                       " FROM tbl_tenants_working_calendars "
1775
                       " WHERE tenant_id = %s AND working_calendar_id = %s ", (id_, wcid))
1776
        if cursor.fetchone() is None:
1777
            cursor.close()
1778
            cnx.close()
1779
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1780
                                   description='API.TENANT_WORKING_CALENDAR_RELATION_NOT_FOUND')
1781
1782
        cursor.execute(" DELETE FROM tbl_tenants_working_calendars "
1783
                       " WHERE tenant_id = %s AND working_calendar_id = %s ", (id_, wcid))
1784
        cnx.commit()
1785
1786
        cursor.close()
1787
        cnx.close()
1788
1789
        resp.status = falcon.HTTP_204
1790
1791
1792 View Code Duplication
class TenantCommandCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1793
    def __init__(self):
1794
        """Initializes Class"""
1795
        pass
1796
1797
    @staticmethod
1798
    def on_options(req, resp, id_):
1799
        resp.status = falcon.HTTP_200
1800
1801
    @staticmethod
1802
    def on_get(req, resp, id_):
1803
        if 'API-KEY' not in req.headers or \
1804
                not isinstance(req.headers['API-KEY'], str) or \
1805
                len(str.strip(req.headers['API-KEY'])) == 0:
1806
            access_control(req)
1807
        else:
1808
            api_key_control(req)
1809
        if not id_.isdigit() or int(id_) <= 0:
1810
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1811
                                   description='API.INVALID_TENANT_ID')
1812
1813
        cnx = mysql.connector.connect(**config.myems_system_db)
1814
        cursor = cnx.cursor()
1815
1816
        cursor.execute(" SELECT name "
1817
                       " FROM tbl_tenants "
1818
                       " WHERE id = %s ", (id_,))
1819
        if cursor.fetchone() is None:
1820
            cursor.close()
1821
            cnx.close()
1822
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1823
                                   description='API.TENANT_NOT_FOUND')
1824
1825
        query = (" SELECT c.id, c.name, c.uuid "
1826
                 " FROM tbl_tenants t, tbl_tenants_commands tc, tbl_commands c "
1827
                 " WHERE tc.tenant_id = t.id AND c.id = tc.command_id AND t.id = %s "
1828
                 " ORDER BY c.id ")
1829
        cursor.execute(query, (id_,))
1830
        rows = cursor.fetchall()
1831
1832
        result = list()
1833
        if rows is not None and len(rows) > 0:
1834
            for row in rows:
1835
                meta_result = {"id": row[0],
1836
                               "name": row[1],
1837
                               "uuid": row[2]}
1838
                result.append(meta_result)
1839
1840
        resp.text = json.dumps(result)
1841
1842
    @staticmethod
1843
    @user_logger
1844
    def on_post(req, resp, id_):
1845
        """Handles POST requests"""
1846
        admin_control(req)
1847
        try:
1848
            raw_json = req.stream.read().decode('utf-8')
1849
        except Exception as ex:
1850
            raise falcon.HTTPError(status=falcon.HTTP_400,
1851
                                   title='API.BAD_REQUEST',
1852
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
1853
1854
        if not id_.isdigit() or int(id_) <= 0:
1855
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1856
                                   description='API.INVALID_TENANT_ID')
1857
1858
        new_values = json.loads(raw_json)
1859
1860
        if 'command_id' not in new_values['data'].keys() or \
1861
                not isinstance(new_values['data']['command_id'], int) or \
1862
                new_values['data']['command_id'] <= 0:
1863
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1864
                                   description='API.INVALID_COMMAND_ID')
1865
        command_id = new_values['data']['command_id']
1866
1867
        cnx = mysql.connector.connect(**config.myems_system_db)
1868
        cursor = cnx.cursor()
1869
1870
        cursor.execute(" SELECT name "
1871
                       " from tbl_tenants "
1872
                       " WHERE id = %s ", (id_,))
1873
        if cursor.fetchone() is None:
1874
            cursor.close()
1875
            cnx.close()
1876
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1877
                                   description='API.TENANT_NOT_FOUND')
1878
1879
        cursor.execute(" SELECT name "
1880
                       " FROM tbl_commands "
1881
                       " WHERE id = %s ", (command_id,))
1882
        if cursor.fetchone() is None:
1883
            cursor.close()
1884
            cnx.close()
1885
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1886
                                   description='API.COMMAND_NOT_FOUND')
1887
1888
        query = (" SELECT id " 
1889
                 " FROM tbl_tenants_commands "
1890
                 " WHERE tenant_id = %s AND command_id = %s")
1891
        cursor.execute(query, (id_, command_id,))
1892
        if cursor.fetchone() is not None:
1893
            cursor.close()
1894
            cnx.close()
1895
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
1896
                                   description='API.TENANT_COMMAND_RELATION_EXISTS')
1897
1898
        add_row = (" INSERT INTO tbl_tenants_commands (tenant_id, command_id) "
1899
                   " VALUES (%s, %s) ")
1900
        cursor.execute(add_row, (id_, command_id,))
1901
        cnx.commit()
1902
        cursor.close()
1903
        cnx.close()
1904
1905
        resp.status = falcon.HTTP_201
1906
        resp.location = '/tenants/' + str(id_) + '/commands/' + str(command_id)
1907
1908
1909 View Code Duplication
class TenantCommandItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1910
    def __init__(self):
1911
        """Initializes Class"""
1912
        pass
1913
1914
    @staticmethod
1915
    def on_options(req, resp, id_, cid):
1916
        resp.status = falcon.HTTP_200
1917
1918
    @staticmethod
1919
    @user_logger
1920
    def on_delete(req, resp, id_, cid):
1921
        admin_control(req)
1922
        if not id_.isdigit() or int(id_) <= 0:
1923
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1924
                                   description='API.INVALID_TENANT_ID')
1925
1926
        if not cid.isdigit() or int(cid) <= 0:
1927
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1928
                                   description='API.INVALID_COMMAND_ID')
1929
1930
        cnx = mysql.connector.connect(**config.myems_system_db)
1931
        cursor = cnx.cursor()
1932
1933
        cursor.execute(" SELECT name "
1934
                       " FROM tbl_tenants "
1935
                       " WHERE id = %s ", (id_,))
1936
        if cursor.fetchone() is None:
1937
            cursor.close()
1938
            cnx.close()
1939
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1940
                                   description='API.TENANT_NOT_FOUND')
1941
1942
        cursor.execute(" SELECT name "
1943
                       " FROM tbl_commands "
1944
                       " WHERE id = %s ", (cid,))
1945
        if cursor.fetchone() is None:
1946
            cursor.close()
1947
            cnx.close()
1948
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1949
                                   description='API.COMMAND_NOT_FOUND')
1950
1951
        cursor.execute(" SELECT id "
1952
                       " FROM tbl_tenants_commands "
1953
                       " WHERE tenant_id = %s AND command_id = %s ", (id_, cid))
1954
        if cursor.fetchone() is None:
1955
            cursor.close()
1956
            cnx.close()
1957
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
1958
                                   description='API.TENANT_COMMAND_RELATION_NOT_FOUND')
1959
1960
        cursor.execute(" DELETE FROM tbl_tenants_commands WHERE tenant_id = %s AND command_id = %s ", (id_, cid))
1961
        cnx.commit()
1962
1963
        cursor.close()
1964
        cnx.close()
1965
1966
        resp.status = falcon.HTTP_204
1967
1968
1969
class TenantExport:
1970
    def __init__(self):
1971
        """"Initializes TenantExport"""
1972
        pass
1973
1974
    @staticmethod
1975
    def on_options(req, resp, id_):
1976
        resp.status = falcon.HTTP_200
1977
1978
    @staticmethod
1979
    def on_get(req, resp, id_):
1980
        if 'API-KEY' not in req.headers or \
1981
                not isinstance(req.headers['API-KEY'], str) or \
1982
                len(str.strip(req.headers['API-KEY'])) == 0:
1983
            access_control(req)
1984
        else:
1985
            api_key_control(req)
1986
        if not id_.isdigit() or int(id_) <= 0:
1987
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
1988
                                   description='API.INVALID_TENANT_ID')
1989
1990
        cnx = mysql.connector.connect(**config.myems_system_db)
1991
        cursor = cnx.cursor()
1992
1993
        query = (" SELECT id, name, uuid "
1994
                 " FROM tbl_tenant_types ")
1995
        cursor.execute(query)
1996
        rows_tenant_types = cursor.fetchall()
1997
1998
        tenant_type_dict = dict()
1999
        if rows_tenant_types is not None and len(rows_tenant_types) > 0:
2000
            for row in rows_tenant_types:
2001
                tenant_type_dict[row[0]] = {"id": row[0],
2002
                                            "name": row[1],
2003
                                            "uuid": row[2]}
2004
2005
        query = (" SELECT id, name, uuid "
2006
                 " FROM tbl_contacts ")
2007
        cursor.execute(query)
2008
        rows_contacts = cursor.fetchall()
2009
2010
        contact_dict = dict()
2011
        if rows_contacts is not None and len(rows_contacts) > 0:
2012
            for row in rows_contacts:
2013
                contact_dict[row[0]] = {"id": row[0],
2014
                                        "name": row[1],
2015
                                        "uuid": row[2]}
2016
2017
        query = (" SELECT id, name, uuid "
2018
                 " FROM tbl_cost_centers ")
2019
        cursor.execute(query)
2020
        rows_cost_centers = cursor.fetchall()
2021
2022
        cost_center_dict = dict()
2023
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
2024
            for row in rows_cost_centers:
2025
                cost_center_dict[row[0]] = {"id": row[0],
2026
                                            "name": row[1],
2027
                                            "uuid": row[2]}
2028
2029
        query = (" SELECT id, name, uuid, "
2030
                 "        buildings, floors, rooms, area, tenant_type_id,"
2031
                 "        is_key_tenant, is_input_counted, "
2032
                 "        lease_number, lease_start_datetime_utc, lease_end_datetime_utc, is_in_lease, "
2033
                 "        contact_id, cost_center_id, description "
2034
                 " FROM tbl_tenants "
2035
                 " WHERE id = %s ")
2036
        cursor.execute(query, (id_,))
2037
        row = cursor.fetchone()
2038
2039
        if row is None:
2040
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2041
                                   description='API.TENANT_NOT_FOUND')
2042
        else:
2043
            timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
2044
            if config.utc_offset[0] == '-':
2045
                timezone_offset = -timezone_offset
2046
2047
            meta_result = {"id": row[0],
2048
                           "name": row[1],
2049
                           "uuid": row[2],
2050
                           "buildings": row[3],
2051
                           "floors": row[4],
2052
                           "rooms": row[5],
2053
                           "area": row[6],
2054
                           "tenant_type": tenant_type_dict.get(row[7], None),
2055
                           "is_key_tenant": bool(row[8]),
2056
                           "is_input_counted": bool(row[9]),
2057
                           "lease_number": row[10],
2058
                           "lease_start_datetime": (row[11].replace(tzinfo=timezone.utc) +
2059
                                                    timedelta(minutes=timezone_offset)).isoformat()[0:19],
2060
                           "lease_end_datetime": (row[12].replace(tzinfo=timezone.utc) +
2061
                                                  timedelta(minutes=timezone_offset)).isoformat()[0:19],
2062
                           "is_in_lease": bool(row[13]),
2063
                           "contact": contact_dict.get(row[14], None),
2064
                           "cost_center": cost_center_dict.get(row[15], None),
2065
                           "description": row[16],
2066
                           "commands": None,
2067
                           "meters": None,
2068
                           "offline_meters": None,
2069
                           "virtual_meters": None,
2070
                           "points": None,
2071
                           "sensors": None,
2072
                           "working_calendars": None
2073
                           }
2074
            query = (" SELECT c.id, c.name, c.uuid "
2075
                     " FROM tbl_tenants t, tbl_tenants_commands tc, tbl_commands c "
2076
                     " WHERE tc.tenant_id = t.id AND c.id = tc.command_id AND t.id = %s "
2077
                     " ORDER BY c.id ")
2078
            cursor.execute(query, (id_,))
2079
            rows = cursor.fetchall()
2080
2081
            command_result = list()
2082
            if rows is not None and len(rows) > 0:
2083
                for row in rows:
2084
                    result = {"id": row[0], "name": row[1], "uuid": row[2]}
2085
                    command_result.append(result)
2086
                meta_result['commands'] = command_result
2087
            query = (" SELECT id, name, uuid "
2088
                     " FROM tbl_energy_categories ")
2089
            cursor.execute(query)
2090
            rows_energy_categories = cursor.fetchall()
2091
2092
            energy_category_dict = dict()
2093
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2094
                for row in rows_energy_categories:
2095
                    energy_category_dict[row[0]] = {"id": row[0],
2096
                                                    "name": row[1],
2097
                                                    "uuid": row[2]}
2098
2099
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id "
2100
                     " FROM tbl_tenants t, tbl_tenants_meters tm, tbl_meters m "
2101
                     " WHERE tm.tenant_id = t.id AND m.id = tm.meter_id AND t.id = %s "
2102
                     " ORDER BY m.id ")
2103
            cursor.execute(query, (id_,))
2104
            rows = cursor.fetchall()
2105
2106
            meter_result = list()
2107
            if rows is not None and len(rows) > 0:
2108
                for row in rows:
2109
                    energy_category = energy_category_dict.get(row[3], None)
2110
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
2111
                              "energy_category": energy_category}
2112
                    meter_result.append(result)
2113
                meta_result['meters'] = meter_result
2114
            query = (" SELECT id, name, uuid "
2115
                     " FROM tbl_energy_categories ")
2116
            cursor.execute(query)
2117
            rows_energy_categories = cursor.fetchall()
2118
2119
            energy_category_dict = dict()
2120
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2121
                for row in rows_energy_categories:
2122
                    energy_category_dict[row[0]] = {"id": row[0],
2123
                                                    "name": row[1],
2124
                                                    "uuid": row[2]}
2125
2126
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id "
2127
                     " FROM tbl_tenants s, tbl_tenants_offline_meters sm, tbl_offline_meters m "
2128
                     " WHERE sm.tenant_id = s.id AND m.id = sm.offline_meter_id AND s.id = %s "
2129
                     " ORDER BY m.id ")
2130
            cursor.execute(query, (id_,))
2131
            rows = cursor.fetchall()
2132
2133
            offlinemeter_result = list()
2134
            if rows is not None and len(rows) > 0:
2135
                for row in rows:
2136
                    energy_category = energy_category_dict.get(row[3], None)
2137
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
2138
                              "energy_category": energy_category}
2139
                    offlinemeter_result.append(result)
2140
                meta_result['offline_meters'] = offlinemeter_result
2141
            query = (" SELECT id, name, uuid "
2142
                     " FROM tbl_energy_categories ")
2143
            cursor.execute(query)
2144
            rows_energy_categories = cursor.fetchall()
2145
2146
            energy_category_dict = dict()
2147
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2148
                for row in rows_energy_categories:
2149
                    energy_category_dict[row[0]] = {"id": row[0],
2150
                                                    "name": row[1],
2151
                                                    "uuid": row[2]}
2152
2153
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id "
2154
                     " FROM tbl_tenants t, tbl_tenants_virtual_meters tm, tbl_virtual_meters m "
2155
                     " WHERE tm.tenant_id = t.id AND m.id = tm.virtual_meter_id AND t.id = %s "
2156
                     " ORDER BY m.id ")
2157
            cursor.execute(query, (id_,))
2158
            rows = cursor.fetchall()
2159
2160
            virtualmeter_result = list()
2161
            if rows is not None and len(rows) > 0:
2162
                for row in rows:
2163
                    energy_category = energy_category_dict.get(row[3], None)
2164
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
2165
                              "energy_category": energy_category}
2166
                    virtualmeter_result.append(result)
2167
                meta_result['virtual_meters'] = virtualmeter_result
2168
            query = (" SELECT id, name, uuid "
2169
                     " FROM tbl_data_sources ")
2170
            cursor.execute(query)
2171
            rows_data_sources = cursor.fetchall()
2172
2173
            data_source_dict = dict()
2174
            if rows_data_sources is not None and len(rows_data_sources) > 0:
2175
                for row in rows_data_sources:
2176
                    data_source_dict[row[0]] = {"id": row[0],
2177
                                                "name": row[1],
2178
                                                "uuid": row[2]}
2179
2180
            query = (" SELECT p.id, p.name, p.data_source_id "
2181
                     " FROM tbl_tenants t, tbl_tenants_points tp, tbl_points p "
2182
                     " WHERE tp.tenant_id = t.id AND p.id = tp.point_id AND t.id = %s "
2183
                     " ORDER BY p.id ")
2184
            cursor.execute(query, (id_,))
2185
            rows = cursor.fetchall()
2186
2187
            point_result = list()
2188
            if rows is not None and len(rows) > 0:
2189
                for row in rows:
2190
                    data_source = data_source_dict.get(row[2], None)
2191
                    result = {"id": row[0], "name": row[1], "data_source": data_source}
2192
                    point_result.append(result)
2193
                meta_result['points'] = point_result
2194
            query = (" SELECT s.id, s.name, s.uuid "
2195
                     " FROM tbl_tenants t, tbl_tenants_sensors ts, tbl_sensors s "
2196
                     " WHERE ts.tenant_id = t.id AND s.id = ts.sensor_id AND t.id = %s "
2197
                     " ORDER BY s.id ")
2198
            cursor.execute(query, (id_,))
2199
            rows = cursor.fetchall()
2200
2201
            sensor_result = list()
2202
            if rows is not None and len(rows) > 0:
2203
                for row in rows:
2204
                    result = {"id": row[0], "name": row[1], "uuid": row[2]}
2205
                    sensor_result.append(result)
2206
                meta_result['sensors'] = sensor_result
2207
            query = (" SELECT wc.id, wc.name, wc.description "
2208
                     " FROM tbl_tenants t, tbl_tenants_working_calendars twc, tbl_working_calendars wc "
2209
                     " WHERE twc.tenant_id = t.id AND wc.id = twc.working_calendar_id AND t.id = %s "
2210
                     " ORDER BY wc.id ")
2211
            cursor.execute(query, (id_,))
2212
            rows = cursor.fetchall()
2213
2214
            workingcalendars_result = list()
2215
            if rows is not None and len(rows) > 0:
2216
                for row in rows:
2217
                    result = {"id": row[0], "name": row[1], "description": row[2]}
2218
                    workingcalendars_result.append(result)
2219
                meta_result['working_calendars'] = workingcalendars_result
2220
2221
        cursor.close()
2222
        cnx.close()
2223
        resp.text = json.dumps(meta_result)
2224
2225
2226
class TenantImport:
2227
    def __init__(self):
2228
        """"Initializes TenantImport"""
2229
        pass
2230
2231
    @staticmethod
2232
    def on_options(req, resp):
2233
        resp.status = falcon.HTTP_200
2234
2235
    @staticmethod
2236
    @user_logger
2237
    def on_post(req, resp):
2238
        """Handles POST requests"""
2239
        admin_control(req)
2240
        try:
2241
            raw_json = req.stream.read().decode('utf-8')
2242
        except Exception as ex:
2243
            raise falcon.HTTPError(status=falcon.HTTP_400,
2244
                                   title='API.BAD_REQUEST',
2245
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
2246
2247
        new_values = json.loads(raw_json)
2248
2249
        if 'name' not in new_values.keys() or \
2250
                not isinstance(new_values['name'], str) or \
2251
                len(str.strip(new_values['name'])) == 0:
2252
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2253
                                   description='API.INVALID_TENANT_NAME')
2254
        name = str.strip(new_values['name'])
2255
2256
        if 'buildings' not in new_values.keys() or \
2257
                not isinstance(new_values['buildings'], str) or \
2258
                len(str.strip(new_values['buildings'])) == 0:
2259
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2260
                                   description='API.INVALID_BUILDINGS_VALUE')
2261
        buildings = str.strip(new_values['buildings'])
2262
2263
        if 'floors' not in new_values.keys() or \
2264
                not isinstance(new_values['floors'], str) or \
2265
                len(str.strip(new_values['floors'])) == 0:
2266
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2267
                                   description='API.INVALID_FLOORS_VALUE')
2268
        floors = str.strip(new_values['floors'])
2269
2270
        if 'rooms' not in new_values.keys() or \
2271
                not isinstance(new_values['rooms'], str) or \
2272
                len(str.strip(new_values['rooms'])) == 0:
2273
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2274
                                   description='API.INVALID_ROOMS_VALUE')
2275
        rooms = str.strip(new_values['rooms'])
2276
2277
        if 'area' not in new_values.keys() or \
2278
                not (isinstance(new_values['area'], float) or
2279
                     isinstance(new_values['area'], int)) or \
2280
                new_values['area'] <= 0.0:
2281
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2282
                                   description='API.INVALID_AREA_VALUE')
2283
        area = new_values['area']
2284
2285
        if 'id' not in new_values['tenant_type'].keys() or \
2286
                not isinstance(new_values['tenant_type']['id'], int) or \
2287
                new_values['tenant_type']['id'] <= 0:
2288
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2289
                                   description='API.INVALID_TENANT_TYPE_ID')
2290
        tenant_type_id = new_values['tenant_type']['id']
2291
2292
        if 'is_input_counted' not in new_values.keys() or \
2293
                not isinstance(new_values['is_input_counted'], bool):
2294
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2295
                                   description='API.INVALID_IS_INPUT_COUNTED_VALUE')
2296
        is_input_counted = new_values['is_input_counted']
2297
2298
        if 'is_key_tenant' not in new_values.keys() or \
2299
                not isinstance(new_values['is_key_tenant'], bool):
2300
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2301
                                   description='API.INVALID_IS_KEY_TENANT_VALUE')
2302
        is_key_tenant = new_values['is_key_tenant']
2303
2304
        if 'lease_number' not in new_values.keys() or \
2305
                not isinstance(new_values['lease_number'], str) or \
2306
                len(str.strip(new_values['lease_number'])) == 0:
2307
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2308
                                   description='API.INVALID_LEASE_NUMBER_VALUE')
2309
        lease_number = str.strip(new_values['lease_number'])
2310
2311
        if 'is_in_lease' not in new_values.keys() or \
2312
                not isinstance(new_values['is_in_lease'], bool):
2313
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2314
                                   description='API.INVALID_IS_IN_LEASE_VALUE')
2315
        is_in_lease = new_values['is_in_lease']
2316
2317
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
2318
        if config.utc_offset[0] == '-':
2319
            timezone_offset = -timezone_offset
2320
2321
        # todo: validate datetime values
2322
        lease_start_datetime_utc = datetime.strptime(new_values['lease_start_datetime'],
2323
                                                     '%Y-%m-%dT%H:%M:%S')
2324
        lease_start_datetime_utc = lease_start_datetime_utc.replace(tzinfo=timezone.utc)
2325
        lease_start_datetime_utc -= timedelta(minutes=timezone_offset)
2326
2327
        lease_end_datetime_utc = datetime.strptime(new_values['lease_end_datetime'],
2328
                                                   '%Y-%m-%dT%H:%M:%S')
2329
        lease_end_datetime_utc = lease_end_datetime_utc.replace(tzinfo=timezone.utc)
2330
        lease_end_datetime_utc -= timedelta(minutes=timezone_offset)
2331
2332
        if 'id' not in new_values['contact'].keys() or \
2333
                not isinstance(new_values['contact']['id'], int) or \
2334
                new_values['contact']['id'] <= 0:
2335
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2336
                                   description='API.INVALID_CONTACT_ID')
2337
        contact_id = new_values['contact']['id']
2338
2339
        if 'id' not in new_values['cost_center'].keys() or \
2340
                not isinstance(new_values['cost_center']['id'], int) or \
2341
                new_values['cost_center']['id'] <= 0:
2342
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2343
                                   description='API.INVALID_COST_CENTER_ID')
2344
        cost_center_id = new_values['cost_center']['id']
2345
2346
        if 'description' in new_values.keys() and \
2347
                new_values['description'] is not None and \
2348
                len(str(new_values['description'])) > 0:
2349
            description = str.strip(new_values['description'])
2350
        else:
2351
            description = None
2352
2353
        cnx = mysql.connector.connect(**config.myems_system_db)
2354
        cursor = cnx.cursor()
2355
2356
        cursor.execute(" SELECT name "
2357
                       " FROM tbl_tenants "
2358
                       " WHERE name = %s ", (name,))
2359
        if cursor.fetchone() is not None:
2360
            cursor.close()
2361
            cnx.close()
2362
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2363
                                   description='API.TENANT_NAME_IS_ALREADY_IN_USE')
2364
2365
        cursor.execute(" SELECT name "
2366
                       " FROM tbl_tenant_types "
2367
                       " WHERE id = %s ",
2368
                       (tenant_type_id,))
2369
        if cursor.fetchone() is None:
2370
            cursor.close()
2371
            cnx.close()
2372
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2373
                                   description='API.TENANT_TYPE_NOT_FOUND')
2374
2375
        cursor.execute(" SELECT name "
2376
                       " FROM tbl_contacts "
2377
                       " WHERE id = %s ",
2378
                       (new_values['contact']['id'],))
2379
        row = cursor.fetchone()
2380
        if row is None:
2381
            cursor.close()
2382
            cnx.close()
2383
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2384
                                   description='API.CONTACT_NOT_FOUND')
2385
2386
        cursor.execute(" SELECT name "
2387
                       " FROM tbl_cost_centers "
2388
                       " WHERE id = %s ",
2389
                       (new_values['cost_center']['id'],))
2390
        row = cursor.fetchone()
2391
        if row is None:
2392
            cursor.close()
2393
            cnx.close()
2394
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2395
                                   description='API.COST_CENTER_NOT_FOUND')
2396
2397
        add_values = (" INSERT INTO tbl_tenants "
2398
                      "    (name, uuid, buildings, floors, rooms, area, tenant_type_id, "
2399
                      "     is_input_counted, is_key_tenant, "
2400
                      "     lease_number, lease_start_datetime_utc, lease_end_datetime_utc, is_in_lease, "
2401
                      "     contact_id, cost_center_id, description) "
2402
                      " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
2403
        cursor.execute(add_values, (name,
2404
                                    str(uuid.uuid4()),
2405
                                    buildings,
2406
                                    floors,
2407
                                    rooms,
2408
                                    area,
2409
                                    tenant_type_id,
2410
                                    is_input_counted,
2411
                                    is_key_tenant,
2412
                                    lease_number,
2413
                                    lease_start_datetime_utc,
2414
                                    lease_end_datetime_utc,
2415
                                    is_in_lease,
2416
                                    contact_id,
2417
                                    cost_center_id,
2418
                                    description))
2419
        new_id = cursor.lastrowid
2420
        if new_values['commands'] is not None and len(new_values['commands']) > 0:
2421
            for command in new_values['commands']:
2422
                cursor.execute(" SELECT name "
2423
                               " FROM tbl_commands "
2424
                               " WHERE id = %s ", (command['id'],))
2425
                if cursor.fetchone() is None:
2426
                    cursor.close()
2427
                    cnx.close()
2428
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2429
                                           description='API.COMMAND_NOT_FOUND')
2430
2431
                query = (" SELECT id "
2432
                         " FROM tbl_tenants_commands "
2433
                         " WHERE tenant_id = %s AND command_id = %s")
2434
                cursor.execute(query, (new_id, command['id'],))
2435
                if cursor.fetchone() is not None:
2436
                    cursor.close()
2437
                    cnx.close()
2438
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2439
                                           description='API.TENANT_COMMAND_RELATION_EXISTS')
2440
2441
                add_row = (" INSERT INTO tbl_tenants_commands (tenant_id, command_id) "
2442
                           " VALUES (%s, %s) ")
2443
                cursor.execute(add_row, (new_id, command['id'],))
2444
        if new_values['meters'] is not None and len(new_values['meters']) > 0:
2445
            for meter in new_values['meters']:
2446
                cursor.execute(" SELECT name "
2447
                               " FROM tbl_meters "
2448
                               " WHERE id = %s ", (meter['id'],))
2449
                if cursor.fetchone() is None:
2450
                    cursor.close()
2451
                    cnx.close()
2452
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2453
                                           description='API.METER_NOT_FOUND')
2454
2455
                query = (" SELECT id "
2456
                         " FROM tbl_tenants_meters "
2457
                         " WHERE tenant_id = %s AND meter_id = %s")
2458
                cursor.execute(query, (new_id, meter['id'],))
2459
                if cursor.fetchone() is not None:
2460
                    cursor.close()
2461
                    cnx.close()
2462
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2463
                                           description='API.TENANT_METER_RELATION_EXISTS')
2464
2465
                add_row = (" INSERT INTO tbl_tenants_meters (tenant_id, meter_id) "
2466
                           " VALUES (%s, %s) ")
2467
                cursor.execute(add_row, (new_id, meter['id'],))
2468
        if new_values['offline_meters'] is not None and len(new_values['offline_meters']) > 0:
2469
            for offline_meter in new_values['offline_meters']:
2470
                cursor.execute(" SELECT name "
2471
                               " FROM tbl_offline_meters "
2472
                               " WHERE id = %s ", (offline_meter['id'],))
2473
                if cursor.fetchone() is None:
2474
                    cursor.close()
2475
                    cnx.close()
2476
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2477
                                           description='API.OFFLINE_METER_NOT_FOUND')
2478
2479
                query = (" SELECT id "
2480
                         " FROM tbl_tenants_offline_meters "
2481
                         " WHERE tenant_id = %s AND offline_meter_id = %s")
2482
                cursor.execute(query, (new_id, offline_meter['id'],))
2483
                if cursor.fetchone() is not None:
2484
                    cursor.close()
2485
                    cnx.close()
2486
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2487
                                           description='API.TENANT_OFFLINE_METER_RELATION_EXISTS')
2488
2489
                add_row = (" INSERT INTO tbl_tenants_offline_meters (tenant_id, offline_meter_id) "
2490
                           " VALUES (%s, %s) ")
2491
                cursor.execute(add_row, (new_id, offline_meter['id'],))
2492
        if new_values['virtual_meters'] is not None and len(new_values['virtual_meters']) > 0:
2493
            for virtual_meter in new_values['virtual_meters']:
2494
                cursor.execute(" SELECT name "
2495
                               " FROM tbl_virtual_meters "
2496
                               " WHERE id = %s ", (virtual_meter['id'],))
2497
                if cursor.fetchone() is None:
2498
                    cursor.close()
2499
                    cnx.close()
2500
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2501
                                           description='API.VIRTUAL_METER_NOT_FOUND')
2502
2503
                query = (" SELECT id "
2504
                         " FROM tbl_tenants_virtual_meters "
2505
                         " WHERE tenant_id = %s AND virtual_meter_id = %s")
2506
                cursor.execute(query, (new_id, virtual_meter['id'],))
2507
                if cursor.fetchone() is not None:
2508
                    cursor.close()
2509
                    cnx.close()
2510
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2511
                                           description='API.TENANT_VIRTUAL_METER_RELATION_EXISTS')
2512
2513
                add_row = (" INSERT INTO tbl_tenants_virtual_meters (tenant_id, virtual_meter_id) "
2514
                           " VALUES (%s, %s) ")
2515
                cursor.execute(add_row, (new_id, virtual_meter['id'],))
2516
        if new_values['points'] is not None and len(new_values['points']) > 0:
2517
            for point in new_values['points']:
2518
                cursor.execute(" SELECT name "
2519
                               " FROM tbl_points "
2520
                               " WHERE id = %s ", (point['id'],))
2521
                if cursor.fetchone() is None:
2522
                    cursor.close()
2523
                    cnx.close()
2524
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2525
                                           description='API.POINT_NOT_FOUND')
2526
2527
                query = (" SELECT id "
2528
                         " FROM tbl_tenants_points "
2529
                         " WHERE tenant_id = %s AND point_id = %s")
2530
                cursor.execute(query, (new_id, point['id'],))
2531
                if cursor.fetchone() is not None:
2532
                    cursor.close()
2533
                    cnx.close()
2534
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2535
                                           description='API.TENANT_POINT_RELATION_EXISTS')
2536
2537
                add_row = (" INSERT INTO tbl_tenants_points (tenant_id, point_id) "
2538
                           " VALUES (%s, %s) ")
2539
                cursor.execute(add_row, (new_id, point['id'],))
2540
        if new_values['sensors'] is not None and len(new_values['sensors']) > 0:
2541
            for sensor in new_values['sensors']:
2542
                cursor.execute(" SELECT name "
2543
                               " FROM tbl_sensors "
2544
                               " WHERE id = %s ", (sensor['id'],))
2545
                if cursor.fetchone() is None:
2546
                    cursor.close()
2547
                    cnx.close()
2548
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2549
                                           description='API.SENSOR_NOT_FOUND')
2550
2551
                query = (" SELECT id "
2552
                         " FROM tbl_tenants_sensors "
2553
                         " WHERE tenant_id = %s AND sensor_id = %s")
2554
                cursor.execute(query, (new_id, sensor['id'],))
2555
                if cursor.fetchone() is not None:
2556
                    cursor.close()
2557
                    cnx.close()
2558
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2559
                                           description='API.TENANT_SENSOR_RELATION_EXISTS')
2560
2561
                add_row = (" INSERT INTO tbl_tenants_sensors (tenant_id, sensor_id) "
2562
                           " VALUES (%s, %s) ")
2563
                cursor.execute(add_row, (new_id, sensor['id'],))
2564
        if new_values['working_calendars'] is not None and len(new_values['working_calendars']) > 0:
2565
            for working_calendar in new_values['working_calendars']:
2566
                cursor.execute(" SELECT name "
2567
                               " FROM tbl_working_calendars "
2568
                               " WHERE id = %s ", (working_calendar['id'],))
2569
                if cursor.fetchone() is None:
2570
                    cursor.close()
2571
                    cnx.close()
2572
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2573
                                           description='API.WORKING_CALENDAR_NOT_FOUND')
2574
2575
                query = (" SELECT id "
2576
                         " FROM tbl_tenants_working_calendars "
2577
                         " WHERE tenant_id = %s AND working_calendar_id = %s")
2578
                cursor.execute(query, (new_id, working_calendar['id'],))
2579
                if cursor.fetchone() is not None:
2580
                    cursor.close()
2581
                    cnx.close()
2582
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2583
                                           description='API.TENANT_WORKING_CALENDAR_RELATION_EXISTS')
2584
2585
                add_row = (" INSERT INTO tbl_tenants_working_calendars (tenant_id, working_calendar_id) "
2586
                           " VALUES (%s, %s) ")
2587
                cursor.execute(add_row, (new_id, working_calendar['id'],))
2588
        cnx.commit()
2589
        cursor.close()
2590
        cnx.close()
2591
2592
        resp.status = falcon.HTTP_201
2593
        resp.location = '/tenants/' + str(new_id)
2594
2595
2596
class TenantClone:
2597
    def __init__(self):
2598
        """"Initializes TenantClone"""
2599
        pass
2600
2601
    @staticmethod
2602
    def on_options(req, resp, id_):
2603
        resp.status = falcon.HTTP_200
2604
2605
    @staticmethod
2606
    @user_logger
2607
    def on_post(req, resp, id_):
2608
        if 'API-KEY' not in req.headers or \
2609
                not isinstance(req.headers['API-KEY'], str) or \
2610
                len(str.strip(req.headers['API-KEY'])) == 0:
2611
            access_control(req)
2612
        else:
2613
            api_key_control(req)
2614
        if not id_.isdigit() or int(id_) <= 0:
2615
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
2616
                                   description='API.INVALID_TENANT_ID')
2617
2618
        cnx = mysql.connector.connect(**config.myems_system_db)
2619
        cursor = cnx.cursor()
2620
2621
        query = (" SELECT id, name, uuid "
2622
                 " FROM tbl_tenant_types ")
2623
        cursor.execute(query)
2624
        rows_tenant_types = cursor.fetchall()
2625
2626
        tenant_type_dict = dict()
2627
        if rows_tenant_types is not None and len(rows_tenant_types) > 0:
2628
            for row in rows_tenant_types:
2629
                tenant_type_dict[row[0]] = {"id": row[0],
2630
                                            "name": row[1],
2631
                                            "uuid": row[2]}
2632
2633
        query = (" SELECT id, name, uuid "
2634
                 " FROM tbl_contacts ")
2635
        cursor.execute(query)
2636
        rows_contacts = cursor.fetchall()
2637
2638
        contact_dict = dict()
2639
        if rows_contacts is not None and len(rows_contacts) > 0:
2640
            for row in rows_contacts:
2641
                contact_dict[row[0]] = {"id": row[0],
2642
                                        "name": row[1],
2643
                                        "uuid": row[2]}
2644
2645
        query = (" SELECT id, name, uuid "
2646
                 " FROM tbl_cost_centers ")
2647
        cursor.execute(query)
2648
        rows_cost_centers = cursor.fetchall()
2649
2650
        cost_center_dict = dict()
2651
        if rows_cost_centers is not None and len(rows_cost_centers) > 0:
2652
            for row in rows_cost_centers:
2653
                cost_center_dict[row[0]] = {"id": row[0],
2654
                                            "name": row[1],
2655
                                            "uuid": row[2]}
2656
2657
        query = (" SELECT id, name, uuid, "
2658
                 "        buildings, floors, rooms, area, tenant_type_id,"
2659
                 "        is_key_tenant, is_input_counted, "
2660
                 "        lease_number, lease_start_datetime_utc, lease_end_datetime_utc, is_in_lease, "
2661
                 "        contact_id, cost_center_id, description "
2662
                 " FROM tbl_tenants "
2663
                 " WHERE id = %s ")
2664
        cursor.execute(query, (id_,))
2665
        row = cursor.fetchone()
2666
2667
        if row is None:
2668
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2669
                                   description='API.TENANT_NOT_FOUND')
2670
        else:
2671
            timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
2672
            if config.utc_offset[0] == '-':
2673
                timezone_offset = -timezone_offset
2674
2675
            meta_result = {"id": row[0],
2676
                           "name": row[1],
2677
                           "uuid": row[2],
2678
                           "buildings": row[3],
2679
                           "floors": row[4],
2680
                           "rooms": row[5],
2681
                           "area": row[6],
2682
                           "tenant_type": tenant_type_dict.get(row[7], None),
2683
                           "is_key_tenant": bool(row[8]),
2684
                           "is_input_counted": bool(row[9]),
2685
                           "lease_number": row[10],
2686
                           "lease_start_datetime": (row[11].replace(tzinfo=timezone.utc) +
2687
                                                    timedelta(minutes=timezone_offset)).isoformat()[0:19],
2688
                           "lease_end_datetime": (row[12].replace(tzinfo=timezone.utc) +
2689
                                                  timedelta(minutes=timezone_offset)).isoformat()[0:19],
2690
                           "is_in_lease": bool(row[13]),
2691
                           "contact": contact_dict.get(row[14], None),
2692
                           "cost_center": cost_center_dict.get(row[15], None),
2693
                           "description": row[16],
2694
                           "commands": None,
2695
                           "meters": None,
2696
                           "offline_meters": None,
2697
                           "virtual_meters": None,
2698
                           "points": None,
2699
                           "sensors": None,
2700
                           "working_calendars": None
2701
                           }
2702
            query = (" SELECT c.id, c.name, c.uuid "
2703
                     " FROM tbl_tenants t, tbl_tenants_commands tc, tbl_commands c "
2704
                     " WHERE tc.tenant_id = t.id AND c.id = tc.command_id AND t.id = %s "
2705
                     " ORDER BY c.id ")
2706
            cursor.execute(query, (id_,))
2707
            rows = cursor.fetchall()
2708
2709
            command_result = list()
2710
            if rows is not None and len(rows) > 0:
2711
                for row in rows:
2712
                    result = {"id": row[0], "name": row[1], "uuid": row[2]}
2713
                    command_result.append(result)
2714
                meta_result['commands'] = command_result
2715
            query = (" SELECT id, name, uuid "
2716
                     " FROM tbl_energy_categories ")
2717
            cursor.execute(query)
2718
            rows_energy_categories = cursor.fetchall()
2719
2720
            energy_category_dict = dict()
2721
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2722
                for row in rows_energy_categories:
2723
                    energy_category_dict[row[0]] = {"id": row[0],
2724
                                                    "name": row[1],
2725
                                                    "uuid": row[2]}
2726
2727
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id "
2728
                     " FROM tbl_tenants t, tbl_tenants_meters tm, tbl_meters m "
2729
                     " WHERE tm.tenant_id = t.id AND m.id = tm.meter_id AND t.id = %s "
2730
                     " ORDER BY m.id ")
2731
            cursor.execute(query, (id_,))
2732
            rows = cursor.fetchall()
2733
2734
            meter_result = list()
2735
            if rows is not None and len(rows) > 0:
2736
                for row in rows:
2737
                    energy_category = energy_category_dict.get(row[3], None)
2738
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
2739
                              "energy_category": energy_category}
2740
                    meter_result.append(result)
2741
                meta_result['meters'] = meter_result
2742
            query = (" SELECT id, name, uuid "
2743
                     " FROM tbl_energy_categories ")
2744
            cursor.execute(query)
2745
            rows_energy_categories = cursor.fetchall()
2746
2747
            energy_category_dict = dict()
2748
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2749
                for row in rows_energy_categories:
2750
                    energy_category_dict[row[0]] = {"id": row[0],
2751
                                                    "name": row[1],
2752
                                                    "uuid": row[2]}
2753
2754
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id "
2755
                     " FROM tbl_tenants s, tbl_tenants_offline_meters sm, tbl_offline_meters m "
2756
                     " WHERE sm.tenant_id = s.id AND m.id = sm.offline_meter_id AND s.id = %s "
2757
                     " ORDER BY m.id ")
2758
            cursor.execute(query, (id_,))
2759
            rows = cursor.fetchall()
2760
2761
            offlinemeter_result = list()
2762
            if rows is not None and len(rows) > 0:
2763
                for row in rows:
2764
                    energy_category = energy_category_dict.get(row[3], None)
2765
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
2766
                              "energy_category": energy_category}
2767
                    offlinemeter_result.append(result)
2768
                meta_result['offline_meters'] = offlinemeter_result
2769
            query = (" SELECT id, name, uuid "
2770
                     " FROM tbl_energy_categories ")
2771
            cursor.execute(query)
2772
            rows_energy_categories = cursor.fetchall()
2773
2774
            energy_category_dict = dict()
2775
            if rows_energy_categories is not None and len(rows_energy_categories) > 0:
2776
                for row in rows_energy_categories:
2777
                    energy_category_dict[row[0]] = {"id": row[0],
2778
                                                    "name": row[1],
2779
                                                    "uuid": row[2]}
2780
2781
            query = (" SELECT m.id, m.name, m.uuid, m.energy_category_id "
2782
                     " FROM tbl_tenants t, tbl_tenants_virtual_meters tm, tbl_virtual_meters m "
2783
                     " WHERE tm.tenant_id = t.id AND m.id = tm.virtual_meter_id AND t.id = %s "
2784
                     " ORDER BY m.id ")
2785
            cursor.execute(query, (id_,))
2786
            rows = cursor.fetchall()
2787
2788
            virtualmeter_result = list()
2789
            if rows is not None and len(rows) > 0:
2790
                for row in rows:
2791
                    energy_category = energy_category_dict.get(row[3], None)
2792
                    result = {"id": row[0], "name": row[1], "uuid": row[2],
2793
                              "energy_category": energy_category}
2794
                    virtualmeter_result.append(result)
2795
                meta_result['virtual_meters'] = virtualmeter_result
2796
            query = (" SELECT id, name, uuid "
2797
                     " FROM tbl_data_sources ")
2798
            cursor.execute(query)
2799
            rows_data_sources = cursor.fetchall()
2800
2801
            data_source_dict = dict()
2802
            if rows_data_sources is not None and len(rows_data_sources) > 0:
2803
                for row in rows_data_sources:
2804
                    data_source_dict[row[0]] = {"id": row[0],
2805
                                                "name": row[1],
2806
                                                "uuid": row[2]}
2807
2808
            query = (" SELECT p.id, p.name, p.data_source_id "
2809
                     " FROM tbl_tenants t, tbl_tenants_points tp, tbl_points p "
2810
                     " WHERE tp.tenant_id = t.id AND p.id = tp.point_id AND t.id = %s "
2811
                     " ORDER BY p.id ")
2812
            cursor.execute(query, (id_,))
2813
            rows = cursor.fetchall()
2814
2815
            point_result = list()
2816
            if rows is not None and len(rows) > 0:
2817
                for row in rows:
2818
                    data_source = data_source_dict.get(row[2], None)
2819
                    result = {"id": row[0], "name": row[1], "data_source": data_source}
2820
                    point_result.append(result)
2821
                meta_result['points'] = point_result
2822
            query = (" SELECT s.id, s.name, s.uuid "
2823
                     " FROM tbl_tenants t, tbl_tenants_sensors ts, tbl_sensors s "
2824
                     " WHERE ts.tenant_id = t.id AND s.id = ts.sensor_id AND t.id = %s "
2825
                     " ORDER BY s.id ")
2826
            cursor.execute(query, (id_,))
2827
            rows = cursor.fetchall()
2828
2829
            sensor_result = list()
2830
            if rows is not None and len(rows) > 0:
2831
                for row in rows:
2832
                    result = {"id": row[0], "name": row[1], "uuid": row[2]}
2833
                    sensor_result.append(result)
2834
                meta_result['sensors'] = sensor_result
2835
            query = (" SELECT wc.id, wc.name, wc.description "
2836
                     " FROM tbl_tenants t, tbl_tenants_working_calendars twc, tbl_working_calendars wc "
2837
                     " WHERE twc.tenant_id = t.id AND wc.id = twc.working_calendar_id AND t.id = %s "
2838
                     " ORDER BY wc.id ")
2839
            cursor.execute(query, (id_,))
2840
            rows = cursor.fetchall()
2841
2842
            workingcalendars_result = list()
2843
            if rows is not None and len(rows) > 0:
2844
                for row in rows:
2845
                    result = {"id": row[0], "name": row[1], "description": row[2]}
2846
                    workingcalendars_result.append(result)
2847
                meta_result['working_calendars'] = workingcalendars_result
2848
            timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
2849
            if config.utc_offset[0] == '-':
2850
                timezone_offset = -timezone_offset
2851
            new_name = (str.strip(meta_result['name']) +
2852
                        (datetime.utcnow() + timedelta(minutes=timezone_offset)).isoformat(sep='-', timespec='seconds'))
2853
            add_values = (" INSERT INTO tbl_tenants "
2854
                          "    (name, uuid, buildings, floors, rooms, area, tenant_type_id, "
2855
                          "     is_input_counted, is_key_tenant, "
2856
                          "     lease_number, lease_start_datetime_utc, lease_end_datetime_utc, is_in_lease, "
2857
                          "     contact_id, cost_center_id, description) "
2858
                          " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
2859
            cursor.execute(add_values, (new_name,
2860
                                        str(uuid.uuid4()),
2861
                                        meta_result['buildings'],
2862
                                        meta_result['floors'],
2863
                                        meta_result['rooms'],
2864
                                        meta_result['area'],
2865
                                        meta_result['tenant_type']['id'],
2866
                                        meta_result['is_input_counted'],
2867
                                        meta_result['is_key_tenant'],
2868
                                        meta_result['lease_number'],
2869
                                        meta_result['lease_start_datetime'],
2870
                                        meta_result['lease_end_datetime'],
2871
                                        meta_result['is_in_lease'],
2872
                                        meta_result['contact']['id'],
2873
                                        meta_result['cost_center']['id'],
2874
                                        meta_result['description']))
2875
            new_id = cursor.lastrowid
2876
            if meta_result['commands'] is not None and len(meta_result['commands']) > 0:
2877
                for command in meta_result['commands']:
2878
                    cursor.execute(" SELECT name "
2879
                                   " FROM tbl_commands "
2880
                                   " WHERE id = %s ", (command['id'],))
2881
                    if cursor.fetchone() is None:
2882
                        cursor.close()
2883
                        cnx.close()
2884
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2885
                                               description='API.COMMAND_NOT_FOUND')
2886
2887
                    query = (" SELECT id "
2888
                             " FROM tbl_tenants_commands "
2889
                             " WHERE tenant_id = %s AND command_id = %s")
2890
                    cursor.execute(query, (new_id, command['id'],))
2891
                    if cursor.fetchone() is not None:
2892
                        cursor.close()
2893
                        cnx.close()
2894
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2895
                                               description='API.TENANT_COMMAND_RELATION_EXISTS')
2896
2897
                    add_row = (" INSERT INTO tbl_tenants_commands (tenant_id, command_id) "
2898
                               " VALUES (%s, %s) ")
2899
                    cursor.execute(add_row, (new_id, command['id'],))
2900
            if meta_result['meters'] is not None and len(meta_result['meters']) > 0:
2901
                for meter in meta_result['meters']:
2902
                    cursor.execute(" SELECT name "
2903
                                   " FROM tbl_meters "
2904
                                   " WHERE id = %s ", (meter['id'],))
2905
                    if cursor.fetchone() is None:
2906
                        cursor.close()
2907
                        cnx.close()
2908
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2909
                                               description='API.METER_NOT_FOUND')
2910
2911
                    query = (" SELECT id "
2912
                             " FROM tbl_tenants_meters "
2913
                             " WHERE tenant_id = %s AND meter_id = %s")
2914
                    cursor.execute(query, (new_id, meter['id'],))
2915
                    if cursor.fetchone() is not None:
2916
                        cursor.close()
2917
                        cnx.close()
2918
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2919
                                               description='API.TENANT_METER_RELATION_EXISTS')
2920
2921
                    add_row = (" INSERT INTO tbl_tenants_meters (tenant_id, meter_id) "
2922
                               " VALUES (%s, %s) ")
2923
                    cursor.execute(add_row, (new_id, meter['id'],))
2924
            if meta_result['offline_meters'] is not None and len(meta_result['offline_meters']) > 0:
2925
                for offline_meter in meta_result['offline_meters']:
2926
                    cursor.execute(" SELECT name "
2927
                                   " FROM tbl_offline_meters "
2928
                                   " WHERE id = %s ", (offline_meter['id'],))
2929
                    if cursor.fetchone() is None:
2930
                        cursor.close()
2931
                        cnx.close()
2932
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2933
                                               description='API.OFFLINE_METER_NOT_FOUND')
2934
2935
                    query = (" SELECT id "
2936
                             " FROM tbl_tenants_offline_meters "
2937
                             " WHERE tenant_id = %s AND offline_meter_id = %s")
2938
                    cursor.execute(query, (new_id, offline_meter['id'],))
2939
                    if cursor.fetchone() is not None:
2940
                        cursor.close()
2941
                        cnx.close()
2942
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2943
                                               description='API.TENANT_OFFLINE_METER_RELATION_EXISTS')
2944
2945
                    add_row = (" INSERT INTO tbl_tenants_offline_meters (tenant_id, offline_meter_id) "
2946
                               " VALUES (%s, %s) ")
2947
                    cursor.execute(add_row, (new_id, offline_meter['id'],))
2948
            if meta_result['virtual_meters'] is not None and len(meta_result['virtual_meters']) > 0:
2949
                for virtual_meter in meta_result['virtual_meters']:
2950
                    cursor.execute(" SELECT name "
2951
                                   " FROM tbl_virtual_meters "
2952
                                   " WHERE id = %s ", (virtual_meter['id'],))
2953
                    if cursor.fetchone() is None:
2954
                        cursor.close()
2955
                        cnx.close()
2956
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2957
                                               description='API.VIRTUAL_METER_NOT_FOUND')
2958
2959
                    query = (" SELECT id "
2960
                             " FROM tbl_tenants_virtual_meters "
2961
                             " WHERE tenant_id = %s AND virtual_meter_id = %s")
2962
                    cursor.execute(query, (new_id, virtual_meter['id'],))
2963
                    if cursor.fetchone() is not None:
2964
                        cursor.close()
2965
                        cnx.close()
2966
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2967
                                               description='API.TENANT_VIRTUAL_METER_RELATION_EXISTS')
2968
2969
                    add_row = (" INSERT INTO tbl_tenants_virtual_meters (tenant_id, virtual_meter_id) "
2970
                               " VALUES (%s, %s) ")
2971
                    cursor.execute(add_row, (new_id, virtual_meter['id'],))
2972
            if meta_result['points'] is not None and len(meta_result['points']) > 0:
2973
                for point in meta_result['points']:
2974
                    cursor.execute(" SELECT name "
2975
                                   " FROM tbl_points "
2976
                                   " WHERE id = %s ", (point['id'],))
2977
                    if cursor.fetchone() is None:
2978
                        cursor.close()
2979
                        cnx.close()
2980
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
2981
                                               description='API.POINT_NOT_FOUND')
2982
2983
                    query = (" SELECT id "
2984
                             " FROM tbl_tenants_points "
2985
                             " WHERE tenant_id = %s AND point_id = %s")
2986
                    cursor.execute(query, (new_id, point['id'],))
2987
                    if cursor.fetchone() is not None:
2988
                        cursor.close()
2989
                        cnx.close()
2990
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
2991
                                               description='API.TENANT_POINT_RELATION_EXISTS')
2992
2993
                    add_row = (" INSERT INTO tbl_tenants_points (tenant_id, point_id) "
2994
                               " VALUES (%s, %s) ")
2995
                    cursor.execute(add_row, (new_id, point['id'],))
2996
            if meta_result['sensors'] is not None and len(meta_result['sensors']) > 0:
2997
                for sensor in meta_result['sensors']:
2998
                    cursor.execute(" SELECT name "
2999
                                   " FROM tbl_sensors "
3000
                                   " WHERE id = %s ", (sensor['id'],))
3001
                    if cursor.fetchone() is None:
3002
                        cursor.close()
3003
                        cnx.close()
3004
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3005
                                               description='API.SENSOR_NOT_FOUND')
3006
3007
                    query = (" SELECT id "
3008
                             " FROM tbl_tenants_sensors "
3009
                             " WHERE tenant_id = %s AND sensor_id = %s")
3010
                    cursor.execute(query, (new_id, sensor['id'],))
3011
                    if cursor.fetchone() is not None:
3012
                        cursor.close()
3013
                        cnx.close()
3014
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3015
                                               description='API.TENANT_SENSOR_RELATION_EXISTS')
3016
3017
                    add_row = (" INSERT INTO tbl_tenants_sensors (tenant_id, sensor_id) "
3018
                               " VALUES (%s, %s) ")
3019
                    cursor.execute(add_row, (new_id, sensor['id'],))
3020
            if meta_result['working_calendars'] is not None and len(meta_result['working_calendars']) > 0:
3021
                for working_calendar in meta_result['working_calendars']:
3022
                    cursor.execute(" SELECT name "
3023
                                   " FROM tbl_working_calendars "
3024
                                   " WHERE id = %s ", (working_calendar['id'],))
3025
                    if cursor.fetchone() is None:
3026
                        cursor.close()
3027
                        cnx.close()
3028
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
3029
                                               description='API.WORKING_CALENDAR_NOT_FOUND')
3030
3031
                    query = (" SELECT id "
3032
                             " FROM tbl_tenants_working_calendars "
3033
                             " WHERE tenant_id = %s AND working_calendar_id = %s")
3034
                    cursor.execute(query, (new_id, working_calendar['id'],))
3035
                    if cursor.fetchone() is not None:
3036
                        cursor.close()
3037
                        cnx.close()
3038
                        raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
3039
                                               description='API.TENANT_WORKING_CALENDAR_RELATION_EXISTS')
3040
3041
                    add_row = (" INSERT INTO tbl_tenants_working_calendars (tenant_id, working_calendar_id) "
3042
                               " VALUES (%s, %s) ")
3043
                    cursor.execute(add_row, (new_id, working_calendar['id'],))
3044
            cnx.commit()
3045
            cursor.close()
3046
            cnx.close()
3047
3048
            resp.status = falcon.HTTP_201
3049
            resp.location = '/tenants/' + str(new_id)
3050