export()   B
last analyzed

Complexity

Conditions 5

Size

Total Lines 46
Code Lines 32

Duplication

Lines 46
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 32
dl 46
loc 46
rs 8.6453
c 0
b 0
f 0
cc 5
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
import base64
2
from core.utilities import get_translation
3
import os
4
import re
5
import uuid
6
import openpyxl.utils.cell as format_cell
7
from openpyxl import Workbook
8
from openpyxl.chart import LineChart, Reference
9
from openpyxl.drawing.image import Image
10
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
11
from core.utilities import round2
12
13
########################################################################################################################
14
# PROCEDURES
15
# Step 1: Validate the report data
16
# Step 2: Generate excel file
17
# Step 3: Encode the excel file to Base64
18
########################################################################################################################
19
20
21 View Code Duplication
def export(report,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
22
           name,
23
           base_period_start_datetime_local,
24
           base_period_end_datetime_local,
25
           reporting_start_datetime_local,
26
           reporting_end_datetime_local,
27
           period_type,
28
           language):
29
    ####################################################################################################################
30
    # Step 1: Validate the report data
31
    ####################################################################################################################
32
    if report is None:
33
        return None
34
    print(report)
35
36
    ####################################################################################################################
37
    # Step 2: Generate excel file from the report data
38
    ####################################################################################################################
39
    filename = generate_excel(report,
40
                              name,
41
                              base_period_start_datetime_local,
42
                              base_period_end_datetime_local,
43
                              reporting_start_datetime_local,
44
                              reporting_end_datetime_local,
45
                              period_type,
46
                              language)
47
    ####################################################################################################################
48
    # Step 3: Encode the excel file to Base64
49
    ####################################################################################################################
50
    binary_file_data = b''
51
    try:
52
        with open(filename, 'rb') as binary_file:
53
            binary_file_data = binary_file.read()
54
    except IOError as ex:
55
        print(str(ex))
56
57
    # Base64 encode the bytes
58
    base64_encoded_data = base64.b64encode(binary_file_data)
59
    # get the Base64 encoded data using human-readable characters.
60
    base64_message = base64_encoded_data.decode('utf-8')
61
    # delete the file from server
62
    try:
63
        os.remove(filename)
64
    except NotImplementedError as ex:
65
        print(str(ex))
66
    return base64_message
67
68
69
def generate_excel(report,
70
                   name,
71
                   base_period_start_datetime_local,
72
                   base_period_end_datetime_local,
73
                   reporting_start_datetime_local,
74
                   reporting_end_datetime_local,
75
                   period_type,
76
                   language):
77
78
    trans = get_translation(language)
79
    trans.install()
80
    _ = trans.gettext
81
82
    wb = Workbook()
83
    ws = wb.active
84
    ws.title = "CombinedEquipmentStatistics"
85
86
    # Row height
87
    ws.row_dimensions[1].height = 102
88
89
    for i in range(2, 2000 + 1):
90
        ws.row_dimensions[i].height = 42
91
92
    # Col width
93
    ws.column_dimensions['A'].width = 1.5
94
    ws.column_dimensions['B'].width = 25.0
95
96
    for i in range(ord('C'), ord('Z')):
97
        ws.column_dimensions[chr(i)].width = 15.0
98
99
    # Font
100
    name_font = Font(name='Arial', size=15, bold=True)
101
    title_font = Font(name='Arial', size=15, bold=True)
102
103
    table_fill = PatternFill(fill_type='solid', fgColor='90ee90')
104
    f_border = Border(left=Side(border_style='medium'),
105
                      right=Side(border_style='medium'),
106
                      bottom=Side(border_style='medium'),
107
                      top=Side(border_style='medium')
108
                      )
109
    b_border = Border(
110
        bottom=Side(border_style='medium'),
111
    )
112
113
    b_c_alignment = Alignment(vertical='bottom',
114
                              horizontal='center',
115
                              text_rotation=0,
116
                              wrap_text=True,
117
                              shrink_to_fit=False,
118
                              indent=0)
119
    c_c_alignment = Alignment(vertical='center',
120
                              horizontal='center',
121
                              text_rotation=0,
122
                              wrap_text=True,
123
                              shrink_to_fit=False,
124
                              indent=0)
125
    b_r_alignment = Alignment(vertical='bottom',
126
                              horizontal='right',
127
                              text_rotation=0,
128
                              wrap_text=True,
129
                              shrink_to_fit=False,
130
                              indent=0)
131
132
    # Img
133
    img = Image("excelexporters/myems.png")
134
    ws.add_image(img, 'A1')
135
136
    # Title
