Passed
Push — master ( 02289f...d6a19b )
by Guangyu
08:58 queued 15s
created

excelexporters.spaceefficiency   F

Complexity

Total Complexity 94

Size/Duplication

Total Lines 799
Duplicated Lines 29.16 %

Importance

Changes 0
Metric Value
wmc 94
eloc 593
dl 233
loc 799
rs 2
c 0
b 0
f 0

6 Functions

Rating   Name   Duplication   Size   Complexity  
A is_base_period_timestamp_exists() 11 11 4
B export() 46 46 5
A timestamps_data_not_equal_0() 0 6 3
F generate_excel() 176 690 76
A get_parameters_timestamps_lists_max_len() 0 7 3
A timestamps_data_all_equal_0() 0 6 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like excelexporters.spaceefficiency often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import base64
2
import gettext
3
import os
4
import re
5
import uuid
6
7
import openpyxl.utils.cell as format_cell
8
from openpyxl import Workbook
9
from openpyxl.chart import 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
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
Duplication introduced by
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
def generate_excel(report,
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
    locale_path = './i18n/'
80
    if language == 'zh_CN':
81
        trans = gettext.translation('myems', locale_path, languages=['zh_CN'])
82
    elif language == 'de':
83
        trans = gettext.translation('myems', locale_path, languages=['de'])
84
    elif language == 'en':
85
        trans = gettext.translation('myems', locale_path, languages=['en'])
86
    else:
87
        trans = gettext.translation('myems', locale_path, languages=['en'])
88
    trans.install()
89
    _ = trans.gettext
90
    wb = Workbook()
91
    ws = wb.active
92
    ws.title = "SpaceEfficiency"
93
94
    # Row height
95
    ws.row_dimensions[1].height = 102
96
    for i in range(2, 2000 + 1):
97
        ws.row_dimensions[i].height = 42
98
99
    # Col width
100
    ws.column_dimensions['A'].width = 1.5
101
102
    ws.column_dimensions['B'].width = 25.0
103
104
    for i in range(ord('C'), ord('Z')):
105
        ws.column_dimensions[chr(i)].width = 15.0
106
107
    # Font
108
    name_font = Font(name='Arial', size=15, bold=True)
109
    title_font = Font(name='Arial', size=15, bold=True)
110
111
    table_fill = PatternFill(fill_type='solid', fgColor='90ee90')
112
    f_border = Border(left=Side(border_style='medium'),
113
                      right=Side(border_style='medium'),
114
                      bottom=Side(border_style='medium'),
115
                      top=Side(border_style='medium')
116
                      )
117
    b_border = Border(
118
        bottom=Side(border_style='medium'),
119
    )
120
121
    b_c_alignment = Alignment(vertical='bottom',
122
                              horizontal='center',
123
                              text_rotation=0,
124
                              wrap_text=True,
125
                              shrink_to_fit=False,
126
                              indent=0)
127
    c_c_alignment = Alignment(vertical='center',
128
                              horizontal='center',
129
                              text_rotation=0,
130
                              wrap_text=True,
131
                              shrink_to_fit=False,
132
                              indent=0)
133
    b_r_alignment = Alignment(vertical='bottom',
134
                              horizontal='right',
135
                              text_rotation=0,
136
                              wrap_text=True,
137
                              shrink_to_fit=False,
138
                              indent=0)
139
    # Img
140
    img = Image("excelexporters/myems.png")
141
    ws.add_image(img, 'A1')
142
143
    # Title
144
    ws['B3'].alignment = b_r_alignment
145
    ws['B3'] = _('Name') + ':'
146
    ws['C3'].border = b_border
147
    ws['C3'].alignment = b_c_alignment
148
    ws['C3'] = name
149
150
    ws['D3'].alignment = b_r_alignment
151
    ws['D3'] = _('Period Type') + ':'
152
    ws['E3'].border = b_border
153
    ws['E3'].alignment = b_c_alignment
154
    ws['E3'] = period_type
155
156
    ws['B4'].alignment = b_r_alignment
157
    ws['B4'] = _('Reporting Start Datetime') + ':'
158
    ws['C4'].border = b_border
159
    ws['C4'].alignment = b_c_alignment
160
    ws['C4'] = reporting_start_datetime_local
161
162
    ws['D4'].alignment = b_r_alignment
163
    ws['D4'] = _('Reporting End Datetime') + ':'
164
    ws['E4'].border = b_border
165
    ws['E4'].alignment = b_c_alignment
166
    ws['E4'] = reporting_end_datetime_local
167
168
    is_base_period_timestamp_exists_flag = is_base_period_timestamp_exists(report['base_period_efficiency'])
169
170
    if is_base_period_timestamp_exists_flag:
171
        ws['B5'].alignment = b_r_alignment
172
        ws['B5'] = _('Base Period Start Datetime') + ':'
173
        ws['C5'].border = b_border
174
        ws['C5'].alignment = b_c_alignment
175
        ws['C5'] = base_period_start_datetime_local
176
177
        ws['D5'].alignment = b_r_alignment
178
        ws['D5'] = _('Base Period End Datetime') + ':'
179
        ws['E5'].border = b_border
180
        ws['E5'].alignment = b_c_alignment
181
        ws['E5'] = base_period_end_datetime_local
182
183
    if "reporting_period_efficiency" not in report.keys() or \
184
            "names" not in report['reporting_period_efficiency'].keys() or len(
185
            report['reporting_period_efficiency']['names']) == 0:
186
        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...
187
        wb.save(filename)
188
189
        return filename
190
191
    ####################################################################################################################
192
    current_row_number = 7
193
    reporting_period_data = report['reporting_period_efficiency']
194
    if "names" not in reporting_period_data.keys() or \
195
            reporting_period_data['names'] is None or \
196
            len(reporting_period_data['names']) == 0:
197
        pass
198
    else:
199
        ws['B' + str(current_row_number)].font = title_font
200
        ws['B' + str(current_row_number)] = name + ' ' + _('Reporting Period Cumulative Efficiency')
201
202
        current_row_number += 1
203
204
        category = reporting_period_data['names']
205
        ca_len = len(category)
206
207
        ws.row_dimensions[current_row_number].height = 80
208
        ws['B' + str(current_row_number)].fill = table_fill
209
        ws['B' + str(current_row_number)].border = f_border
210
211
        col = 'C'
212
213
        for i in range(0, ca_len):
214
            ws[col + str(current_row_number)].fill = table_fill
215
            ws[col + str(current_row_number)].font = name_font
216
            ws[col + str(current_row_number)].alignment = c_c_alignment
217
            ws[col + str(current_row_number)].border = f_border
218
            ws[col + str(current_row_number)] = \
219
                reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
220
221
            col = chr(ord(col) + 1)
222
223
        current_row_number += 1
224
225
        ws['B' + str(current_row_number)].font = title_font
226
        ws['B' + str(current_row_number)].alignment = c_c_alignment
227
        ws['B' + str(current_row_number)].border = f_border
228
        ws['B' + str(current_row_number)] = _('Cumulative Efficiency')
229
230
        col = 'C'
231
232
        for i in range(0, ca_len):
233
            ws[col + str(current_row_number)].font = name_font
234
            ws[col + str(current_row_number)].alignment = c_c_alignment
235
            ws[col + str(current_row_number)].border = f_border
236
            ws[col + str(current_row_number)] = round(reporting_period_data['cumulations'][i], 2) \
237
                if reporting_period_data['cumulations'][i] is not None else None
238
239
            col = chr(ord(col) + 1)
240
241
        current_row_number += 1
242
243
        ws['B' + str(current_row_number)].font = title_font
244
        ws['B' + str(current_row_number)].alignment = c_c_alignment
245
        ws['B' + str(current_row_number)].border = f_border
246
        ws['B' + str(current_row_number)] = _('Increment Rate')
247
248
        col = 'C'
249
250
        for i in range(0, ca_len):
251
            ws[col + str(current_row_number)].font = name_font
252
            ws[col + str(current_row_number)].alignment = c_c_alignment
253
            ws[col + str(current_row_number)].border = f_border
254
            ws[col + str(current_row_number)] = str(
255
                round(reporting_period_data['increment_rates'][i] * 100, 2)) + '%' \
256
                if reporting_period_data['increment_rates'][i] is not None else '-'
257
258
            col = chr(ord(col) + 1)
259
260
        current_row_number += 2
261
262
    ####################################################################################################################
263
264
    has_parameters_names_and_timestamps_and_values_data = True
265
    current_sheet_parameters_row_number = current_row_number
266
267 View Code Duplication
    if 'parameters' not in report.keys() or \
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
268
            report['parameters'] is None or \
269
            'names' not in report['parameters'].keys() or \
270
            report['parameters']['names'] is None or \
271
            len(report['parameters']['names']) == 0 or \
272
            'timestamps' not in report['parameters'].keys() or \
273
            report['parameters']['timestamps'] is None or \
274
            len(report['parameters']['timestamps']) == 0 or \
275
            'values' not in report['parameters'].keys() or \
276
            report['parameters']['values'] is None or \
277
            len(report['parameters']['values']) == 0 or \
278
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
279
280
        has_parameters_names_and_timestamps_and_values_data = False
281
282
    ####################################################################################################################
283
284
    has_values_data = True
285
    has_timestamps_data = True
286
287
    if 'values' not in reporting_period_data.keys() or \
288
            reporting_period_data['values'] is None or \
289
            len(reporting_period_data['values']) == 0:
290
        has_values_data = False
291
292
    if 'timestamps' not in reporting_period_data.keys() or \
293
            reporting_period_data['timestamps'] is None or \
294
            len(reporting_period_data['timestamps']) == 0 or \
295
            len(reporting_period_data['timestamps'][0]) == 0:
296
        has_timestamps_data = False
297
298
    if not is_base_period_timestamp_exists_flag:
299
        if has_values_data and has_timestamps_data:
300
            ca_len = len(reporting_period_data['names'])
301
            time = reporting_period_data['timestamps'][0]
302
303
            ws['B' + str(current_row_number)].font = title_font
304
            ws['B' + str(current_row_number)] = name + ' ' + _('Reporting Period Cumulative Efficiency')
305
306
            current_row_number += 1
307
308
            chart_start_row_number = current_row_number
309
310
            current_row_number += ca_len * 6 + 1
311
312
            if has_parameters_names_and_timestamps_and_values_data:
313
                current_sheet_parameters_row_number = current_row_number
314
                real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
315
                current_row_number += 6*real_timestamps_len + 2
316
317
            ws['B' + str(current_row_number)].font = title_font
318
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
319
320
            current_row_number += 1
321
322
            table_start_row_number = current_row_number
323
324
            ws.row_dimensions[current_row_number].height = 85
325
            current_col_number = 2
326
            col = format_cell.get_column_letter(current_col_number)
327
            ws[col + str(current_row_number)].fill = table_fill
328
            ws[col + str(current_row_number)].font = title_font
329
            ws[col + str(current_row_number)].alignment = c_c_alignment
330
            ws[col + str(current_row_number)].border = f_border
331
            ws[col + str(current_row_number)] = _('Datetime')
332
333
            for i in range(0, ca_len):
334
                current_col_number += 1
335
                col = format_cell.get_column_letter(current_col_number)
336
                ws[col + str(current_row_number)].fill = table_fill
337
                ws[col + str(current_row_number)].font = title_font
338
                ws[col + str(current_row_number)].alignment = c_c_alignment
339
                ws[col + str(current_row_number)].border = f_border
340
                ws[col + str(current_row_number)] = \
341
                    reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
342
343
            current_row_number += 1
344
345
            for i in range(0, len(time)):
346
                current_col_number = 2
347
                col = format_cell.get_column_letter(current_col_number)
348
                ws[col + str(current_row_number)].font = title_font
349
                ws[col + str(current_row_number)].alignment = c_c_alignment
350
                ws[col + str(current_row_number)].border = f_border
351
                ws[col + str(current_row_number)] = time[i]
352
353
                for j in range(0, ca_len):
354
                    current_col_number += 1
355
                    col = format_cell.get_column_letter(current_col_number)
356
                    ws[col + str(current_row_number)].font = title_font
357
                    ws[col + str(current_row_number)].alignment = c_c_alignment
358
                    ws[col + str(current_row_number)].border = f_border
359
                    ws[col + str(current_row_number)] = round(reporting_period_data['values'][j][i], 2) \
360
                        if reporting_period_data['values'][j][i] is not None else None
361
362
                current_row_number += 1
363
364
            table_end_row_number = current_row_number - 1
365
366
            current_col_number = 2
367
            col = format_cell.get_column_letter(current_col_number)
368
            ws[col + str(current_row_number)].font = title_font
369
            ws[col + str(current_row_number)].alignment = c_c_alignment
370
            ws[col + str(current_row_number)].border = f_border
371
            ws[col + str(current_row_number)] = _('Subtotal')
372
373
            for i in range(0, ca_len):
374
                current_col_number += 1
375
                col = format_cell.get_column_letter(current_col_number)
376
                ws[col + str(current_row_number)].font = title_font
377
                ws[col + str(current_row_number)].alignment = c_c_alignment
378
                ws[col + str(current_row_number)].border = f_border
379
                ws[col + str(current_row_number)] = round(reporting_period_data['cumulations'][i], 2) \
380
                    if reporting_period_data['cumulations'][i] is not None else None
381
382
            current_row_number += 2
383
384
            for i in range(0, ca_len):
385
                line = LineChart()
386
                line.title = _('Reporting Period Cumulative Efficiency') + ' - ' + \
387
                    reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
388
                labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
389
                line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number, max_row=table_end_row_number)
