Passed
Push — master ( d6dd87...c1af40 )
by Guangyu
10:17 queued 14s
created

excelexporters.offlinemetersaving.generate_excel()   F

Complexity

Conditions 53

Size

Total Lines 664
Code Lines 504

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 504
dl 0
loc 664
rs 0
c 0
b 0
f 0
cc 53
nop 8

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like excelexporters.offlinemetersaving.generate_excel() 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.

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