137
    ws['B3'].alignment = b_r_alignment
138
    ws['B3'] = _('Name') + ':'
139
    ws['C3'].border = b_border
140
    ws['C3'].alignment = b_c_alignment
141
    ws['C3'] = name
142
143
    ws['D3'].alignment = b_r_alignment
144
    ws['D3'] = _('Period Type') + ':'
145
    ws['E3'].border = b_border
146
    ws['E3'].alignment = b_c_alignment
147
    ws['E3'] = period_type
148
149
    ws['B4'].alignment = b_r_alignment
150
    ws['B4'] = _('Reporting Start Datetime') + ':'
151
    ws['C4'].border = b_border
152
    ws['C4'].alignment = b_c_alignment
153
    ws['C4'] = reporting_start_datetime_local
154
155
    ws['D4'].alignment = b_r_alignment
156
    ws['D4'] = _('Reporting End Datetime') + ':'
157
    ws['E4'].border = b_border
158
    ws['E4'].alignment = b_c_alignment
159
    ws['E4'] = reporting_end_datetime_local
160
161
    is_base_period_timestamp_exists_flag = is_base_period_timestamp_exists(report['base_period'])
162
163
    if is_base_period_timestamp_exists_flag:
164
        ws['B5'].alignment = b_r_alignment
165
        ws['B5'] = _('Base Period Start Datetime') + ':'
166
        ws['C5'].border = b_border
167
        ws['C5'].alignment = b_c_alignment
168
        ws['C5'] = base_period_start_datetime_local
169
170
        ws['D5'].alignment = b_r_alignment
171
        ws['D5'] = _('Base Period End Datetime') + ':'
172
        ws['E5'].border = b_border
173
        ws['E5'].alignment = b_c_alignment
174
        ws['E5'] = base_period_end_datetime_local
175
176
    if "reporting_period" not in report.keys() or \
177
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
178
        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...
179
        wb.save(filename)
180
181
        return filename
182
    ####################################################################################################################
183
    # First: Statistics
184
    # 7: title
185
    # 8: table title
186
    # 9~ca_len table_data
187
    ####################################################################################################################
188
    reporting_period_data = report['reporting_period']
189
190
    if "names" not in reporting_period_data.keys() or \
191
            reporting_period_data['names'] is None or \
192
            len(reporting_period_data['names']) == 0:
193
        filename = str(uuid.uuid4()) + '.xlsx'
194
        wb.save(filename)
195
        return filename
196
197
    ws['B7'].font = title_font
198
    ws['B7'] = name + ' ' + _('Statistics')
199
200
    category = reporting_period_data['names']
201
202
    # table_title
203
    ws['B8'].fill = table_fill
204
    ws['B8'].font = title_font
205
    ws['B8'].alignment = c_c_alignment
206
    ws['B8'] = _('Reporting Period')
207
    ws['B8'].border = f_border
208
209
    ws['C8'].font = title_font
210
    ws['C8'].alignment = c_c_alignment
211
    ws['C8'] = _('Arithmetic Mean')
212
    ws['C8'].border = f_border
213
214
    ws['D8'].font = title_font
215
    ws['D8'].alignment = c_c_alignment
216
    ws['D8'] = _('Median (Middle Value)')
217
    ws['D8'].border = f_border
218
219
    ws['E8'].font = title_font
220
    ws['E8'].alignment = c_c_alignment
221
    ws['E8'] = _('Minimum Value')
222
    ws['E8'].border = f_border
223
224
    ws['F8'].font = title_font
225
    ws['F8'].alignment = c_c_alignment
226
    ws['F8'] = _('Maximum Value')
227
    ws['F8'].border = f_border
228
229
    ws['G8'].font = title_font
230
    ws['G8'].alignment = c_c_alignment
231
    ws['G8'] = _('Sample Standard Deviation')
232
    ws['G8'].border = f_border
233
234
    ws['H8'].font = title_font
235
    ws['H8'].alignment = c_c_alignment
236
    ws['H8'] = _('Sample Variance')
237
    ws['H8'].border = f_border
238
239
    # table_data
240
241
    for i, value in enumerate(category):
242
        row = i * 2 + 9
243
        ws['B' + str(row)].font = name_font
244
        ws['B' + str(row)].alignment = c_c_alignment
245
        ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + " )"
246
        ws['B' + str(row)].border = f_border
247
248
        ws['B' + str(row + 1)].font = name_font
249
        ws['B' + str(row + 1)].alignment = c_c_alignment
250
        ws['B' + str(row + 1)] = _('Increment Rate')
251
        ws['B' + str(row + 1)].border = f_border
252
253
        ws['C' + str(row)].font = name_font