390
                line.add_data(line_data, titles_from_data=True)
391
                line.set_categories(labels)
392
                line_data = line.series[0]
393
                line_data.marker.symbol = "circle"
394
                line_data.smooth = True
395
                line.x_axis.crosses = 'min'
396
                line.height = 8.25
397
                line.width = 24
398
                line.dLbls = DataLabelList()
399
                line.dLbls.dLblPos = 't'
400
                line.dLbls.showVal = True
401
                line.dLbls.showPercent = False
402
                chart_col = 'B'
403
                chart_cell = chart_col + str(chart_start_row_number)
404
                chart_start_row_number += 6
405
                ws.add_chart(line, chart_cell)
406
    else:
407
        if has_values_data and has_timestamps_data:
408
            base_period_data = report['base_period_efficiency']
409
            reporting_period_data = report['reporting_period_efficiency']
410
            base_period_timestamps = base_period_data['timestamps']
411
            reporting_period_timestamps = reporting_period_data['timestamps']
412
            # Tip:
413
            #     base_period_data['names'] == reporting_period_data['names']
414
            #     base_period_data['units'] == reporting_period_data['units']
415
            base_period_data_ca_len = len(base_period_data['names'])
416
            reporting_period_data_ca_len = len(reporting_period_data['names'])
417
            ws['B' + str(current_row_number)].font = title_font
