Issues (1577)

myems-api/excelexporters/combinedequipmentcost.py (6 issues)

1
import base64
2
from core.utilities import get_translation
3
import os
4
import re
5
import uuid
6
from decimal import Decimal
7
import openpyxl.utils.cell as format_cell
8
from openpyxl import Workbook
9
from openpyxl.chart import PieChart, LineChart, Reference
10
from openpyxl.chart.label import DataLabelList
11
from openpyxl.drawing.image import Image
12
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
13
from core.utilities import round2
14
15
########################################################################################################################
16
# PROCEDURES
17
# Step 1: Validate the report data
18
# Step 2: Generate excel file
19
# Step 3: Encode the excel file to Base64
20
########################################################################################################################
21
22
23 View Code Duplication
def export(report,
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
24
           name,
25
           base_period_start_datetime_local,
26
           base_period_end_datetime_local,
27
           reporting_start_datetime_local,
28
           reporting_end_datetime_local,
29
           period_type,
30
           language):
31
    ####################################################################################################################
32
    # Step 1: Validate the report data
33
    ####################################################################################################################
34
    if report is None:
35
        return None
36
    print(report)
37
38
    ####################################################################################################################
39
    # Step 2: Generate excel file from the report data
40
    ####################################################################################################################
41
    filename = generate_excel(report,
42
                              name,
43
                              base_period_start_datetime_local,
44
                              base_period_end_datetime_local,
45
                              reporting_start_datetime_local,
46
                              reporting_end_datetime_local,
47
                              period_type,
48
                              language)
49
    ####################################################################################################################
50
    # Step 3: Encode the excel file to Base64
51
    ####################################################################################################################
52
    binary_file_data = b''
53
    try:
54
        with open(filename, 'rb') as binary_file:
55
            binary_file_data = binary_file.read()
56
    except IOError as ex:
57
        print(str(ex))
58
59
    # Base64 encode the bytes
60
    base64_encoded_data = base64.b64encode(binary_file_data)
61
    # get the Base64 encoded data using human-readable characters.
62
    base64_message = base64_encoded_data.decode('utf-8')
63
    # delete the file from server
64
    try:
65
        os.remove(filename)
66
    except NotImplementedError as ex:
67
        print(str(ex))
68
    return base64_message
69
70
71 View Code Duplication
def generate_excel(report,
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
72
                   name,
73
                   base_period_start_datetime_local,
74
                   base_period_end_datetime_local,
75
                   reporting_start_datetime_local,
76
                   reporting_end_datetime_local,
77
                   period_type,
78
                   language):
79
80
    trans = get_translation(language)
81
    trans.install()
82
    _ = trans.gettext
83
84
    wb = Workbook()
85
    ws = wb.active
86
    ws.title = "CombinedEquipmentCost"
87
88
    # Row height
89
    ws.row_dimensions[1].height = 102
90
    for i in range(2, 2000 + 1):
91
        ws.row_dimensions[i].height = 42
92
93
    # Col width
94
    ws.column_dimensions['A'].width = 1.5
95
96
    ws.column_dimensions['B'].width = 25.0
97
98
    for i in range(ord('C'), ord('Z')):
99
        ws.column_dimensions[chr(i)].width = 15.0
100
101
    # Font
102
    name_font = Font(name='Arial', size=15, bold=True)
103
    title_font = Font(name='Arial', size=15, bold=True)
104
105
    table_fill = PatternFill(fill_type='solid', fgColor='90ee90')
106
    f_border = Border(left=Side(border_style='medium'),
107
                      right=Side(border_style='medium'),
108
                      bottom=Side(border_style='medium'),
109
                      top=Side(border_style='medium')
110
                      )
111
    b_border = Border(
112
        bottom=Side(border_style='medium'),
113
    )
114
115
    b_c_alignment = Alignment(vertical='bottom',
116
                              horizontal='center',
117
                              text_rotation=0,
118
                              wrap_text=True,
119
                              shrink_to_fit=False,
120
                              indent=0)
121
    c_c_alignment = Alignment(vertical='center',
122
                              horizontal='center',
123
                              text_rotation=0,
124
                              wrap_text=True,
125
                              shrink_to_fit=False,
126
                              indent=0)
127
    b_r_alignment = Alignment(vertical='bottom',
128
                              horizontal='right',
129
                              text_rotation=0,
130
                              wrap_text=True,
131
                              shrink_to_fit=False,
132
                              indent=0)
133
134
    # Img
135
    img = Image("excelexporters/myems.png")
136
    ws.add_image(img, 'A1')
137
138
    # Title=
139
    ws['B3'].alignment = b_r_alignment
140
    ws['B3'] = _('Name') + ':'
141
    ws['C3'].border = b_border
142
    ws['C3'].alignment = b_c_alignment
143
    ws['C3'] = name
144
145
    ws['D3'].alignment = b_r_alignment
146
    ws['D3'] = _('Period Type') + ':'
147
    ws['E3'].border = b_border
148
    ws['E3'].alignment = b_c_alignment
149
    ws['E3'] = period_type
150
151
    ws['B4'].alignment = b_r_alignment
152
    ws['B4'] = _('Reporting Start Datetime') + ':'
153
    ws['C4'].border = b_border
154
    ws['C4'].alignment = b_c_alignment
155
    ws['C4'] = reporting_start_datetime_local
156
157
    ws['D4'].alignment = b_r_alignment
158
    ws['D4'] = _('Reporting End Datetime') + ':'
159
    ws['E4'].border = b_border
160
    ws['E4'].alignment = b_c_alignment
161
    ws['E4'] = reporting_end_datetime_local
162
163
    is_base_period_timestamp_exists_flag = is_base_period_timestamp_exists(report['base_period'])
164
165
    if is_base_period_timestamp_exists_flag:
166
        ws['B5'].alignment = b_r_alignment
167
        ws['B5'] = _('Base Period Start Datetime') + ':'
