Passed
Push — master ( cb176a...4b8481 )
by
unknown
13:30
created

NonWorkingDayCollection.on_options()   A

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 3
1
import falcon
2
from datetime import datetime, timedelta
3
import mysql.connector
4
import simplejson as json
5
from core.useractivity import admin_control, access_control, api_key_control
6
import config
7
8
9
class WorkingCalendarCollection:
10
    """
11
    Working Calendar Collection Resource
12
13
    This class handles CRUD operations for working calendar collection.
14
    It provides endpoints for listing all working calendars and creating new calendars.
15
    Working calendars define business days and holidays for the energy management system.
16
    """
17
    def __init__(self):
18
        """Initialize WorkingCalendarCollection"""
19
        pass
20
21
    @staticmethod
22
    def on_options(req, resp):
23
        """Handle OPTIONS requests for CORS preflight"""
24
        _ = req
25
        resp.status = falcon.HTTP_200
26
27
    @staticmethod
28
    def on_get(req, resp):
29
        if 'API-KEY' not in req.headers or \
30
                not isinstance(req.headers['API-KEY'], str) or \
31
                len(str.strip(req.headers['API-KEY'])) == 0:
32
            access_control(req)
33
        else:
34
            api_key_control(req)
35
        cnx = mysql.connector.connect(**config.myems_system_db)
36
        cursor = cnx.cursor()
37
38
        cursor.execute(" SELECT id, name, description"
39
                       " FROM tbl_working_calendars ")
40
41
        rows_calendars = cursor.fetchall()
42
43
        result = list()
44
        if rows_calendars is not None and len(rows_calendars) > 0:
45
            for row in rows_calendars:
46
                meta_result = {"id": row[0],
47
                               "name": row[1],
48
                               "description": row[2]}
49
                result.append(meta_result)
50
51
        cursor.close()
52
        cnx.close()
53
        resp.text = json.dumps(result)
54
55
    @staticmethod
56
    def on_post(req, resp):
57
        """Handles POST requests"""
58
        admin_control(req)
59
        try:
60
            raw_json = req.stream.read().decode('utf-8')
61
            new_values = json.loads(raw_json)
62
        except UnicodeDecodeError as ex:
63
            print("Failed to decode request")
64
            raise falcon.HTTPError(status=falcon.HTTP_400,
65
                                   title='API.BAD_REQUEST',
66
                                   description='API.INVALID_ENCODING')
67
        except json.JSONDecodeError as ex:
68
            print("Failed to parse JSON")
69
            raise falcon.HTTPError(status=falcon.HTTP_400,
70
                                   title='API.BAD_REQUEST',
71
                                   description='API.INVALID_JSON_FORMAT')
72
        except Exception as ex:
73
            print("Unexpected error reading request stream")
74
            raise falcon.HTTPError(status=falcon.HTTP_400,
75
                                   title='API.BAD_REQUEST',
76
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
77
78
        if 'name' not in new_values['data'].keys() or \
79
                not isinstance(new_values['data']['name'], str) or \
80
                len(str.strip(new_values['data']['name'])) == 0:
81
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
82
                                   description='API.INVALID_WORKING_CALENDAR_NAME')
83
        name = str.strip(new_values['data']['name'])
84
85
        if 'description' in new_values['data'].keys() and \
86
                new_values['data']['description'] is not None and \
87
                len(str(new_values['data']['description'])) > 0:
88
            description = str.strip(new_values['data']['description'])
89
        else:
90
            description = None
91
92
        cnx = mysql.connector.connect(**config.myems_system_db)
93
        cursor = cnx.cursor()
94
95
        cursor.execute(" SELECT name "
96
                       " FROM tbl_working_calendars "
97
                       " WHERE name = %s ", (name,))
98
        if cursor.fetchone() is not None:
99
            cursor.close()
100
            cnx.close()
101
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
102
                                   description='API.WORKING_CALENDAR_NAME_IS_ALREADY_IN_USE')
103
104
        add_values = (" INSERT INTO tbl_working_calendars "
105
                      " (name, description) "
106
                      " VALUES (%s, %s) ")
107
        cursor.execute(add_values, (name,
108
                                    description))
109
        new_id = cursor.lastrowid
110
        cnx.commit()
111
        cursor.close()
112
        cnx.close()
113
114
        resp.status = falcon.HTTP_201
115
        resp.location = '/workingcalendar/' + str(new_id)