254
        ws['C' + str(row)].alignment = c_c_alignment
255
        ws['C' + str(row)] = reporting_period_data['means'][i] \
256
            if reporting_period_data['means'][i] is not None else ''
257
        ws['C' + str(row)].border = f_border
258
        ws['C' + str(row)].number_format = '0.00'
259
260
        ws['C' + str(row + 1)].font = name_font
261
        ws['C' + str(row + 1)].alignment = c_c_alignment
262
        ws['C' + str(row + 1)] = str(round2(reporting_period_data['means_increment_rate'][i] * 100, 2)) + "%" \
263
            if reporting_period_data['means_increment_rate'][i] is not None else '0.00%'
264
        ws['C' + str(row + 1)].border = f_border
265
266
        ws['D' + str(row)].font = name_font
267
        ws['D' + str(row)].alignment = c_c_alignment
268
        ws['D' + str(row)] = reporting_period_data['medians'][i] \
269
            if reporting_period_data['medians'][i] is not None else ''
270
        ws['D' + str(row)].border = f_border
271
        ws['D' + str(row)].number_format = '0.00'
272
273
        ws['D' + str(row + 1)].font = name_font
274
        ws['D' + str(row + 1)].alignment = c_c_alignment
275
        ws['D' + str(row + 1)] = str(round2(reporting_period_data['medians_increment_rate'][i] * 100, 2)) + "%" \
276
            if reporting_period_data['medians_increment_rate'][i] is not None else '0.00%'
277
        ws['D' + str(row + 1)].border = f_border
278
279
        ws['E' + str(row)].font = name_font
280
        ws['E' + str(row)].alignment = c_c_alignment
281
        ws['E' + str(row)] = reporting_period_data['minimums'][i] \
282
            if reporting_period_data['minimums'][i] is not None else ''
283
        ws['E' + str(row)].border = f_border
284
        ws['E' + str(row)].number_format = '0.00'
285
286
        ws['E' + str(row + 1)].font = name_font
287
        ws['E' + str(row + 1)].alignment = c_c_alignment
288
        ws['E' + str(row + 1)] = str(round2(reporting_period_data['minimums_increment_rate'][i] * 100, 2)) + "%" \
289
            if reporting_period_data['minimums_increment_rate'][i] is not None else '0.00%'
290
        ws['E' + str(row + 1)].border = f_border
291
292
        ws['F' + str(row)].font = name_font
293
        ws['F' + str(row)].alignment = c_c_alignment
294
        ws['F' + str(row)] = reporting_period_data['maximums'][i] \
295
            if reporting_period_data['maximums'][i] is not None else ''
296
        ws['F' + str(row)].border = f_border
297
        ws['F' + str(row)].number_format = '0.00'
298
299
        ws['F' + str(row + 1)].font = name_font
300
        ws['F' + str(row + 1)].alignment = c_c_alignment