168
        ws['C5'].border = b_border
169
        ws['C5'].alignment = b_c_alignment
170
        ws['C5'] = base_period_start_datetime_local
171
172
        ws['D5'].alignment = b_r_alignment
173
        ws['D5'] = _('Base Period End Datetime') + ':'
174
        ws['E5'].border = b_border
175
        ws['E5'].alignment = b_c_alignment
176
        ws['E5'] = base_period_end_datetime_local
177
178
    if "reporting_period" not in report.keys() or \
179
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
180
        filename = str(uuid.uuid4()) + '.xlsx'
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable str does not seem to be defined.
Loading history...
181
        wb.save(filename)
182
183
        return filename
184
185
    reporting_period_data = report['reporting_period']
186
    if "names" not in reporting_period_data.keys() or \
187
            reporting_period_data['names'] is None or \
188
            len(reporting_period_data['names']) == 0:
189
        for i in range(7, 10 + 1):
190
            ws.row_dimensions[i].height = 0.1
191
192
    else:
193
        ws['B7'].font = title_font
194
        ws['B7'] = name + ' ' + _('Reporting Period Costs')
195
196
        category = reporting_period_data['names']
197
        ca_len = len(category)
198
199
        ws.row_dimensions[8].height = 60
200
        ws['B8'].fill = table_fill
201
        ws['B8'].border = f_border
202
203
        ws['B9'].font = title_font
204
        ws['B9'].alignment = c_c_alignment
205
        ws['B9'] = _('Cost')
206
        ws['B9'].border = f_border
207
208
        ws['B10'].font = title_font
209
        ws['B10'].alignment = c_c_alignment
210
        ws['B10'] = _('Increment Rate')
211
        ws['B10'].border = f_border
212
213
        col = 'B'
214
215
        for i in range(0, ca_len):
216
            col = chr(ord('C') + i)
217
            ws[col + '8'].fill = table_fill
218
            ws[col + '8'].font = name_font
219
            ws[col + '8'].alignment = c_c_alignment
220
            ws[col + '8'] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
221
            ws[col + '8'].border = f_border
222
223
            ws[col + '9'].font = name_font
224
            ws[col + '9'].alignment = c_c_alignment
225
            ws[col + '9'] = round2(reporting_period_data['subtotals'][i], 2)
226
            ws[col + '9'].border = f_border
227
228
            ws[col + '10'].font = name_font
229
            ws[col + '10'].alignment = c_c_alignment
230
            ws[col + '10'] = str(round2(reporting_period_data['increment_rates'][i] * 100, 2)) + "%" \
231
                if reporting_period_data['increment_rates'][i] is not None else "-"
232
            ws[col + '10'].border = f_border
233
234
        end_col = chr(ord(col) + 1)
235
        ws[end_col + '8'].fill = table_fill
236
        ws[end_col + '8'].font = name_font
237
        ws[end_col + '8'].alignment = c_c_alignment
238
        ws[end_col + '8'] = _("Total") + " (" + reporting_period_data['total_unit'] + ")"
239
        ws[end_col + '8'].border = f_border
240
241
        ws[end_col + '9'].font = name_font
242
        ws[end_col + '9'].alignment = c_c_alignment
243
        ws[end_col + '9'] = round2(reporting_period_data['total'], 2)
244
        ws[end_col + '9'].border = f_border
245
246
        ws[end_col + '10'].font = name_font
247
        ws[end_col + '10'].alignment = c_c_alignment
248
        ws[end_col + '10'] = str(round2(reporting_period_data['total_increment_rate'] * 100, 2)) + "%" \
249
            if reporting_period_data['total_increment_rate'] is not None else "-"
250
        ws[end_col + '10'].border = f_border
251
252
    if "toppeaks" not in reporting_period_data.keys() or \
253
            reporting_period_data['toppeaks'] is None or \
254
            len(reporting_period_data['toppeaks']) == 0:
255
        for i in range(12, 18 + 1):
256
            ws.row_dimensions[i].height = 0.1
257
258
    else:
259
        electricity_index = -1
260
        for i in range(len(reporting_period_data['energy_category_ids'])):
261
            if reporting_period_data['energy_category_ids'][i] == 1:
262
                electricity_index = i
263
                break
264
265
        ws['B12'].font = title_font
266
        ws['B12'] = name + _('Electricity Cost by Time-Of-Use')
267
268
        ws['B13'].fill = table_fill
269
        ws['B13'].font = name_font
270
        ws['B13'].alignment = c_c_alignment
271
        ws['B13'].border = f_border
272
273
        ws['C13'].fill = table_fill
274
        ws['C13'].font = name_font
275
        ws['C13'].alignment = c_c_alignment
276
        ws['C13'].border = f_border
277
        ws['C13'] = _('Electricity Cost by Time-Of-Use')
278
279
        ws['D13'].fill = table_fill
280
        ws['D13'].font = name_font
281
        ws['D13'].alignment = c_c_alignment
282
        ws['D13'].border = f_border
283
        ws['D13'] = _('Electricity Cost Proportion by Time-Of-Use')
284
285
        costsum = None
286
287
        if electricity_index >= 0:
288
            costsum = round(reporting_period_data['toppeaks'][electricity_index], 2) + \
289
                      round(reporting_period_data['onpeaks'][electricity_index], 2) + \
290
                      round(reporting_period_data['midpeaks'][electricity_index], 2) + \
291
                      round(reporting_period_data['offpeaks'][electricity_index], 2) + \
292
                      round(reporting_period_data['deeps'][electricity_index], 2)
293
294
        ws['B14'].font = title_font
295
        ws['B14'].alignment = c_c_alignment
296
        ws['B14'] = _('TopPeak')
297
        ws['B14'].border = f_border
298
299
        ws['C14'].font = title_font
300
        ws['C14'].alignment = c_c_alignment
301
        ws['C14'].border = f_border