418
            ws['B' + str(current_row_number)] = name + ' ' + _('Reporting Period Cumulative Efficiency')
419
420
            current_row_number += 1
421
422
            chart_start_row_number = current_row_number
423
424
            current_row_number += reporting_period_data_ca_len * 6 + 1
425
426
            if has_parameters_names_and_timestamps_and_values_data:
427
                current_sheet_parameters_row_number = current_row_number
428
                real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
429
                current_row_number += 6*real_timestamps_len + 2
430
431
            ws['B' + str(current_row_number)].font = title_font
432
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
433
434
            current_row_number += 1
435
436
            table_start_row_number = current_row_number
437
438
            ws.row_dimensions[current_row_number].height = 85
439
            current_col_number = 2
440
            col = format_cell.get_column_letter(current_col_number)
441
            ws[col + str(current_row_number)].fill = table_fill
442
            ws[col + str(current_row_number)].font = title_font
443
            ws[col + str(current_row_number)].alignment = c_c_alignment
444
            ws[col + str(current_row_number)].border = f_border
445
            ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime')
446
447
            for i in range(0, base_period_data_ca_len):
448
                current_col_number += 1
449
                col = format_cell.get_column_letter(current_col_number)
450
451
                ws[col + str(current_row_number)].fill = table_fill