116
117
118
class WorkingCalendarItem:
119
    def __init__(self):
120
        pass
121
122
    @staticmethod
123
    def on_options(req, resp, id_):
124
        _ = req
125
        resp.status = falcon.HTTP_200
126
        _ = id_
127
128 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
129
    def on_get(req, resp, id_):
130
        if 'API-KEY' not in req.headers or \
131
                not isinstance(req.headers['API-KEY'], str) or \
132
                len(str.strip(req.headers['API-KEY'])) == 0:
133
            access_control(req)
134
        else:
135
            api_key_control(req)
136
        if not id_.isdigit() or int(id_) <= 0:
137
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
138
                                   description='API.INVALID_WORKING_CALENDAR_ID')
139
140
        cnx = mysql.connector.connect(**config.myems_system_db)
141
        cursor = cnx.cursor()
142
143
        cursor.execute(" SELECT id, name, description"
144
                       " FROM tbl_working_calendars "
145
                       " WHERE id = %s ", (id_,))
146
        row = cursor.fetchone()
147
        cursor.close()
148
        cnx.close()
149
150
        if row is None:
151
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
152
                                   description='API.WORKING_CALENDAR_NOT_FOUND')
153
154
        meta_result = {"id": row[0],
155
                       "name": row[1],
156
                       "description": row[2]}
157
        resp.text = json.dumps(meta_result)
158
159
    @staticmethod
160
    def on_delete(req, resp, id_):
161
        admin_control(req)
162
        if not id_.isdigit() or int(id_) <= 0:
163
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
164
                                   description='API.INVALID_WORKING_CALENDAR_ID')
165
166
        cnx = mysql.connector.connect(**config.myems_system_db)
167
        cursor = cnx.cursor()
168
169
        cursor.execute(" SELECT id "
170
                       " FROM tbl_working_calendars "
171
                       " WHERE id = %s ", (id_,))
172
        if cursor.fetchone() is None:
173
            cursor.close()
174
            cnx.close()
175
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
176
                                   description='API.WORKING_CALENDAR_NOT_FOUND')
177
178
        # check relation with space
179
        cursor.execute(" SELECT id FROM tbl_spaces_working_calendars"
180
                       " WHERE working_calendar_id = %s ", (id_,))
181
182
        rows_non_working_days = cursor.fetchall()
183
        if rows_non_working_days is not None and len(rows_non_working_days) > 0:
184
            cursor.close()
185
            cnx.close()
186
            raise falcon.HTTPError(status=falcon.HTTP_400,
187
                                   title='API.BAD_REQUEST',
188
                                   description='API.THERE_IS_RELATION_WITH_SPACES')
189
190
        # check relation with tenants
191
        cursor.execute(" SELECT tenant_id "
192
                       " FROM tbl_tenants_working_calendars "
193
                       " WHERE working_calendar_id = %s ", (id_,))
194
        rows_tenants = cursor.fetchall()
195
        if rows_tenants is not None and len(rows_tenants) > 0:
196
            cursor.close()
197
            cnx.close()
198
            raise falcon.HTTPError(status=falcon.HTTP_400,
199
                                   title='API.BAD_REQUEST',
200
                                   description='API.THERE_IS_RELATION_WITH_TENANTS')
201
202
        # check relation with stores
203
        cursor.execute(" SELECT store_id "
204
                       " FROM tbl_stores_working_calendars "
205
                       " WHERE working_calendar_id = %s ", (id_,))
206
        rows_stores = cursor.fetchall()
207
        if rows_stores is not None and len(rows_stores) > 0:
208
            cursor.close()
209
            cnx.close()
210
            raise falcon.HTTPError(status=falcon.HTTP_400,
211
                                   title='API.BAD_REQUEST',
212
                                   description='API.THERE_IS_RELATION_WITH_STORES')
213
214
        # check relation with shopfloors
215
        cursor.execute(" SELECT shopfloor_id "
216
                       " FROM tbl_shopfloors_working_calendars "
217
                       " WHERE working_calendar_id = %s ", (id_,))
218
        rows_shopfloors = cursor.fetchall()
219
        if rows_shopfloors is not None and len(rows_shopfloors) > 0:
220
            cursor.close()
221
            cnx.close()
222
            raise falcon.HTTPError(status=falcon.HTTP_400,
223
                                   title='API.BAD_REQUEST',
224
                                   description='API.THERE_IS_RELATION_WITH_SHOPFLOORS')