302
        ws['C14'] = round2(reporting_period_data['toppeaks'][electricity_index], 2) if electricity_index >= 0 else "-"
303
304
        ws['D14'].font = title_font
305
        ws['D14'].alignment = c_c_alignment
306
        ws['D14'].border = f_border
307
        ws['D14'] = '{:.2%}'.format(round2(reporting_period_data['toppeaks'][electricity_index], 2) / costsum) \
308
            if costsum is not None and costsum != Decimal(0.0) else " "
309
310
        ws['B15'].font = title_font
311
        ws['B15'].alignment = c_c_alignment
312
        ws['B15'] = _('OnPeak')
313
        ws['B15'].border = f_border
314
315
        ws['C15'].font = title_font
316
        ws['C15'].alignment = c_c_alignment
317
        ws['C15'].border = f_border
318
        ws['C15'] = round2(reporting_period_data['onpeaks'][electricity_index], 2) if electricity_index >= 0 else "-"
319
320
        ws['D15'].font = title_font
321
        ws['D15'].alignment = c_c_alignment
322
        ws['D15'].border = f_border
323
        ws['D15'] = '{:.2%}'.format(round2(reporting_period_data['onpeaks'][electricity_index], 2) / costsum) \
324
            if costsum is not None and costsum != Decimal(0.0) else " "
325
326
        ws['B16'].font = title_font
327
        ws['B16'].alignment = c_c_alignment
328
        ws['B16'] = _('MidPeak')
329
        ws['B16'].border = f_border
330
331
        ws['C16'].font = title_font
332
        ws['C16'].alignment = c_c_alignment
333
        ws['C16'].border = f_border
334
        ws['C16'] = round2(reporting_period_data['midpeaks'][electricity_index], 2) if electricity_index >= 0 else "-"
335
336
        ws['D16'].font = title_font
337
        ws['D16'].alignment = c_c_alignment
338
        ws['D16'].border = f_border
339
        ws['D16'] = '{:.2%}'.format(round2(reporting_period_data['midpeaks'][electricity_index], 2) / costsum) \
340
            if costsum is not None and costsum != Decimal(0.0) else " "
341
342
        ws['B17'].font = title_font
343
        ws['B17'].alignment = c_c_alignment
344
        ws['B17'] = _('OffPeak')
345
        ws['B17'].border = f_border
346
347
        ws['C17'].font = title_font
348
        ws['C17'].alignment = c_c_alignment
349
        ws['C17'].border = f_border
350
        ws['C17'] = round2(reporting_period_data['offpeaks'][electricity_index], 2) if electricity_index >= 0 else "-"
351
352
        ws['D17'].font = title_font
353
        ws['D17'].alignment = c_c_alignment
354
        ws['D17'].border = f_border
355
        ws['D17'] = '{:.2%}'.format(round2(reporting_period_data['offpeaks'][electricity_index], 2) / costsum) \
356
            if costsum is not None and costsum != Decimal(0.0) else " "
357
358
        pie = PieChart()
359
        pie.title = name + _('Electricity Cost by Time-Of-Use')
360
        labels = Reference(ws, min_col=2, min_row=14, max_row=17)
361
        pie_data = Reference(ws, min_col=3, min_row=13, max_row=17)
362
        pie.add_data(pie_data, titles_from_data=True)
363
        pie.set_categories(labels)
364
        pie.height = 6.6
365
        pie.width = 9
366
        s1 = pie.series[0]
367
        s1.dLbls = DataLabelList()
368
        s1.dLbls.showCatName = False
369
        s1.dLbls.showVal = False
370
        s1.dLbls.showPercent = True
371
        ws.add_chart(pie, "E13")
372
373
    ####################################################################################################################
374
375
    current_row_number = 19
376
    if "subtotals" not in reporting_period_data.keys() or \
377
            reporting_period_data['subtotals'] is None or \
378
            len(reporting_period_data['subtotals']) == 0:
379
        for i in range(21, 29 + 1):
380
            current_row_number = 30
381
            ws.row_dimensions[i].height = 0.1
382
    else:
383
        ws['B' + str(current_row_number)].font = title_font
384
        ws['B' + str(current_row_number)] = name + ' ' + _('Costs Proportion')
385
386
        current_row_number += 1
387
388
        table_start_row_number = current_row_number
389
390
        ws['B' + str(current_row_number)].fill = table_fill
391
        ws['B' + str(current_row_number)].font = name_font
392
        ws['B' + str(current_row_number)].alignment = c_c_alignment
393
        ws['B' + str(current_row_number)].border = f_border
394
395
        ws['C' + str(current_row_number)].fill = table_fill
396
        ws['C' + str(current_row_number)].font = name_font
397
        ws['C' + str(current_row_number)].alignment = c_c_alignment
398
        ws['C' + str(current_row_number)].border = f_border
399
        ws['C' + str(current_row_number)] = _('Cost')
400
401
        ws['D' + str(current_row_number)].fill = table_fill
402
        ws['D' + str(current_row_number)].font = name_font
403
        ws['D' + str(current_row_number)].alignment = c_c_alignment
404
        ws['D' + str(current_row_number)].border = f_border
405
        ws['D' + str(current_row_number)] = _('Costs Proportion')
406
407
        current_row_number += 1
408
409
        ca_len = len(reporting_period_data['names'])
410
        costsum = Decimal(0.0)
411
        for i in range(0, ca_len):
412
            costsum = round(reporting_period_data['subtotals'][i], 2) + costsum
413
        for i in range(0, ca_len):
414
            ws['B' + str(current_row_number)].font = title_font
415
            ws['B' + str(current_row_number)].alignment = c_c_alignment
416
            ws['B' + str(current_row_number)] = reporting_period_data['names'][i]
417
            ws['B' + str(current_row_number)].border = f_border
418
419
            ws['C' + str(current_row_number)].font = title_font