452
                ws[col + str(current_row_number)].font = title_font
453
                ws[col + str(current_row_number)].alignment = c_c_alignment
454
                ws[col + str(current_row_number)] = _('Base Period') + " - " + base_period_data['names'][i] + \
455
                    " (" + base_period_data['units'][i] + ")"
456
                ws[col + str(current_row_number)].border = f_border
457
458
            current_col_number += 1
459
            col = format_cell.get_column_letter(current_col_number)
460
461
            ws[col + str(current_row_number)].fill = table_fill
462
            ws[col + str(current_row_number)].font = title_font
463
            ws[col + str(current_row_number)].border = f_border
464
            ws[col + str(current_row_number)].alignment = c_c_alignment
465
            ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime')
466
467
            for i in range(0, reporting_period_data_ca_len):
468
                current_col_number += 1
469
                col = format_cell.get_column_letter(current_col_number)
470
                ws[col + str(current_row_number)].fill = table_fill
471
                ws[col + str(current_row_number)].font = title_font
472
                ws[col + str(current_row_number)].alignment = c_c_alignment
473
                ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
474
                    + reporting_period_data['names'][i] + " (" + \
475
                    reporting_period_data['units'][i] + ")"
476
                ws[col + str(current_row_number)].border = f_border
477
478
            current_row_number += 1