301
        ws['F' + str(row + 1)] = str(round2(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
302
            if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%'
303
        ws['F' + str(row + 1)].border = f_border
304
305
        ws['G' + str(row)].font = name_font
306
        ws['G' + str(row)].alignment = c_c_alignment
307
        ws['G' + str(row)] = reporting_period_data['stdevs'][i] \
308
            if reporting_period_data['stdevs'][i] is not None else ''
309
        ws['G' + str(row)].border = f_border
310
        ws['G' + str(row)].number_format = '0.00'
311
312
        ws['G' + str(row + 1)].font = name_font
313
        ws['G' + str(row + 1)].alignment = c_c_alignment
314
        ws['G' + str(row + 1)] = str(round2(reporting_period_data['stdevs_increment_rate'][i] * 100, 2)) + "%" \
315
            if reporting_period_data['stdevs_increment_rate'][i] is not None else '0.00%'
316
        ws['G' + str(row + 1)].border = f_border
317
318
        ws['H' + str(row)].font = name_font
319
        ws['H' + str(row)].alignment = c_c_alignment
320
        ws['H' + str(row)] = reporting_period_data['variances'][i] \
321
            if reporting_period_data['variances'][i] is not None else ''
322
        ws['H' + str(row)].border = f_border
323
        ws['H' + str(row)].number_format = '0.00'
324
325
        ws['H' + str(row + 1)].font = name_font
326
        ws['H' + str(row + 1)].alignment = c_c_alignment
327
        ws['H' + str(row + 1)] = str(round2(reporting_period_data['variances_increment_rate'][i] * 100, 2)) + "%" \
328
            if reporting_period_data['variances_increment_rate'][i] is not None else '0.00%'
329
        ws['H' + str(row + 1)].border = f_border
330
331
    ####################################################################################################################
332
    # Second: Detailed Data
333
    # analysis_end_row_number+1~ analysis_end_row_number+1+line_charts_row_number+: line
334
    # detailed_start_row_number~ : the detailed data table
335
    ####################################################################################################################
336
    current_row_number = len(category) * 2 + 9 + 1
337
338
    table_start_draw_flag = current_row_number + 1
339
    if "timestamps" not in reporting_period_data.keys() or \
340
            reporting_period_data['timestamps'] is None or \
341
            len(reporting_period_data['timestamps']) == 0:
342
        pass
343
    else:
344
        if not is_base_period_timestamp_exists_flag:
345
            reporting_period_data = report['reporting_period']
346
            times = reporting_period_data['timestamps']
347
            ca_len = len(report['reporting_period']['names'])
348
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
349
            ws['B' + str(current_row_number)].font = title_font
350
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
351
352
            current_row_number += 1
353
            # 1: Stand for blank line  2: Stand for title
354
            current_row_number += ca_len * 6 + real_timestamps_len * 6 + 1 + 2
355
            table_start_row_number = current_row_number
356
357
            time = times[0]
358
            has_data = False
359
360
            if len(time) > 0:
361
                has_data = True
362
363
            if has_data:
364
365
                ws.row_dimensions[current_row_number].height = 60
366
                current_col_number = 2
367
                col = format_cell.get_column_letter(current_col_number)
368
                ws[col + str(current_row_number)].fill = table_fill
369
                ws[col + str(current_row_number)].font = title_font
370
                ws[col + str(current_row_number)].border = f_border
371
                ws[col + str(current_row_number)].alignment = c_c_alignment
372
                ws[col + str(current_row_number)] = _('Datetime')
373
374
                for i in range(0, ca_len):
375
                    current_col_number += 1
376
                    col = format_cell.get_column_letter(current_col_number)
377
378
                    ws[col + str(current_row_number)].fill = table_fill
379
                    ws[col + str(current_row_number)].font = title_font
380
                    ws[col + str(current_row_number)].alignment = c_c_alignment
381
                    ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
382
                        " (" + reporting_period_data['units'][i] + ")"
383
                    ws[col + str(current_row_number)].border = f_border
384
385
                current_row_number += 1
386
387
                for i in range(0, len(time)):
388
                    current_col_number = 2
389
                    col = format_cell.get_column_letter(current_col_number)
390
                    ws[col + str(current_row_number)].font = title_font
391
                    ws[col + str(current_row_number)].alignment = c_c_alignment
392
                    ws[col + str(current_row_number)] = time[i]
393
                    ws[col + str(current_row_number)].border = f_border
394
395
                    for j in range(0, ca_len):
396
                        current_col_number += 1
397
                        col = format_cell.get_column_letter(current_col_number)
398
399
                        ws[col + str(current_row_number)].font = title_font
400
                        ws[col + str(current_row_number)].alignment = c_c_alignment
401
                        ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2)
402
                        ws[col + str(current_row_number)].border = f_border
403
404
                    current_row_number += 1
405
406
                table_end_row_number = current_row_number - 1
407
408
                current_col_number = 2
409
                col = format_cell.get_column_letter(current_col_number)
410
                ws[col + str(current_row_number)].font = title_font
411
                ws[col + str(current_row_number)].alignment = c_c_alignment
412
                ws[col + str(current_row_number)] = _('Subtotal')
413
                ws[col + str(current_row_number)].border = f_border
414
415
                for i in range(0, ca_len):
416
                    current_col_number += 1
417
                    col = format_cell.get_column_letter(current_col_number)
418
419
                    ws[col + str(current_row_number)].font = title_font
420
                    ws[col + str(current_row_number)].alignment = c_c_alignment
421
                    ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2)
422
                    ws[col + str(current_row_number)].border = f_border
423
424
                    # line
425
                    line = LineChart()
426
                    line.title = _('Reporting Period Consumption') + ' - ' \
427
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
428
                    labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
429
                    line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
430
                                          max_row=table_end_row_number)
431
                    line.add_data(line_data, titles_from_data=True)
432
                    line.set_categories(labels)
433
                    line_data = line.series[0]
434
                    line_data.marker.symbol = "auto"
435
                    line_data.smooth = True
436
                    line.x_axis.crosses = 'min'
437
                    line.height = 8.25
438
                    line.width = 24
439
                    chart_col = 'B'
440
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
441
                    ws.add_chart(line, chart_cell)
442
443
                current_row_number += 2
444
        else:
445
            base_period_data = report['base_period']
446
            reporting_period_data = report['reporting_period']