225
226
        cursor.execute(" DELETE FROM tbl_working_calendars_non_working_days "
227
                       " WHERE working_calendar_id = %s ", (id_,))
228
        cnx.commit()
229
230
        cursor.execute(" DELETE FROM tbl_working_calendars WHERE id = %s ", (id_,))
231
        cnx.commit()
232
233
        cursor.close()
234
        cnx.close()
235
236
        resp.status = falcon.HTTP_204
237
238 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
239
    def on_put(req, resp, id_):
240
        """Handles PUT requests"""
241
        admin_control(req)
242
        try:
243
            raw_json = req.stream.read().decode('utf-8')
244
        except UnicodeDecodeError as ex:
245
            print("Failed to decode request")
246
            raise falcon.HTTPError(status=falcon.HTTP_400,
247
                                   title='API.BAD_REQUEST',
248
                                   description='API.INVALID_ENCODING')
249
        except Exception as ex:
250
            print("Unexpected error reading request stream")
251
            raise falcon.HTTPError(status=falcon.HTTP_400,
252
                                   title='API.BAD_REQUEST',
253
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
254
255
        if not id_.isdigit() or int(id_) <= 0:
256
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
257
                                   description='API.INVALID_WORKING_CALENDAR_ID')
258
259
        new_values = json.loads(raw_json)
260
261
        if 'name' not in new_values['data'].keys() or \
262
                not isinstance(new_values['data']['name'], str) or \
263
                len(str.strip(new_values['data']['name'])) == 0:
264
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
265
                                   description='API.INVALID_WORKING_CALENDAR_NAME')
266
        name = str.strip(new_values['data']['name'])
267
268
        if 'description' in new_values['data'].keys() and \
269
                new_values['data']['description'] is not None and \
270
                len(str(new_values['data']['description'])) > 0:
271
            description = str.strip(new_values['data']['description'])
272
        else:
273
            description = None
274
275
        cnx = mysql.connector.connect(**config.myems_system_db)
276
        cursor = cnx.cursor()
277
278
        cursor.execute(" SELECT name "
279
                       " FROM tbl_working_calendars "
280
                       " WHERE id = %s ", (id_,))
281
        if cursor.fetchone() is None:
282
            cursor.close()
283
            cnx.close()
284
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
285
                                   description='API.WORKING_CALENDAR_NOT_FOUND')
286
287
        cursor.execute(" SELECT name "
288
                       " FROM tbl_working_calendars "
289
                       " WHERE name = %s AND id != %s ", (name, id_))
290
        if cursor.fetchone() is not None:
291
            cursor.close()
292
            cnx.close()
293
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
294
                                   description='API.WORKING_CALENDAR_NAME_IS_ALREADY_IN_USE')
295
296
        update_row = (" UPDATE tbl_working_calendars "
297
                      " SET name = %s, description = %s "
298
                      " WHERE id = %s ")
299
        cursor.execute(update_row, (name, description, id_))
300
        cnx.commit()
301
302
        cursor.close()
303
        cnx.close()
304
305
        resp.status = falcon.HTTP_200
306
307
308
class NonWorkingDayCollection:
309
    def __init__(self):
310
        pass
311
312
    @staticmethod
313
    def on_options(req, resp, id_):
314
        _ = req
315
        resp.status = falcon.HTTP_200
316
        _ = id_
317
318 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
319
    def on_get(req, resp, id_):
320
        if 'API-KEY' not in req.headers or \
321
                not isinstance(req.headers['API-KEY'], str) or \
322
                len(str.strip(req.headers['API-KEY'])) == 0:
323
            access_control(req)
324
        else:
325
            api_key_control(req)
326
        if not id_.isdigit() or int(id_) <= 0:
327
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
328
                                   description='API.INVALID_NON_WORKING_DAY_ID')
329
330
        cnx = mysql.connector.connect(**config.myems_system_db)
331
        cursor = cnx.cursor()
332
333
        cursor.execute(" SELECT id, working_calendar_id, date_local, description"
334
                       " FROM tbl_working_calendars_non_working_days "
335
                       " WHERE working_calendar_id = %s "
336
                       " ORDER BY date_local DESC ", (id_,))
337
        rows_date_local = cursor.fetchall()
338
339
        meta_result = list()