479
480
            max_timestamps_len = len(base_period_timestamps[0]) \
481
                if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \
482
                else len(reporting_period_timestamps[0])
483
484
            for i in range(0, max_timestamps_len):
485
                current_col_number = 2
486
                col = format_cell.get_column_letter(current_col_number)
487
                ws[col + str(current_row_number)].font = title_font
488
                ws[col + str(current_row_number)].alignment = c_c_alignment
489
                ws[col + str(current_row_number)] = base_period_timestamps[0][i] \
490
                    if i < len(base_period_timestamps[0]) else None
491
                ws[col + str(current_row_number)].border = f_border
492
493
                for j in range(0, base_period_data_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)].font = title_font
498
                    ws[col + str(current_row_number)].alignment = c_c_alignment
499
                    ws[col + str(current_row_number)] = round(base_period_data['values'][j][i], 2) \
500
                        if i < len(base_period_data['values'][j]) \
501
                        and base_period_data['values'][j][i] is not None else None
502
                    ws[col + str(current_row_number)].border = f_border
503
                current_col_number += 1
504
                col = format_cell.get_column_letter(current_col_number)
505
506
                ws[col + str(current_row_number)].font = title_font
507
                ws[col + str(current_row_number)].alignment = c_c_alignment
508
                ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \
509
                    if i < len(reporting_period_timestamps[0]) else None
510
                ws[col + str(current_row_number)].border = f_border
511
512
                for j in range(0, reporting_period_data_ca_len):
513
                    current_col_number += 1
514
                    col = format_cell.get_column_letter(current_col_number)
515
516
                    ws[col + str(current_row_number)].font = title_font
517
                    ws[col + str(current_row_number)].alignment = c_c_alignment
518
                    ws[col + str(current_row_number)] = round(reporting_period_data['values'][j][i], 2) \
519
                        if i < len(reporting_period_data['values'][j]) \
520
                        and reporting_period_data['values'][j][i] is not None else None
521
                    ws[col + str(current_row_number)].border = f_border
522
523
                current_row_number += 1
524
525
            current_col_number = 2
526
            col = format_cell.get_column_letter(current_col_number)
527
528
            ws[col + str(current_row_number)].font = title_font
529
            ws[col + str(current_row_number)].alignment = c_c_alignment
530
            ws[col + str(current_row_number)] = _('Subtotal')
531
            ws[col + str(current_row_number)].border = f_border
532
533
            for i in range(0, base_period_data_ca_len):
534
                current_col_number += 1
535
                col = format_cell.get_column_letter(current_col_number)
536
                ws[col + str(current_row_number)].font = title_font
537
                ws[col + str(current_row_number)].alignment = c_c_alignment
538
                ws[col + str(current_row_number)] = round(base_period_data['cumulations'][i], 2) \
539
                    if base_period_data['cumulations'][i] is not None else None
540
                ws[col + str(current_row_number)].border = f_border
541
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)] = _('Subtotal')
548
            ws[col + str(current_row_number)].border = f_border
549
550
            for i in range(0, reporting_period_data_ca_len):
551
                col = chr(ord(col) + 1)
552
                ws[col + str(current_row_number)].font = title_font
553
                ws[col + str(current_row_number)].alignment = c_c_alignment
554
                ws[col + str(current_row_number)] = round(reporting_period_data['cumulations'][i], 2) \