420
            ws['C' + str(current_row_number)].alignment = c_c_alignment
421
            ws['C' + str(current_row_number)].border = f_border
422
            ws['C' + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2)
423
424
            ws['D' + str(current_row_number)].font = title_font
425
            ws['D' + str(current_row_number)].alignment = c_c_alignment
426
            ws['D' + str(current_row_number)].border = f_border
427
            ws['D' + str(current_row_number)] = '{:.2%}'.format(round2(
428
                reporting_period_data['subtotals'][i], 2) / costsum) if \
429
                costsum is not None and costsum != Decimal(0.0) else " "
430
            current_row_number += 1
431
432
        table_end_row_number = current_row_number - 1
433
434
        pie = PieChart()
435
        pie.title = name + ' ' + _('Costs Proportion')
436
        labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
437
        pie_data = Reference(ws, min_col=3, min_row=table_start_row_number, max_row=table_end_row_number)
438
        pie.add_data(pie_data, titles_from_data=True)
439
        pie.set_categories(labels)
440
        pie.height = 6.6
441
        pie.width = 9
442
        s1 = pie.series[0]
443
        s1.dLbls = DataLabelList()
444
        s1.dLbls.showCatName = False
445
        s1.dLbls.showVal = False
446
        s1.dLbls.showPercent = True
447
        table_cell = 'E' + str(table_start_row_number)
448
        ws.add_chart(pie, table_cell)
449
450
        if ca_len < 4:
451
            current_row_number = current_row_number - ca_len + 4
452
453
        current_row_number += 1
454
455
    ####################################################################################################################
456
    table_start_draw_flag = current_row_number + 1
457
458
    if "timestamps" not in reporting_period_data.keys() or \
459
            reporting_period_data['timestamps'] is None or \
460
            len(reporting_period_data['timestamps']) == 0:
461
        pass
462
    else:
463
        if not is_base_period_timestamp_exists_flag:
464
            reporting_period_data = report['reporting_period']
465
            times = reporting_period_data['timestamps']
466
            ca_len = len(report['reporting_period']['names'])
467
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
468
            ws['B' + str(current_row_number)].font = title_font
469
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
470
471
            current_row_number += 1
472
            # 1: Stand for blank line  2: Stand for title
473
            current_row_number += ca_len * 6 + real_timestamps_len * 6 + 1 + 2
474
            table_start_row_number = current_row_number
475
476
            time = times[0]
477
            has_data = False
478
479
            if len(time) > 0:
480
                has_data = True
481
482
            if has_data:
483
484
                ws.row_dimensions[current_row_number].height = 60
485
                current_col_number = 2
486
                col = format_cell.get_column_letter(current_col_number)
487
                ws[col + str(current_row_number)].fill = table_fill
488
                ws[col + str(current_row_number)].font = title_font
489
                ws[col + str(current_row_number)].border = f_border
490
                ws[col + str(current_row_number)].alignment = c_c_alignment
491
                ws[col + str(current_row_number)] = _('Datetime')
492
493
                for i in range(0, ca_len):
494
                    current_col_number += 1
495
                    col = format_cell.get_column_letter(current_col_number)
496
497
                    ws[col + str(current_row_number)].fill = table_fill
498
                    ws[col + str(current_row_number)].font = title_font
499
                    ws[col + str(current_row_number)].alignment = c_c_alignment
500
                    ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
501
                        " (" + reporting_period_data['units'][i] + ")"
502
                    ws[col + str(current_row_number)].border = f_border
503
504
                current_col_number += 1
505
                col = format_cell.get_column_letter(current_col_number)
506
                ws[col + str(current_row_number)].fill = table_fill
507
                ws[col + str(current_row_number)].font = title_font
508
                ws[col + str(current_row_number)].alignment = c_c_alignment
509
                ws[col + str(current_row_number)] = _('Total') + '(' + report['reporting_period']['total_unit'] + ')'
510
                ws[col + str(current_row_number)].border = f_border
511
512
                current_row_number += 1
513
514
                for i in range(0, len(time)):
515
                    current_col_number = 2
516
                    col = format_cell.get_column_letter(current_col_number)
517
518
                    ws[col + str(current_row_number)].font = title_font
519
                    ws[col + str(current_row_number)].alignment = c_c_alignment
520
                    ws[col + str(current_row_number)] = time[i]
521
                    ws[col + str(current_row_number)].border = f_border
522
523
                    total = Decimal(0.0)
524
525
                    for j in range(0, ca_len):
526
                        current_col_number += 1
527
                        col = format_cell.get_column_letter(current_col_number)
528
529
                        ws[col + str(current_row_number)].font = title_font
530
                        ws[col + str(current_row_number)].alignment = c_c_alignment
531
                        ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2)
532
                        total += reporting_period_data['values'][j][i]
533
                        ws[col + str(current_row_number)].border = f_border
534
535
                    current_col_number += 1
536
                    col = format_cell.get_column_letter(current_col_number)
537
                    ws[col + str(current_row_number)].font = title_font
538
                    ws[col + str(current_row_number)].alignment = c_c_alignment
539
                    ws[col + str(current_row_number)] = round2(total, 2)
540
                    ws[col + str(current_row_number)].border = f_border
541
542
                    current_row_number += 1
543
544
                table_end_row_number = current_row_number - 1
545
546
                current_col_number = 2
547
                col = format_cell.get_column_letter(current_col_number)
548
549
                ws[col + str(current_row_number)].font = title_font
550
                ws[col + str(current_row_number)].alignment = c_c_alignment
551
                ws[col + str(current_row_number)] = _('Subtotal')
552
                ws[col + str(current_row_number)].border = f_border
553
554
                subtotals = Decimal(0.0)
555
556
                for i in range(0, ca_len):
557
                    current_col_number += 1
558
                    col = format_cell.get_column_letter(current_col_number)
559
                    ws[col + str(current_row_number)].font = title_font