340
        if rows_date_local is not None and len(rows_date_local) > 0:
341
            for row in rows_date_local:
342
                date_local_dict = {'id': row[0],
343
                                   'working_calendar_id': row[1],
344
                                   'date_local': row[2].isoformat()[0:10],
345
                                   'description': row[3]}
346
                meta_result.append(date_local_dict)
347
348
        cursor.close()
349
        cnx.close()
350
351
        resp.text = json.dumps(meta_result)
352
353
    @staticmethod
354
    def on_post(req, resp, id_):
355
        """Handles POST requests"""
356
        admin_control(req)
357
        try:
358
            raw_json = req.stream.read().decode('utf-8')
359
            new_values = json.loads(raw_json)
360
        except UnicodeDecodeError as ex:
361
            print("Failed to decode request")
362
            raise falcon.HTTPError(status=falcon.HTTP_400,
363
                                   title='API.BAD_REQUEST',
364
                                   description='API.INVALID_ENCODING')
365
        except json.JSONDecodeError as ex:
366
            print("Failed to parse JSON")
367
            raise falcon.HTTPError(status=falcon.HTTP_400,
368
                                   title='API.BAD_REQUEST',
369
                                   description='API.INVALID_JSON_FORMAT')
370
        except Exception as ex:
371
            print("Unexpected error reading request stream")
372
            raise falcon.HTTPError(status=falcon.HTTP_400,
373
                                   title='API.BAD_REQUEST',
374
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
375
376
        if not id_.isdigit() or int(id_) <= 0:
377
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
378
                                   description='API.INVALID_WORKING_CALENDAR_ID')
379
        working_calendar_id = id_
380
381
        if 'date_local' not in new_values['data'].keys() or \
382
                new_values['data']['date_local'] is None or \
383
                len(str(new_values['data']['date_local'])) <= 0:
384
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
385
                                   description='API.INVALID_DATE_LOCAL')
386
        date_local = str.strip(new_values['data']['date_local'])
387
388
        if 'description' in new_values['data'].keys() and \
389
                new_values['data']['description'] is not None and \
390
                len(str(new_values['data']['description'])) > 0:
391
            description = str.strip(new_values['data']['description'])
392
        else:
393
            description = None
394
395
        cnx = mysql.connector.connect(**config.myems_system_db)
396
        cursor = cnx.cursor()
397
398
        cursor.execute(" SELECT id "
399
                       " FROM tbl_working_calendars_non_working_days "
400
                       " WHERE working_calendar_id = %s AND date_local = %s ",
401
                       (working_calendar_id, date_local))
402
        if cursor.fetchone() is not None:
403
            cursor.close()
404
            cnx.close()
405
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
406
                                   description='API.DATE_IS_ALREADY_IN_WORKING_CALENDAR')
407
408
        add_values = (" INSERT INTO tbl_working_calendars_non_working_days "
409
                      " (working_calendar_id, date_local, description) "
410
                      " VALUES (%s, %s, %s) ")
411
        cursor.execute(add_values, (working_calendar_id, date_local, description))
412
        new_id = cursor.lastrowid
413
        cnx.commit()
414
        cursor.close()
415
        cnx.close()
416
417
        resp.status = falcon.HTTP_201
418
        resp.location = '/nonworkingday/' + str(new_id)
419
420
421
class NonWorkingDayItem:
422
    def __init__(self):
423
        pass
424
425
    @staticmethod
426
    def on_options(req, resp, id_):
427
        _ = req
428
        resp.status = falcon.HTTP_200
429
        _ = id_
430
431
    @staticmethod
432
    def on_get(req, resp, id_):
433
        if 'API-KEY' not in req.headers or \
434
                not isinstance(req.headers['API-KEY'], str) or \
435
                len(str.strip(req.headers['API-KEY'])) == 0:
436
            access_control(req)
437
        else:
438
            api_key_control(req)
439
        if not id_.isdigit() or int(id_) <= 0:
440
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
441
                                   description='API.INVALID_NON_WORKING_DAY_ID')
442
443
        cnx = mysql.connector.connect(**config.myems_system_db)
444
        cursor = cnx.cursor()
445
446
        cursor.execute(" SELECT id, working_calendar_id, date_local, description"
447
                       " FROM tbl_working_calendars_non_working_days "
448
                       " WHERE id = %s ", (id_,))
449
        row = cursor.fetchone()
