core.store.StoreWorkingCalendarItem.on_options()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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