447
            base_period_timestamps = base_period_data['timestamps']
448
            reporting_period_timestamps = reporting_period_data['timestamps']
449
            # Tip:
450
            #     base_period_data['names'] == reporting_period_data['names']
451
            #     base_period_data['units'] == reporting_period_data['units']
452
            base_period_data_ca_len = len(base_period_data['names'])
453
            reporting_period_data_ca_len = len(reporting_period_data['names'])
454
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
455
            ws['B' + str(current_row_number)].font = title_font
456
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
457
458
            current_row_number += 1
459
            # 1: Stand for blank line  2: Stand for title
460
            current_row_number += reporting_period_data_ca_len * 6 + real_timestamps_len * 6 + 1 + 2
461
            table_start_row_number = current_row_number
462
463
            has_data = False
464
465
            if len(base_period_timestamps[0]) or len(reporting_period_timestamps[0]) > 0:
466
                has_data = True
467
468
            if has_data:
469
                ws.row_dimensions[current_row_number].height = 60
470
                current_col_number = 2
471
                col = format_cell.get_column_letter(current_col_number)
472
                ws[col + str(current_row_number)].fill = table_fill
473
                ws[col + str(current_row_number)].font = title_font
474
                ws[col + str(current_row_number)].border = f_border
475
                ws[col + str(current_row_number)].alignment = c_c_alignment
476
                ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime')
477
478
                for i in range(0, base_period_data_ca_len):
479
                    current_col_number += 1
480
                    col = format_cell.get_column_letter(current_col_number)
481
482
                    ws[col + str(current_row_number)].fill = table_fill
483
                    ws[col + str(current_row_number)].font = title_font
484
                    ws[col + str(current_row_number)].alignment = c_c_alignment
485
                    ws[col + str(current_row_number)] = _('Base Period') + " - " + base_period_data['names'][i] + \
486
                        " (" + base_period_data['units'][i] + ")"
487
                    ws[col + str(current_row_number)].border = f_border
488
                current_col_number += 1
489
                col = format_cell.get_column_letter(current_col_number)
490
491
                ws[col + str(current_row_number)].fill = table_fill
492
                ws[col + str(current_row_number)].font = title_font
493
                ws[col + str(current_row_number)].border = f_border
494
                ws[col + str(current_row_number)].alignment = c_c_alignment
495
                ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime')
496
497
                for i in range(0, reporting_period_data_ca_len):
498
                    current_col_number += 1
499
                    col = format_cell.get_column_letter(current_col_number)
500
                    ws[col + str(current_row_number)].fill = table_fill
501
                    ws[col + str(current_row_number)].font = title_font
502
                    ws[col + str(current_row_number)].alignment = c_c_alignment
503
                    ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
504
                        + reporting_period_data['names'][i] + " (" + \
505
                        reporting_period_data['units'][i] + ")"
506
                    ws[col + str(current_row_number)].border = f_border
507
508
                current_row_number += 1
509
510
                max_timestamps_len = len(base_period_timestamps[0]) \
511
                    if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \
512
                    else len(reporting_period_timestamps[0])
513
514
                for i in range(0, max_timestamps_len):
515
                    current_col_number = 2
516
                    col = format_cell.get_column_letter(current_col_number)
517
                    ws[col + str(current_row_number)].font = title_font
518
                    ws[col + str(current_row_number)].alignment = c_c_alignment
519
                    ws[col + str(current_row_number)] = base_period_timestamps[0][i] \
520
                        if i < len(base_period_timestamps[0]) else None
521
                    ws[col + str(current_row_number)].border = f_border
522
523
                    for j in range(0, base_period_data_ca_len):
524
                        current_col_number += 1
525
                        col = format_cell.get_column_letter(current_col_number)
526
527
                        ws[col + str(current_row_number)].font = title_font
528
                        ws[col + str(current_row_number)].alignment = c_c_alignment
529
                        ws[col + str(current_row_number)] = round2(base_period_data['values'][j][i], 2) \
530
                            if i < len(base_period_data['values'][j]) else None
531
                        ws[col + str(current_row_number)].border = f_border
532
                    current_col_number += 1
533
                    col = format_cell.get_column_letter(current_col_number)
534
535
                    ws[col + str(current_row_number)].font = title_font
536
                    ws[col + str(current_row_number)].alignment = c_c_alignment
537
                    ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \
538
                        if i < len(reporting_period_timestamps[0]) else None
539
                    ws[col + str(current_row_number)].border = f_border
540
541
                    for j in range(0, reporting_period_data_ca_len):
542
                        current_col_number += 1
543
                        col = format_cell.get_column_letter(current_col_number)