555
                    if reporting_period_data['cumulations'][i] is not None else None
556
                ws[col + str(current_row_number)].border = f_border
557
558
            current_row_number += 2
559
560
            for i in range(0, reporting_period_data_ca_len):
561
                line = LineChart()
562
                line.title = _('Base Period Cumulative Efficiency') + ' / ' \
563
                    + _('Reporting Period Cumulative Efficiency') + ' - '  \
564
                    + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
565
                labels = Reference(ws, min_col=2 + base_period_data_ca_len + 1,
566
                                   min_row=table_start_row_number + 1,
567
                                   max_row=table_start_row_number + len(reporting_period_timestamps[0]))
568
                base_line_data = Reference(ws, min_col=3 + i,
569
                                           min_row=table_start_row_number,
570
                                           max_row=table_start_row_number + len(reporting_period_timestamps[0]))
571
                reporting_line_data = Reference(ws, min_col=3 + base_period_data_ca_len + 1 + i,
572
                                                min_row=table_start_row_number,
573
                                                max_row=table_start_row_number + len(reporting_period_timestamps[0]))
574
                line.add_data(base_line_data, titles_from_data=True)
575
                line.add_data(reporting_line_data, titles_from_data=True)
576
                line.set_categories(labels)
577
                for j in range(len(line.series)):
578
                    line.series[j].marker.symbol = "circle"
579
                    line.series[j].smooth = True
580
                line.x_axis.crosses = 'min'
581
                line.height = 8.25
582
                line.width = 24
583
                line.dLbls = DataLabelList()
584
                line.dLbls.dLblPos = 't'
585
                line.dLbls.showVal = True
586
                line.dLbls.showPercent = False
587
                chart_col = 'B'
588
                chart_cell = chart_col + str(chart_start_row_number)
589
                chart_start_row_number += 6
590
                ws.add_chart(line, chart_cell)
591
592
    ####################################################################################################################
593
594 View Code Duplication
    if has_parameters_names_and_timestamps_and_values_data:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
595
596
        ################################################################################################################
597
        # new worksheet
598
        ################################################################################################################
599
600
        parameters_data = report['parameters']
601
        parameters_names_len = len(parameters_data['names'])
602
603
        file_name = "Space"+re.sub(r'[^A-Z]', '', ws.title.strip('S')) + "_"
604
        parameters_ws = wb.create_sheet(file_name + _('Parameters'))
605
606
        parameters_timestamps_data_max_len = \
607
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
608
609
        # Row height
610
        parameters_ws.row_dimensions[1].height = 102
611
        for i in range(2, 7 + 1):
612
            parameters_ws.row_dimensions[i].height = 42
613
614
        for i in range(8, parameters_timestamps_data_max_len + 10):
615
            parameters_ws.row_dimensions[i].height = 60
616
617
        # Col width
618
        parameters_ws.column_dimensions['A'].width = 1.5
619
620
        parameters_ws.column_dimensions['B'].width = 25.0
621
622
        for i in range(3, 12+parameters_names_len*3):
623
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
624
625
        # Img
626
        img = Image("excelexporters/myems.png")
627
        parameters_ws.add_image(img, 'A1')
628
629
        # Title
630
        parameters_ws['B3'].alignment = b_r_alignment
631
        parameters_ws['B3'] = _('Name') + ':'
632
        parameters_ws['C3'].border = b_border
633
        parameters_ws['C3'].alignment = b_c_alignment
634
        parameters_ws['C3'] = name
635
636
        parameters_ws['D3'].alignment = b_r_alignment
637
        parameters_ws['D3'] = _('Period Type') + ':'
638
        parameters_ws['E3'].border = b_border
639
        parameters_ws['E3'].alignment = b_c_alignment
640
        parameters_ws['E3'] = period_type
641
642
        parameters_ws['B4'].alignment = b_r_alignment
643
        parameters_ws['B4'] = _('Reporting Start Datetime') + ':'
644
        parameters_ws['C4'].border = b_border
645
        parameters_ws['C4'].alignment = b_c_alignment
646
        parameters_ws['C4'] = reporting_start_datetime_local
647
648
        parameters_ws['D4'].alignment = b_r_alignment
649
        parameters_ws['D4'] = _('Reporting End Datetime') + ':'
