excelexporters.virtualmeterplan.generate_excel()   F
last analyzed

Complexity

Conditions 50

Size

Total Lines 644
Code Lines 485

Duplication

Lines 0
Ratio 0 %

Importance

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