544
545
                        ws[col + str(current_row_number)].font = title_font
546
                        ws[col + str(current_row_number)].alignment = c_c_alignment
547
                        ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2) \
548
                            if i < len(reporting_period_data['values'][j]) else None
549
                        ws[col + str(current_row_number)].border = f_border
550
551
                    current_row_number += 1
552
553
                current_col_number = 2
554
                col = format_cell.get_column_letter(current_col_number)
555
                ws[col + str(current_row_number)].font = title_font
556
                ws[col + str(current_row_number)].alignment = c_c_alignment
557
                ws[col + str(current_row_number)] = _('Subtotal')
558
                ws[col + str(current_row_number)].border = f_border
559
560
                for i in range(0, base_period_data_ca_len):
561
                    current_col_number += 1
562
                    col = format_cell.get_column_letter(current_col_number)
563
                    ws[col + str(current_row_number)].font = title_font
564
                    ws[col + str(current_row_number)].alignment = c_c_alignment
565
                    ws[col + str(current_row_number)] = round2(base_period_data['subtotals'][i], 2)
566
                    ws[col + str(current_row_number)].border = f_border
567
568
                current_col_number += 1
569
                col = format_cell.get_column_letter(current_col_number)
570
571
                ws[col + str(current_row_number)].font = title_font
572
                ws[col + str(current_row_number)].alignment = c_c_alignment
573
                ws[col + str(current_row_number)] = _('Subtotal')
574
                ws[col + str(current_row_number)].border = f_border
575
576
                for i in range(0, reporting_period_data_ca_len):
577
                    current_col_number += 1
578
                    col = format_cell.get_column_letter(current_col_number)
579
                    ws[col + str(current_row_number)].font = title_font
580
                    ws[col + str(current_row_number)].alignment = c_c_alignment
581
                    ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2)
582
                    ws[col + str(current_row_number)].border = f_border
583
584
                for i in range(0, reporting_period_data_ca_len):
585
                    # line
586
                    line = LineChart()
587
                    line.title = _('Base Period Consumption') + ' / ' \
588
                        + _('Reporting Period Consumption') + ' - ' \
589
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
590
                    labels = Reference(ws, min_col=2 + base_period_data_ca_len + 1,
591
                                       min_row=table_start_row_number + 1,
592
                                       max_row=table_start_row_number + len(reporting_period_timestamps[0]))
593
                    base_line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
594
                                               max_row=table_start_row_number + len(reporting_period_timestamps[0]))
595
                    reporting_line_data = Reference(ws, min_col=3 + base_period_data_ca_len + 1 + i,
596
                                                    min_row=table_start_row_number,
597
                                                    max_row=table_start_row_number
598
                                                    + len(reporting_period_timestamps[0]))
599
                    line.add_data(base_line_data, titles_from_data=True)
600
                    line.add_data(reporting_line_data, titles_from_data=True)
601
                    line.set_categories(labels)
602
                    for j in range(len(line.series)):
603
                        line.series[j].marker.symbol = "auto"
604
                        line.series[j].smooth = True
605
                    line.x_axis.crosses = 'min'
606
                    line.height = 8.25
607
                    line.width = 24
608
                    chart_col = 'B'
609
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
610
                    ws.add_chart(line, chart_cell)
611
612
                current_row_number += 2
613
614
    ####################################################################################################################
615 View Code Duplication
    if "associated_equipment" not in report.keys() or \
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
616
            "energy_category_names" not in report['associated_equipment'].keys() or \
617
            len(report['associated_equipment']["energy_category_names"]) == 0 \
618
            or 'associated_equipment_names_array' not in report['associated_equipment'].keys() \
619
            or report['associated_equipment']['associated_equipment_names_array'] is None \
620
            or len(report['associated_equipment']['associated_equipment_names_array']) == 0 \
621
            or len(report['associated_equipment']['associated_equipment_names_array'][0]) == 0:
622
        pass
623
    else:
624
        associated_equipment = report['associated_equipment']
625
626
        ws['B' + str(current_row_number)].font = title_font
627
        ws['B' + str(current_row_number)] = name + ' ' + _('Associated Equipment Data')
628
629
        current_row_number += 1
630
631
        ws.row_dimensions[current_row_number].height = 60
632
        ws['B' + str(current_row_number)].fill = table_fill
633
        ws['B' + str(current_row_number)].font = name_font
634
        ws['B' + str(current_row_number)].alignment = c_c_alignment
635
        ws['B' + str(current_row_number)].border = f_border
636
        ws['B' + str(current_row_number)] = _('Associated Equipment')