560
                    ws[col + str(current_row_number)].alignment = c_c_alignment
561
                    ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2)
562
                    subtotals += reporting_period_data['subtotals'][i]
563
                    ws[col + str(current_row_number)].border = f_border
564
565
                    # line
566
                    line = LineChart()
567
                    line.title = _('Reporting Period Costs') + ' - ' \
568
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
569
                    labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
570
                    line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
571
                                          max_row=table_end_row_number)
572
                    line.add_data(line_data, titles_from_data=True)
573
                    line.set_categories(labels)
574
                    line_data = line.series[0]
575
                    line_data.marker.symbol = "auto"
576
                    line_data.smooth = True
577
                    line.x_axis.crosses = 'min'
578
                    line.height = 8.25
579
                    line.width = 24
580
                    chart_col = 'B'
581
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
582
                    ws.add_chart(line, chart_cell)
583
584
                current_col_number += 1
585
                col = format_cell.get_column_letter(current_col_number)
586
                ws[col + str(current_row_number)].font = title_font
587
                ws[col + str(current_row_number)].alignment = c_c_alignment
588
                ws[col + str(current_row_number)] = round2(subtotals, 2)
589
                ws[col + str(current_row_number)].border = f_border
590
591
                current_row_number += 2
592
        else:
593
            base_period_data = report['base_period']
594
            reporting_period_data = report['reporting_period']
595
            base_period_timestamps = base_period_data['timestamps']
596
            reporting_period_timestamps = reporting_period_data['timestamps']
597
            # Tip:
598
            #     base_period_data['names'] == reporting_period_data['names']
599
            #     base_period_data['units'] == reporting_period_data['units']
600
            base_period_data_ca_len = len(base_period_data['names'])
601
            reporting_period_data_ca_len = len(reporting_period_data['names'])
602
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
603
            ws['B' + str(current_row_number)].font = title_font
604
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
605
606
            current_row_number += 1
607
            # 1: Stand for blank line  2: Stand for title
608
            current_row_number += reporting_period_data_ca_len * 6 + real_timestamps_len * 6 + 1 + 2
609
            table_start_row_number = current_row_number
610
611
            has_data = False
612
613
            if len(base_period_timestamps[0]) or len(reporting_period_timestamps[0]) > 0:
614
                has_data = True
615
616
            if has_data:
617
                ws.row_dimensions[current_row_number].height = 60
618
                current_col_number = 2
619
                col = format_cell.get_column_letter(current_col_number)
620
                ws[col + str(current_row_number)].fill = table_fill
621
                ws[col + str(current_row_number)].font = title_font
622
                ws[col + str(current_row_number)].border = f_border
623
                ws[col + str(current_row_number)].alignment = c_c_alignment
624
                ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime')
625
626
                for i in range(0, base_period_data_ca_len):
627
                    current_col_number += 1
628
                    col = format_cell.get_column_letter(current_col_number)
629
630
                    ws[col + str(current_row_number)].fill = table_fill
631
                    ws[col + str(current_row_number)].font = title_font
632
                    ws[col + str(current_row_number)].alignment = c_c_alignment
633
                    ws[col + str(current_row_number)] = _('Base Period') + " - " + base_period_data['names'][i] + \
634
                        " (" + base_period_data['units'][i] + ")"
635
                    ws[col + str(current_row_number)].border = f_border
636
637
                current_col_number += 1
638
                col = format_cell.get_column_letter(current_col_number)
639
                ws[col + str(current_row_number)].fill = table_fill
640
                ws[col + str(current_row_number)].font = title_font
641
                ws[col + str(current_row_number)].alignment = c_c_alignment
642
                ws[col + str(current_row_number)] = _('Base Period') + " - " \
643
                    + _('Total') + '(' + report['reporting_period']['total_unit'] + ')'
644
                ws[col + str(current_row_number)].border = f_border
645
646
                current_col_number += 1
647
                col = format_cell.get_column_letter(current_col_number)
648
649
                ws[col + str(current_row_number)].fill = table_fill
650
                ws[col + str(current_row_number)].font = title_font
651
                ws[col + str(current_row_number)].border = f_border
652
                ws[col + str(current_row_number)].alignment = c_c_alignment
653
                ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime')
654
655
                for i in range(0, reporting_period_data_ca_len):
656
                    current_col_number += 1
657
                    col = format_cell.get_column_letter(current_col_number)
658
                    ws[col + str(current_row_number)].fill = table_fill
659
                    ws[col + str(current_row_number)].font = title_font
660
                    ws[col + str(current_row_number)].alignment = c_c_alignment
661
                    ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
662
                        + reporting_period_data['names'][i] + " (" + \
663
                        reporting_period_data['units'][i] + ")"
664
                    ws[col + str(current_row_number)].border = f_border
665
666
                current_col_number += 1
667
                col = format_cell.get_column_letter(current_col_number)
668
                ws[col + str(current_row_number)].fill = table_fill
669
                ws[col + str(current_row_number)].font = title_font
670
                ws[col + str(current_row_number)].alignment = c_c_alignment
671
                ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
672
                    + _('Total') + '(' + report['reporting_period']['total_unit'] + ')'
673
                ws[col + str(current_row_number)].border = f_border
674
675
                current_row_number += 1
676
677
                max_timestamps_len = len(base_period_timestamps[0]) \
678
                    if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \
679
                    else len(reporting_period_timestamps[0])
680
681
                for i in range(0, max_timestamps_len):
682
                    current_col_number = 2
683
                    col = format_cell.get_column_letter(current_col_number)
684
                    ws[col + str(current_row_number)].font = title_font
685
                    ws[col + str(current_row_number)].alignment = c_c_alignment
686
                    ws[col + str(current_row_number)] = base_period_timestamps[0][i] \
687
                        if i < len(base_period_timestamps[0]) else None
688
                    ws[col + str(current_row_number)].border = f_border