450
        cursor.close()
451
        cnx.close()
452
453
        if row is None:
454
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
455
                                   description='API.NON_WORKING_DAY_NOT_FOUND')
456
        else:
457
            meta_result = {"id": row[0],
458
                           "working_calendar_id": row[1],
459
                           "date_local": row[2].isoformat()[0:10],
460
                           "description": row[3]}
461
        resp.text = json.dumps(meta_result)
462
463
    @staticmethod
464
    def on_delete(req, resp, id_):
465
        admin_control(req)
466
        if not id_.isdigit() or int(id_) <= 0:
467
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
468
                                   description='API.INVALID_NON_WORKING_DAY_ID')
469
470
        cnx = mysql.connector.connect(**config.myems_system_db)
471
        cursor = cnx.cursor()
472
473
        cursor.execute(" SELECT id "
474
                       " FROM tbl_working_calendars_non_working_days "
475
                       " WHERE id = %s ", (id_,))
476
        if cursor.fetchone() is None:
477
            cursor.close()
478
            cnx.close()
479
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
480
                                   description='API.NON_WORKING_DAY_NOT_FOUND')
481
482
        cursor.execute(" DELETE FROM tbl_working_calendars_non_working_days WHERE id = %s ", (id_,))
483
        cnx.commit()
484
485
        cursor.close()
486
        cnx.close()
487
488
        resp.status = falcon.HTTP_204
489
490
    @staticmethod
491
    def on_put(req, resp, id_):
492
        """Handles PUT requests"""
493
        admin_control(req)
494
        try:
495
            raw_json = req.stream.read().decode('utf-8')
496
        except UnicodeDecodeError as ex:
497
            print("Failed to decode request")
498
            raise falcon.HTTPError(status=falcon.HTTP_400,
499
                                   title='API.BAD_REQUEST',
500
                                   description='API.INVALID_ENCODING')
501
        except Exception as ex:
502
            print("Unexpected error reading request stream")
503
            raise falcon.HTTPError(status=falcon.HTTP_400,
504
                                   title='API.BAD_REQUEST',
505
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
506
507
        if not id_.isdigit() or int(id_) <= 0:
508
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
509
                                   description='API.INVALID_NON_WORKING_DAY_ID')
510
511
        new_values = json.loads(raw_json)
512
513
        if 'date_local' in new_values['data'].keys() and \
514
                new_values['data']['date_local'] is not None and \
515
                len(str(new_values['data']['date_local'])) > 0:
516
            date_local = str.strip(new_values['data']['date_local'])
517
518
        if 'description' in new_values['data'].keys() and \
519
                new_values['data']['description'] is not None and \
520
                len(str(new_values['data']['description'])) > 0:
521
            description = str.strip(new_values['data']['description'])
522
        else:
523
            description = None
524
525
        cnx = mysql.connector.connect(**config.myems_system_db)
526
        cursor = cnx.cursor()
527
528
        cursor.execute(" SELECT date_local "
529
                       " FROM tbl_working_calendars_non_working_days "
530
                       " WHERE id = %s ", (id_,))
531
        if cursor.fetchone() is None:
532
            cursor.close()
533
            cnx.close()
534
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
535
                                   description='API.DATE_LOCAL_NOT_FOUND')
536
537
        cursor.execute(" SELECT id "
538
                       " FROM tbl_working_calendars_non_working_days "
539
                       " WHERE id != %s AND date_local = %s ",
540
                       (id_, date_local))
0 ignored issues
show
introduced by
The variable date_local does not seem to be defined in case 'date_local' in Subscrip...str(SubscriptNode)) > 0 on line 513 is False. Are you sure this can never be the case?
Loading history...
541
        if cursor.fetchone() is not None:
542
            cursor.close()
543
            cnx.close()
544
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
545
                                   description='API.DATE_IS_ALREADY_IN_WORKING_CALENDAR')
546
547
        update_row = (" UPDATE tbl_working_calendars_non_working_days "
548
                      " SET date_local = %s, description = %s "
549
                      " WHERE id = %s ")
550
        cursor.execute(update_row, (date_local, description, id_))
551
        cnx.commit()
552
553
        cursor.close()
554
        cnx.close()
555
556
        resp.status = falcon.HTTP_200
557
558
559 View Code Duplication
class WorkingCalendarExport:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
560
    def __init__(self):
561
        pass
562
563
    @staticmethod