637
        ca_len = len(associated_equipment['energy_category_names'])
638
        for i in range(0, ca_len):
639
            row = chr(ord('C') + i)
640
            ws[row + str(current_row_number)].fill = table_fill
641
            ws[row + str(current_row_number)].font = name_font
642
            ws[row + str(current_row_number)].alignment = c_c_alignment
643
            ws[row + str(current_row_number)].border = f_border
644
            ws[row + str(current_row_number)] = \
645
                associated_equipment['energy_category_names'][i] + " (" + associated_equipment['units'][i] + ")"
646
647
        associated_equipment_len = len(associated_equipment['associated_equipment_names_array'][0])
648
        for i in range(0, associated_equipment_len):
649
            current_row_number += 1
650
            row = str(current_row_number)
651
652
            ws['B' + row].font = title_font
653
            ws['B' + row].alignment = c_c_alignment
654
            ws['B' + row] = associated_equipment['associated_equipment_names_array'][0][i]
655
            ws['B' + row].border = f_border
656
            for j in range(0, ca_len):
657
                col = chr(ord('C') + j)
658
                ws[col + row].font = title_font
659
                ws[col + row].alignment = c_c_alignment
660
                ws[col + row] = round2(associated_equipment['subtotals_array'][j][i], 2) \
661
                    if associated_equipment['subtotals_array'][j][i] is not None else ''
662
                ws[col + row].border = f_border
663
    ####################################################################################################################
664
    current_sheet_parameters_row_number = table_start_draw_flag + len(reporting_period_data['names']) * 6 + 1
665
    if 'parameters' not in report.keys() or \
666
            report['parameters'] is None or \
667
            'names' not in report['parameters'].keys() or \
668
            report['parameters']['names'] is None or \
669
            len(report['parameters']['names']) == 0 or \
670
            'timestamps' not in report['parameters'].keys() or \
671
            report['parameters']['timestamps'] is None or \
672
            len(report['parameters']['timestamps']) == 0 or \
673
            'values' not in report['parameters'].keys() or \
674
            report['parameters']['values'] is None or \
675
            len(report['parameters']['values']) == 0 or \
676
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
677
        pass
678
    else:
679
        ################################################################################################################
680
        # new worksheet
681
        ################################################################################################################
682
683
        parameters_data = report['parameters']
684
        parameters_names_len = len(parameters_data['names'])
685
686
        file_name = (re.sub(r'[^A-Z]', '', ws.title))+'tatistics_'
687
        parameters_ws = wb.create_sheet(file_name + _('Parameters'))
688
689
        parameters_timestamps_data_max_len = \
690
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
691
692
        # Row height
693
        parameters_ws.row_dimensions[1].height = 102
694
        for i in range(2, 7 + 1):
695
            parameters_ws.row_dimensions[i].height = 42
696
697
        for i in range(8, parameters_timestamps_data_max_len + 10):
698
            parameters_ws.row_dimensions[i].height = 60
699
700
        # Col width
701
        parameters_ws.column_dimensions['A'].width = 1.5
702
703
        parameters_ws.column_dimensions['B'].width = 25.0
704
705
        for i in range(3, 12+parameters_names_len*3):
706
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
707
708
        # Img
709
        img = Image("excelexporters/myems.png")
710
        parameters_ws.add_image(img, 'A1')
711
712
        # Title
713
        parameters_ws['B3'].alignment = b_r_alignment
714
        parameters_ws['B3'] = _('Name') + ':'
715
        parameters_ws['C3'].border = b_border
716
        parameters_ws['C3'].alignment = b_c_alignment
717
        parameters_ws['C3'] = name
718
719
        parameters_ws['D3'].alignment = b_r_alignment
720
        parameters_ws['D3'] = _('Period Type') + ':'
721
        parameters_ws['E3'].border = b_border
722
        parameters_ws['E3'].alignment = b_c_alignment
723
        parameters_ws['E3'] = period_type
724
725
        parameters_ws['B4'].alignment = b_r_alignment
726
        parameters_ws['B4'] = _('Reporting Start Datetime') + ':'
727
        parameters_ws['C4'].border = b_border
728
        parameters_ws['C4'].alignment = b_c_alignment
729
        parameters_ws['C4'] = reporting_start_datetime_local
730
731
        parameters_ws['D4'].alignment = b_r_alignment
732
        parameters_ws['D4'] = _('Reporting End Datetime') + ':'
733
        parameters_ws['E4'].border = b_border
734
        parameters_ws['E4'].alignment = b_c_alignment
735
        parameters_ws['E4'] = reporting_end_datetime_local
736
737
        parameters_ws_current_row_number = 6