689
690
                    base_period_total = Decimal(0.0)
691
692
                    for j in range(0, base_period_data_ca_len):
693
                        current_col_number += 1
694
                        col = format_cell.get_column_letter(current_col_number)
695
696
                        ws[col + str(current_row_number)].font = title_font
697
                        ws[col + str(current_row_number)].alignment = c_c_alignment
698
                        ws[col + str(current_row_number)] = round2(base_period_data['values'][j][i], 2) \
699
                            if i < len(base_period_data['values'][j]) else None
700
                        if i < len(base_period_timestamps[0]):
701
                            base_period_total += base_period_data['values'][j][i]
702
                        ws[col + str(current_row_number)].border = f_border
703
704
                    current_col_number += 1
705
                    col = format_cell.get_column_letter(current_col_number)
706
                    ws[col + str(current_row_number)].font = title_font
707
                    ws[col + str(current_row_number)].alignment = c_c_alignment
708
                    ws[col + str(current_row_number)] = round2(base_period_total, 2) \
709
                        if i < len(base_period_timestamps[0]) else None
710
                    ws[col + str(current_row_number)].border = f_border
711
712
                    current_col_number += 1
713
                    col = format_cell.get_column_letter(current_col_number)
714
715
                    ws[col + str(current_row_number)].font = title_font
716
                    ws[col + str(current_row_number)].alignment = c_c_alignment
717
                    ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \
718
                        if i < len(reporting_period_timestamps[0]) else None
719
                    ws[col + str(current_row_number)].border = f_border
720
721
                    reporting_period_total = Decimal(0.0)
722
723
                    for j in range(0, reporting_period_data_ca_len):
724
                        current_col_number += 1
725
                        col = format_cell.get_column_letter(current_col_number)
726
727
                        ws[col + str(current_row_number)].font = title_font
728
                        ws[col + str(current_row_number)].alignment = c_c_alignment
729
                        ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2) \
730
                            if i < len(reporting_period_data['values'][j]) else None
731
                        if i < len(reporting_period_timestamps[0]):
732
                            reporting_period_total += reporting_period_data['values'][j][i]
733
                        ws[col + str(current_row_number)].border = f_border
734
735
                    current_col_number += 1
736
                    col = format_cell.get_column_letter(current_col_number)
737
                    ws[col + str(current_row_number)].font = title_font
738
                    ws[col + str(current_row_number)].alignment = c_c_alignment
739
                    ws[col + str(current_row_number)] = round2(reporting_period_total, 2) \
740
                        if i < len(reporting_period_timestamps[0]) else None
741
                    ws[col + str(current_row_number)].border = f_border
742
743
                    current_row_number += 1
744
745
                current_col_number = 2
746
                col = format_cell.get_column_letter(current_col_number)
747
                ws[col + str(current_row_number)].font = title_font
748
                ws[col + str(current_row_number)].alignment = c_c_alignment
749
                ws[col + str(current_row_number)] = _('Subtotal')
750
                ws[col + str(current_row_number)].border = f_border
751
752
                base_period_subtotals = Decimal(0.0)
753
754
                for i in range(0, base_period_data_ca_len):
755
                    current_col_number += 1
756
                    col = format_cell.get_column_letter(current_col_number)
757
                    ws[col + str(current_row_number)].font = title_font
758
                    ws[col + str(current_row_number)].alignment = c_c_alignment
759
                    ws[col + str(current_row_number)] = round2(base_period_data['subtotals'][i], 2)
760
                    base_period_subtotals += base_period_data['subtotals'][i]
761
                    ws[col + str(current_row_number)].border = f_border
762
763
                current_col_number += 1
764
                col = format_cell.get_column_letter(current_col_number)
765
                ws[col + str(current_row_number)].font = title_font
766
                ws[col + str(current_row_number)].alignment = c_c_alignment
767
                ws[col + str(current_row_number)] = round2(base_period_subtotals, 2)
768
                ws[col + str(current_row_number)].border = f_border
769
770
                current_col_number += 1
771
                col = format_cell.get_column_letter(current_col_number)
772
773
                ws[col + str(current_row_number)].font = title_font
774
                ws[col + str(current_row_number)].alignment = c_c_alignment
775
                ws[col + str(current_row_number)] = _('Subtotal')
776
                ws[col + str(current_row_number)].border = f_border
777
778
                reporting_period_subtotals = Decimal(0.0)
779
780
                for i in range(0, reporting_period_data_ca_len):
781
                    current_col_number += 1
782
                    col = format_cell.get_column_letter(current_col_number)
783
                    ws[col + str(current_row_number)].font = title_font
784
                    ws[col + str(current_row_number)].alignment = c_c_alignment
785
                    ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2)
786
                    reporting_period_subtotals += reporting_period_data['subtotals'][i]
787
                    ws[col + str(current_row_number)].border = f_border
788
789
                current_col_number += 1
790
                col = format_cell.get_column_letter(current_col_number)
791
                ws[col + str(current_row_number)].font = title_font
792
                ws[col + str(current_row_number)].alignment = c_c_alignment
793
                ws[col + str(current_row_number)] = round2(reporting_period_subtotals, 2)
794
                ws[col + str(current_row_number)].border = f_border
795
796
                for i in range(0, reporting_period_data_ca_len):
797
                    # line
798
                    line = LineChart()
799
                    line.title = _('Base Period Costs') + " / " \
800
                        + _('Reporting Period Costs') + ' - ' \
801
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
802
                    labels = Reference(ws, min_col=2 + base_period_data_ca_len + 1 + 1,
803
                                       min_row=table_start_row_number + 1,
804
                                       max_row=table_start_row_number + len(reporting_period_timestamps[0]))
805
                    base_line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
806
                                               max_row=table_start_row_number + len(reporting_period_timestamps[0]))