564
    def on_options(req, resp, id_):
565
        _ = req
566
        resp.status = falcon.HTTP_200
567
        _ = id_
568
569
    @staticmethod
570
    def on_get(req, resp, id_):
571
        if 'API-KEY' not in req.headers or \
572
                not isinstance(req.headers['API-KEY'], str) or \
573
                len(str.strip(req.headers['API-KEY'])) == 0:
574
            access_control(req)
575
        else:
576
            api_key_control(req)
577
        if not id_.isdigit() or int(id_) <= 0:
578
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
579
                                   description='API.INVALID_WORKING_CALENDAR_ID')
580
581
        cnx = mysql.connector.connect(**config.myems_system_db)
582
        cursor = cnx.cursor()
583
584
        cursor.execute(" SELECT id, name, description"
585
                       " FROM tbl_working_calendars "
586
                       " WHERE id = %s ", (id_,))
587
        row = cursor.fetchone()
588
589
        if row is None:
590
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
591
                                   description='API.WORKING_CALENDAR_NOT_FOUND')
592
593
        meta_result = {"id": row[0],
594
                       "name": row[1],
595
                       "description": row[2],
596
                       "non_working_days": None}
597
598
        cursor.execute(" SELECT id, working_calendar_id, date_local, description"
599
                       " FROM tbl_working_calendars_non_working_days "
600
                       " WHERE working_calendar_id = %s ", (id_,))
601
        rows_date_local = cursor.fetchall()
602
603
        result = list()
604
        if rows_date_local is not None and len(rows_date_local) > 0:
605
            for row in rows_date_local:
606
                date_local_dict = {'id': row[0],
607
                                   'working_calendar_id': row[1],
608
                                   'date_local': row[2].isoformat()[0:10],
609
                                   'description': row[3]}
610
                result.append(date_local_dict)
611
        meta_result['non_working_days'] = result
612
        cursor.close()
613
        cnx.close()
614
        resp.text = json.dumps(meta_result)
615
616
617
class WorkingCalendarImport:
618
    def __init__(self):
619
        pass
620
621
    @staticmethod
622
    def on_options(req, resp):
623
        _ = req
624
        resp.status = falcon.HTTP_200
625
626
    @staticmethod
627
    def on_post(req, resp):
628
        """Handles POST requests"""
629
        admin_control(req)
630
        try:
631
            raw_json = req.stream.read().decode('utf-8')
632
            new_values = json.loads(raw_json)
633
        except UnicodeDecodeError as ex:
634
            print("Failed to decode request")
635
            raise falcon.HTTPError(status=falcon.HTTP_400,
636
                                   title='API.BAD_REQUEST',
637
                                   description='API.INVALID_ENCODING')
638
        except json.JSONDecodeError as ex:
639
            print("Failed to parse JSON")
640
            raise falcon.HTTPError(status=falcon.HTTP_400,
641
                                   title='API.BAD_REQUEST',
642
                                   description='API.INVALID_JSON_FORMAT')
643
        except Exception as ex:
644
            print("Unexpected error reading request stream")
645
            raise falcon.HTTPError(status=falcon.HTTP_400,
646
                                   title='API.BAD_REQUEST',
647
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
648
649
        if 'name' not in new_values.keys() or \
650
                not isinstance(new_values['name'], str) or \
651
                len(str.strip(new_values['name'])) == 0:
652
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
653
                                   description='API.INVALID_WORKING_CALENDAR_NAME')
654
        name = str.strip(new_values['name'])
655
656
        if 'description' in new_values.keys() and \
657
                new_values['description'] is not None and \
658
                len(str(new_values['description'])) > 0:
659
            description = str.strip(new_values['description'])
660
        else:
661
            description = None
662
663
        cnx = mysql.connector.connect(**config.myems_system_db)
664
        cursor = cnx.cursor()
665
666
        cursor.execute(" SELECT name "
667
                       " FROM tbl_working_calendars "
668
                       " WHERE name = %s ", (name,))
669
        if cursor.fetchone() is not None:
670
            cursor.close()
671
            cnx.close()
672
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
673
                                   description='API.WORKING_CALENDAR_NAME_IS_ALREADY_IN_USE')
674
675
        add_values = (" INSERT INTO tbl_working_calendars "
676
                      " (name, description) "
677
                      " VALUES (%s, %s) ")
678
        cursor.execute(add_values, (name,
679
                                    description))