650
        parameters_ws['E4'].border = b_border
651
        parameters_ws['E4'].alignment = b_c_alignment
652
        parameters_ws['E4'] = reporting_end_datetime_local
653
654
        parameters_ws_current_row_number = 6
655
656
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
657
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters')
658
659
        parameters_ws_current_row_number += 1
660
661
        parameters_table_start_row_number = parameters_ws_current_row_number
662
663
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
664
665
        parameters_ws_current_row_number += 1
666
667
        table_current_col_number = 2
668
669
        for i in range(0, parameters_names_len):
670
671
            if len(parameters_data['timestamps'][i]) == 0:
672
                continue
673
674
            col = format_cell.get_column_letter(table_current_col_number)
675
676
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
677
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
678
679
            col = format_cell.get_column_letter(table_current_col_number + 1)
680
681
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
682
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
683
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
684
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
685
            parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
686
687
            table_current_row_number = parameters_ws_current_row_number
688
689
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
690
                col = format_cell.get_column_letter(table_current_col_number)
691
692
                parameters_ws[col + str(table_current_row_number)].border = f_border
693
                parameters_ws[col + str(table_current_row_number)].font = title_font
694
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
695
                parameters_ws[col + str(table_current_row_number)] = value
696
697
                col = format_cell.get_column_letter(table_current_col_number + 1)
698
699
                parameters_ws[col + str(table_current_row_number)].border = f_border
700
                parameters_ws[col + str(table_current_row_number)].font = title_font
701
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
702
                parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
703
704
                table_current_row_number += 1
705
706
            table_current_col_number = table_current_col_number + 3
707
708
        ################################################################################################################
709
        # parameters chart and parameters table
710
        ################################################################################################################
711
712
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
713
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters')
714
715
        current_sheet_parameters_row_number += 1
716
717
        chart_start_row_number = current_sheet_parameters_row_number
718
719
        col_index = 0
720
721
        for i in range(0, parameters_names_len):
722
723
            if len(parameters_data['timestamps'][i]) == 0:
724
                continue
725
726
            line = LineChart()
727
            data_col = 3+col_index*3
728
            labels_col = 2+col_index*3
729
            col_index += 1
730
            line.title = _('Parameters') + ' - ' + \
731
                parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
732
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
733
                               max_row=(len(parameters_data['timestamps'][i])+parameters_table_start_row_number))
734
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
735
                                  max_row=(len(parameters_data['timestamps'][i])+parameters_table_start_row_number))
736
            line.add_data(line_data, titles_from_data=True)
737
            line.set_categories(labels)
738
            line_data = line.series[0]
739
            line_data.marker.symbol = "circle"
740
            line_data.smooth = True
741
            line.x_axis.crosses = 'min'
742
            line.height = 8.25
743
            line.width = 24
744
            line.dLbls = DataLabelList()
745
            line.dLbls.dLblPos = 't'
746
            line.dLbls.showVal = False
747
            line.dLbls.showPercent = False
748
            chart_col = 'B'
749
            chart_cell = chart_col + str(chart_start_row_number)
750
            chart_start_row_number += 6
751
            ws.add_chart(line, chart_cell)
752
753
        current_sheet_parameters_row_number = chart_start_row_number
754
755
        current_sheet_parameters_row_number += 1
756
757
    filename = str(uuid.uuid4()) + '.xlsx'
758
    wb.save(filename)
759
760
    return filename
761
762
763
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
764
    max_len = 0
765
    for i, value in enumerate(list(parameters_timestamps_lists)):
766
        if len(value) > max_len:
767
            max_len = len(value)
768
769
    return max_len
770
771
772
def timestamps_data_all_equal_0(lists):
773
    for i, value in enumerate(list(lists)):
774
        if len(value) > 0:
775
            return False
776
777
    return True
778
779
780
def timestamps_data_not_equal_0(lists):
781
    number = 0
782
    for i, value in enumerate(list(lists)):
783
        if len(value) > 0:
784
            number += 1
785
    return number
786
787
788 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...
789
    timestamps = base_period_data['timestamps']
790
791
    if len(timestamps) == 0:
792
        return False
793
794
    for timestamp in timestamps:
795
        if len(timestamp) > 0:
796
            return True
797
798
    return False
799