807
                    reporting_line_data = Reference(ws, min_col=3 + base_period_data_ca_len + 1 + 1 + i,
808
                                                    min_row=table_start_row_number,
809
                                                    max_row=table_start_row_number
810
                                                    + len(reporting_period_timestamps[0]))
811
                    line.add_data(base_line_data, titles_from_data=True)
812
                    line.add_data(reporting_line_data, titles_from_data=True)
813
                    line.set_categories(labels)
814
                    for j in range(len(line.series)):
815
                        line.series[j].marker.symbol = "auto"
816
                        line.series[j].smooth = True
817
                    line.x_axis.crosses = 'min'
818
                    line.height = 8.25
819
                    line.width = 24
820
                    chart_col = 'B'
821
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
822
                    ws.add_chart(line, chart_cell)
823
824
                current_row_number += 2
825
826
    ####################################################################################################################
827
828
    if "associated_equipment" not in report.keys() or \
829
            "energy_category_names" not in report['associated_equipment'].keys() or \
830
            len(report['associated_equipment']["energy_category_names"]) == 0 \
831
            or 'associated_equipment_names_array' not in report['associated_equipment'].keys() \
832
            or report['associated_equipment']['associated_equipment_names_array'] is None \
833
            or len(report['associated_equipment']['associated_equipment_names_array']) == 0 \
834
            or len(report['associated_equipment']['associated_equipment_names_array'][0]) == 0:
835
        pass
836
    else:
837
        associated_equipment = report['associated_equipment']
838
        current_row_number += 1
839
840
        ws['B' + str(current_row_number)].font = title_font
841
        ws['B' + str(current_row_number)] = name + ' ' + _('Associated Equipment Data')
842
843
        current_row_number += 1
844
845
        ws.row_dimensions[current_row_number].height = 60
846
        ws['B' + str(current_row_number)].fill = table_fill
847
        ws['B' + str(current_row_number)].font = name_font
848
        ws['B' + str(current_row_number)].alignment = c_c_alignment
849
        ws['B' + str(current_row_number)].border = f_border
850
        ws['B' + str(current_row_number)] = _('Associated Equipment')
851
        ca_len = len(associated_equipment['energy_category_names'])
852
853
        for i in range(0, ca_len):
854
            col = chr(ord('C') + i)
855
            ws[col + str(current_row_number)].fill = table_fill
856
            ws[col + str(current_row_number)].font = name_font
857
            ws[col + str(current_row_number)].alignment = c_c_alignment
858
            ws[col + str(current_row_number)].border = f_border
859
            ws[col + str(current_row_number)] = \
860
                associated_equipment['energy_category_names'][i] + " (" + associated_equipment['units'][i] + ")"
861
862
        end_col = chr(ord('B') + ca_len + 1)
863
        ws[end_col + str(current_row_number)].fill = table_fill
864
        ws[end_col + str(current_row_number)].font = name_font
865
        ws[end_col + str(current_row_number)].alignment = c_c_alignment
866
        ws[end_col + str(current_row_number)].border = f_border
867
        ws[end_col + str(current_row_number)] = _("Total") + " (" + reporting_period_data['units'][i] + ")"
0 ignored issues
show
The variable i does not seem to be defined in case the for loop on line 90 is not entered. Are you sure this can never be the case?
Loading history...
868
869
        associated_equipment_len = len(associated_equipment['associated_equipment_names_array'][0])
870
871
        for i in range(0, associated_equipment_len):
872
            current_row_number += 1
873
            row = str(current_row_number)
874
            value = Decimal(0.0)
875
876
            ws['B' + row].font = title_font
877
            ws['B' + row].alignment = c_c_alignment
878
            ws['B' + row] = associated_equipment['associated_equipment_names_array'][0][i]
879
            ws['B' + row].border = f_border
880
881
            for j in range(0, ca_len):
882
                col = chr(ord('C') + j)
883
                ws[col + row].font = title_font
884
                ws[col + row].alignment = c_c_alignment
885
                ws[col + row] = round2(associated_equipment['subtotals_array'][j][i], 2)
886
                value += round(associated_equipment['subtotals_array'][j][i], 2)
887
                ws[col + row].border = f_border
888
889
            end_col = chr(ord(col) + 1)
0 ignored issues
show
The variable col does not seem to be defined for all execution paths.
Loading history...
890
            ws[end_col + row].font = title_font
891
            ws[end_col + row].alignment = c_c_alignment
892
            ws[end_col + row] = round2(value, 2)
893
            ws[end_col + row].border = f_border
894
895
    ####################################################################################################################
896
    current_sheet_parameters_row_number = table_start_draw_flag + len(reporting_period_data['names']) * 6 + 1
897
    if 'parameters' not in report.keys() or \
898
            report['parameters'] is None or \
899
            'names' not in report['parameters'].keys() or \
900
            report['parameters']['names'] is None or \
901
            len(report['parameters']['names']) == 0 or \
902
            'timestamps' not in report['parameters'].keys() or \
903
            report['parameters']['timestamps'] is None or \
904
            len(report['parameters']['timestamps']) == 0 or \
905
            'values' not in report['parameters'].keys() or \
906
            report['parameters']['values'] is None or \
907
            len(report['parameters']['values']) == 0 or \
908
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
909
        pass
910
    else:
911
912
        ################################################################################################################
913
        # new worksheet
914
        ################################################################################################################
915
916
        parameters_data = report['parameters']
917
        parameters_names_len = len(parameters_data['names'])
918
919
        file_name = (re.sub(r'[^A-Z]', '', ws.title))+'_'
920
        parameters_ws = wb.create_sheet(file_name + _('Parameters'))
921
922
        parameters_timestamps_data_max_len = \
923
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
924
925
        # Row height
926
        parameters_ws.row_dimensions[1].height = 102
927
        for i in range(2, 7 + 1):
928
            parameters_ws.row_dimensions[i].height = 42
929
930
        for i in range(8, parameters_timestamps_data_max_len + 10):