680
        new_id = cursor.lastrowid
681
        working_calendar_id = new_id
682
        for values in new_values['non_working_days']:
683
            if 'date_local' not in values or \
684
                    values['date_local'] is None or \
685
                    len(str(values['date_local'])) <= 0:
686
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
687
                                       description='API.INVALID_DATE_LOCAL')
688
            date_local = str.strip(values['date_local'])
689
690
            if 'description' in values and \
691
                    values['description'] is not None and \
692
                    len(str(values['description'])) > 0:
693
                description = str.strip(values['description'])
694
            else:
695
                description = None
696
697
            cursor.execute(" SELECT id "
698
                           " FROM tbl_working_calendars_non_working_days "
699
                           " WHERE working_calendar_id = %s AND date_local = %s ",
700
                           (working_calendar_id, date_local))
701
            if cursor.fetchone() is not None:
702
                cursor.close()
703
                cnx.close()
704
                raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
705
                                       description='API.DATE_IS_ALREADY_IN_WORKING_CALENDAR')
706
707
            add_values = (" INSERT INTO tbl_working_calendars_non_working_days "
708
                          " (working_calendar_id, date_local, description) "
709
                          " VALUES (%s, %s, %s) ")
710
            cursor.execute(add_values, (working_calendar_id, date_local, description))
711
        cnx.commit()
712
        cursor.close()
713
        cnx.close()
714
715
        resp.status = falcon.HTTP_201
716
        resp.location = '/workingcalendar/' + str(new_id)
717
718
719
class WorkingCalendarClone:
720
    def __init__(self):
721
        pass
722
723
    @staticmethod
724
    def on_options(req, resp, id_):
725
        _ = req
726
        resp.status = falcon.HTTP_200
727
        _ = id_
728
729
    @staticmethod
730
    def on_post(req, resp, id_):
731
        admin_control(req)
732
        if not id_.isdigit() or int(id_) <= 0:
733
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
734
                                   description='API.INVALID_WORKING_CALENDAR_ID')
735
736
        cnx = mysql.connector.connect(**config.myems_system_db)
737
        cursor = cnx.cursor()
738
739
        cursor.execute(" SELECT id, name, description"
740
                       " FROM tbl_working_calendars "
741
                       " WHERE id = %s ", (id_,))
742
        row = cursor.fetchone()
743
744
        if row is None:
745
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
746
                                   description='API.WORKING_CALENDAR_NOT_FOUND')
747
748
        meta_result = {"id": row[0],
749
                       "name": row[1],
750
                       "description": row[2],
751
                       "non_working_days": None}
752
        cursor.execute(" SELECT id, working_calendar_id, date_local, description"
753
                       " FROM tbl_working_calendars_non_working_days "
754
                       " WHERE working_calendar_id = %s ", (id_,))
755
        rows_date_local = cursor.fetchall()
756
757
        result = list()
758
        if rows_date_local is not None and len(rows_date_local) > 0:
759
            for row in rows_date_local:
760
                date_local_dict = {'id': row[0],
761
                                   'working_calendar_id': row[1],
762
                                   'date_local': row[2].isoformat()[0:10],
763
                                   'description': row[3]}
764
                result.append(date_local_dict)
765
        meta_result['non_working_days'] = result
766
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
767
        if config.utc_offset[0] == '-':
768
            timezone_offset = -timezone_offset
769
        new_name = (str.strip(meta_result['name']) +
770
                    (datetime.utcnow() + timedelta(minutes=timezone_offset)).isoformat(sep='-', timespec='seconds'))
771
        add_values = (" INSERT INTO tbl_working_calendars "
772
                      " (name, description) "
773
                      " VALUES (%s, %s) ")
774
        cursor.execute(add_values, (new_name,
775
                                    meta_result['description']))
776
        new_id = cursor.lastrowid
777
        for values in meta_result['non_working_days']:
778
            add_values = (" INSERT INTO tbl_working_calendars_non_working_days "
779
                          " (working_calendar_id, date_local, description) "
780
                          " VALUES (%s, %s, %s) ")
781
            cursor.execute(add_values, (new_id, values['date_local'], values['description']))
782
        cnx.commit()
783
        cursor.close()
784
        cnx.close()
785
786
        resp.status = falcon.HTTP_201
787
        resp.location = '/workingcalendar/' + str(new_id)
788
789