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

excelexporters.metercost.generate_excel()   F

Complexity

Conditions 53

Size

Total Lines 661
Code Lines 500

Duplication

Lines 0
Ratio 0 %

Importance

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