Passed
Push — master ( c215ca...be0b67 )
by Guangyu
13:48 queued 12s
created

excelexporters.virtualmeterenergy.generate_excel()   F

Complexity

Conditions 53

Size

Total Lines 663
Code Lines 502

Duplication

Lines 663
Ratio 100 %

Importance

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