738
739
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
740
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters')
741
742
        parameters_ws_current_row_number += 1
743
744
        parameters_table_start_row_number = parameters_ws_current_row_number
745
746
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
747
748
        parameters_ws_current_row_number += 1
749
750
        table_current_col_number = 2
751
752
        for i in range(0, parameters_names_len):
753
754
            if len(parameters_data['timestamps'][i]) == 0:
755
                continue
756
757
            col = format_cell.get_column_letter(table_current_col_number)
758
759
            parameters_ws[col + str(parameters_ws_current_row_number-1)].fill = table_fill
760
            parameters_ws[col + str(parameters_ws_current_row_number-1)].border = f_border
761
762
            col = format_cell.get_column_letter(table_current_col_number + 1)
763
764
            parameters_ws[col + str(parameters_ws_current_row_number-1)].fill = table_fill
765
            parameters_ws[col + str(parameters_ws_current_row_number-1)].border = f_border
766
            parameters_ws[col + str(parameters_ws_current_row_number-1)].font = name_font
767
            parameters_ws[col + str(parameters_ws_current_row_number-1)].alignment = c_c_alignment
768
            parameters_ws[col + str(parameters_ws_current_row_number-1)] = parameters_data['names'][i]
769
770
            table_current_row_number = parameters_ws_current_row_number
771
772
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
773
                col = format_cell.get_column_letter(table_current_col_number)
774
775
                parameters_ws[col + str(table_current_row_number)].border = f_border
776
                parameters_ws[col + str(table_current_row_number)].font = title_font
777
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
778
                parameters_ws[col + str(table_current_row_number)] = value
779
780
                col = format_cell.get_column_letter(table_current_col_number + 1)
781
782
                parameters_ws[col + str(table_current_row_number)].border = f_border
783
                parameters_ws[col + str(table_current_row_number)].font = title_font
784
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
785
                parameters_ws[col + str(table_current_row_number)] = round2(parameters_data['values'][i][j], 2)
786
787
                table_current_row_number += 1
788
789
            table_current_col_number = table_current_col_number + 3
790
791
        ################################################################################################################
792
        # parameters chart and parameters table
793
        ################################################################################################################
794
795
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
796
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters')
797
798
        current_sheet_parameters_row_number += 1
799
800
        chart_start_row_number = current_sheet_parameters_row_number
801
802
        col_index = 0
803
804
        for i in range(0, parameters_names_len):
805
806
            if len(parameters_data['timestamps'][i]) == 0:
807
                continue
808
809
            line = LineChart()
810
            data_col = 3+col_index*3
811
            labels_col = 2+col_index*3
812
            col_index += 1
813
            line.title = _('Parameters') + ' - ' + \
814
                parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
815
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
816
                               max_row=(len(parameters_data['timestamps'][i])+parameters_table_start_row_number))
817
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
818
                                  max_row=(len(parameters_data['timestamps'][i])+parameters_table_start_row_number))
819
            line.add_data(line_data, titles_from_data=True)
820
            line.set_categories(labels)
821
            line_data = line.series[0]
822
            line_data.marker.symbol = "auto"
823
            line_data.smooth = True
824
            line.x_axis.crosses = 'min'
825
            line.height = 8.25
826
            line.width = 24
827
            chart_col = 'B'
828
            chart_cell = chart_col + str(chart_start_row_number)
829
            chart_start_row_number += 6
830
            ws.add_chart(line, chart_cell)
831
832
        current_sheet_parameters_row_number = chart_start_row_number
833
834
        current_sheet_parameters_row_number += 1
835
    ####################################################################################################################
836
    filename = str(uuid.uuid4()) + '.xlsx'
837
    wb.save(filename)
838
839
    return filename
840
841
842
def timestamps_data_all_equal_0(lists):
843
    for i, value in enumerate(list(lists)):
844
        if len(value) > 0:
845
            return False
846
847
    return True
848
849
850
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
851
    max_len = 0
852
    for i, value in enumerate(list(parameters_timestamps_lists)):
853
        if len(value) > max_len:
854
            max_len = len(value)
855
856
    return max_len
857
858
859
def timestamps_data_not_equal_0(lists):
860
    number = 0
861
    for i, value in enumerate(list(lists)):
862
        if len(value) > 0:
863
            number += 1
864
    return number
865
866
867 View Code Duplication
def is_base_period_timestamp_exists(base_period_data):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
868
    timestamps = base_period_data['timestamps']
869
870
    if len(timestamps) == 0:
871
        return False
872
873
    for timestamp in timestamps:
874
        if len(timestamp) > 0:
875
            return True
876
877
    return False
878