931
            parameters_ws.row_dimensions[i].height = 60
932
933
        # Col width
934
        parameters_ws.column_dimensions['A'].width = 1.5
935
936
        parameters_ws.column_dimensions['B'].width = 25.0
937
938
        for i in range(3, 12 + parameters_names_len * 3):
939
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
940
941
        # Img
942
        img = Image("excelexporters/myems.png")
943
        parameters_ws.add_image(img, 'A1')
944
945
        # Title
946
        parameters_ws['B3'].alignment = b_r_alignment
947
        parameters_ws['B3'] = _('Name') + ':'
948
        parameters_ws['C3'].border = b_border
949
        parameters_ws['C3'].alignment = b_c_alignment
950
        parameters_ws['C3'] = name
951
952
        parameters_ws['D3'].alignment = b_r_alignment
953
        parameters_ws['D3'] = _('Period Type') + ':'
954
        parameters_ws['E3'].border = b_border
955
        parameters_ws['E3'].alignment = b_c_alignment
956
        parameters_ws['E3'] = period_type
957
958
        parameters_ws['B4'].alignment = b_r_alignment
959
        parameters_ws['B4'] = _('Reporting Start Datetime') + ':'
960
        parameters_ws['C4'].border = b_border
961
        parameters_ws['C4'].alignment = b_c_alignment
962
        parameters_ws['C4'] = reporting_start_datetime_local
963
964
        parameters_ws['D4'].alignment = b_r_alignment
965
        parameters_ws['D4'] = _('Reporting End Datetime') + ':'
966
        parameters_ws['E4'].border = b_border
967
        parameters_ws['E4'].alignment = b_c_alignment
968
        parameters_ws['E4'] = reporting_end_datetime_local
969
970
        parameters_ws_current_row_number = 6
971
972
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
973
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters')
974
975
        parameters_ws_current_row_number += 1
976
977
        parameters_table_start_row_number = parameters_ws_current_row_number
978
979
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
980
981
        parameters_ws_current_row_number += 1
982
983
        table_current_col_number = 2
984
985
        for i in range(0, parameters_names_len):
986
987
            if len(parameters_data['timestamps'][i]) == 0:
988
                continue
989
990
            col = format_cell.get_column_letter(table_current_col_number)
991
992
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
993
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
994
995
            col = format_cell.get_column_letter(table_current_col_number + 1)
996
997
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
998
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
999
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
1000
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
1001
            parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
1002
1003
            table_current_row_number = parameters_ws_current_row_number
1004
1005
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
1006
                col = format_cell.get_column_letter(table_current_col_number)
1007
1008
                parameters_ws[col + str(table_current_row_number)].border = f_border
1009
                parameters_ws[col + str(table_current_row_number)].font = title_font
1010
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
1011
                parameters_ws[col + str(table_current_row_number)] = value
1012
1013
                col = format_cell.get_column_letter(table_current_col_number + 1)
1014
1015
                parameters_ws[col + str(table_current_row_number)].border = f_border
1016
                parameters_ws[col + str(table_current_row_number)].font = title_font
1017
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
1018
                parameters_ws[col + str(table_current_row_number)] = round2(parameters_data['values'][i][j], 2)
1019
1020
                table_current_row_number += 1
1021
1022
            table_current_col_number = table_current_col_number + 3
1023
1024
        ########################################################
1025
        # parameters chart and parameters table
1026
        ########################################################
1027
1028
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
1029
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters')
1030
1031
        current_sheet_parameters_row_number += 1
1032
1033
        chart_start_row_number = current_sheet_parameters_row_number
1034
1035
        col_index = 0
1036
1037
        for i in range(0, parameters_names_len):
1038
1039
            if len(parameters_data['timestamps'][i]) == 0:
1040
                continue
1041
1042
            line = LineChart()
1043
            data_col = 3 + col_index * 3
1044
            labels_col = 2 + col_index * 3
1045
            col_index += 1
1046
            line.title = _('Parameters') + ' - ' + \
1047
                parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
1048
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
1049
                               max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
1050
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
1051
                                  max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
1052
            line.add_data(line_data, titles_from_data=True)
1053
            line.set_categories(labels)
1054
            line_data = line.series[0]
1055
            line_data.marker.symbol = "auto"
1056
            line_data.smooth = True
1057
            line.x_axis.crosses = 'min'
1058
            line.height = 8.25
1059
            line.width = 24
1060
            chart_col = 'B'
1061
            chart_cell = chart_col + str(chart_start_row_number)
1062
            chart_start_row_number += 6
1063
            ws.add_chart(line, chart_cell)
1064
1065
        current_sheet_parameters_row_number = chart_start_row_number
1066
1067
        current_sheet_parameters_row_number += 1
1068
    ####################################################################################################################
1069
    filename = str(uuid.uuid4()) + '.xlsx'
1070
    wb.save(filename)
1071
1072
    return filename
1073
1074
1075
def timestamps_data_all_equal_0(lists):
1076
    for i, value in enumerate(list(lists)):
1077
        if len(value) > 0:
1078
            return False
1079
1080
    return True
1081
1082
1083
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
1084
    max_len = 0
1085
    for i, value in enumerate(list(parameters_timestamps_lists)):
1086
        if len(value) > max_len:
1087
            max_len = len(value)
1088
1089
    return max_len
1090
1091
1092
def timestamps_data_not_equal_0(lists):
1093
    number = 0
1094
    for i, value in enumerate(list(lists)):
1095
        if len(value) > 0:
1096
            number += 1
1097
    return number
1098
1099
1100 View Code Duplication
def is_base_period_timestamp_exists(base_period_data):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
1101
    timestamps = base_period_data['timestamps']
1102
1103
    if len(timestamps) == 0:
1104
        return False
1105
1106
    for timestamp in timestamps:
1107
        if len(timestamp) > 0:
1108
            return True
1109
1110
    return False
1111