Passed
Push — master ( 82dd0d...8c8679 )
by Guangyu
10:18 queued 13s
created

excelexporters.tenantload.generate_excel()   F

Complexity

Conditions 104

Size

Total Lines 913
Code Lines 714

Duplication

Lines 913
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 714
dl 913
loc 913
rs 0
c 0
b 0
f 0
cc 104
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.tenantload.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
19
# Step 3: Encode the excel file to Base64
20
########################################################################################################################
21
22
23 View Code Duplication
def export(report,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
24
           name,
25
           base_period_start_datetime_local,
26
           base_period_end_datetime_local,
27
           reporting_start_datetime_local,
28
           reporting_end_datetime_local,
29
           period_type,
30
           language):
31
    ####################################################################################################################
32
    # Step 1: Validate the report data
33
    ####################################################################################################################
34
    if report is None:
35
        return None
36
37
    ####################################################################################################################
38
    # Step 2: Generate excel file from the report data
39
    ####################################################################################################################
40
    filename = generate_excel(report,
41
                              name,
42
                              base_period_start_datetime_local,
43
                              base_period_end_datetime_local,
44
                              reporting_start_datetime_local,
45
                              reporting_end_datetime_local,
46
                              period_type,
47
                              language)
48
    ####################################################################################################################
49
    # Step 3: Encode the excel file to Base64
50
    ####################################################################################################################
51
    binary_file_data = b''
52
    try:
53
        with open(filename, 'rb') as binary_file:
54
            binary_file_data = binary_file.read()
55
    except IOError as ex:
56
        print(str(ex))
57
58
    # Base64 encode the bytes
59
    base64_encoded_data = base64.b64encode(binary_file_data)
60
    # get the Base64 encoded data using human-readable characters.
61
    base64_message = base64_encoded_data.decode('utf-8')
62
    # delete the file from server
63
    try:
64
        os.remove(filename)
65
    except NotImplementedError as ex:
66
        print(str(ex))
67
    return base64_message
68
69
70 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...
71
                   name,
72
                   base_period_start_datetime_local,
73
                   base_period_end_datetime_local,
74
                   reporting_start_datetime_local,
75
                   reporting_end_datetime_local,
76
                   period_type,
77
                   language):
78
79
    locale_path = './i18n/'
80
    if language == 'zh_CN':
81
        trans = gettext.translation('myems', locale_path, languages=['zh_CN'])
82
    elif language == 'de':
83
        trans = gettext.translation('myems', locale_path, languages=['de'])
84
    elif language == 'en':
85
        trans = gettext.translation('myems', locale_path, languages=['en'])
86
    else:
87
        trans = gettext.translation('myems', locale_path, languages=['en'])
88
    trans.install()
89
    _ = trans.gettext
90
91
    wb = Workbook()
92
93
    # todo
94
    ws = wb.active
95
    ws.title = "TenantLoad"
96
    # Row height
97
    ws.row_dimensions[1].height = 102
98
    for i in range(2, 2000 + 1):
99
        ws.row_dimensions[i].height = 42
100
101
    # Col width
102
    ws.column_dimensions['A'].width = 1.5
103
104
    ws.column_dimensions['B'].width = 25.0
105
106
    for i in range(ord('C'), ord('Z')):
107
        ws.column_dimensions[chr(i)].width = 15.0
108
109
    # Font
110
    name_font = Font(name='Arial', size=15, bold=True)
111
    title_font = Font(name='Arial', size=15, bold=True)
112
113
    table_fill = PatternFill(fill_type='solid', fgColor='90ee90')
114
    f_border = Border(left=Side(border_style='medium'),
115
                      right=Side(border_style='medium'),
116
                      bottom=Side(border_style='medium'),
117
                      top=Side(border_style='medium')
118
                      )
119
    b_border = Border(
120
        bottom=Side(border_style='medium'),
121
    )
122
123
    b_c_alignment = Alignment(vertical='bottom',
124
                              horizontal='center',
125
                              text_rotation=0,
126
                              wrap_text=True,
127
                              shrink_to_fit=False,
128
                              indent=0)
129
    c_c_alignment = Alignment(vertical='center',
130
                              horizontal='center',
131
                              text_rotation=0,
132
                              wrap_text=True,
133
                              shrink_to_fit=False,
134
                              indent=0)
135
    b_r_alignment = Alignment(vertical='bottom',
136
                              horizontal='right',
137
                              text_rotation=0,
138
                              wrap_text=True,
139
                              shrink_to_fit=False,
140
                              indent=0)
141
142
    # Img
143
    img = Image("excelexporters/myems.png")
144
    ws.add_image(img, 'A1')
145
146
    # Title
147
    ws['B3'].alignment = b_r_alignment
148
    ws['B3'] = _('Name') + ':'
149
    ws['C3'].border = b_border
150
    ws['C3'].alignment = b_c_alignment
151
    ws['C3'] = name
152
153
    ws['D3'].alignment = b_r_alignment
154
    ws['D3'] = _('Period Type') + ':'
155
    ws['E3'].border = b_border
156
    ws['E3'].alignment = b_c_alignment
157
    ws['E3'] = period_type
158
159
    ws['B4'].alignment = b_r_alignment
160
    ws['B4'] = _('Reporting Start Datetime') + ':'
161
    ws['C4'].border = b_border
162
    ws['C4'].alignment = b_c_alignment
163
    ws['C4'] = reporting_start_datetime_local
164
165
    ws['D4'].alignment = b_r_alignment
166
    ws['D4'] = _('Reporting End Datetime') + ':'
167
    ws['E4'].border = b_border
168
    ws['E4'].alignment = b_c_alignment
169
    ws['E4'] = reporting_end_datetime_local
170
171
    is_base_period_timestamp_exists_flag = is_base_period_timestamp_exists(report['base_period'])
172
173
    if is_base_period_timestamp_exists_flag:
174
        ws['B5'].alignment = b_r_alignment
175
        ws['B5'] = _('Base Period Start Datetime') + ':'
176
        ws['C5'].border = b_border
177
        ws['C5'].alignment = b_c_alignment
178
        ws['C5'] = base_period_start_datetime_local
179
180
        ws['D5'].alignment = b_r_alignment
181
        ws['D5'] = _('Base Period End Datetime') + ':'
182
        ws['E5'].border = b_border
183
        ws['E5'].alignment = b_c_alignment
184
        ws['E5'] = base_period_end_datetime_local
185
186
    if "reporting_period" not in report.keys() or \
187
            "timestamps" not in report['reporting_period'].keys() or len(report['reporting_period']['timestamps']) == 0:
188
        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...
189
        wb.save(filename)
190
191
        return filename
192
193
    ####################################################################################################################
194
    current_row_number = 7
195
    if "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
196
        pass
197
    else:
198
        reporting_period_data = report['reporting_period']
199
        category = reporting_period_data['names']
200
        ca_len = len(category)
201
202
        ws['B' + str(current_row_number)].font = title_font
203
        ws['B' + str(current_row_number)] = name + _('Reporting Period Average Load')
204
205
        current_row_number += 1
206
207
        ws.row_dimensions[current_row_number].height = 60
208
        ws['B' + str(current_row_number)].fill = table_fill
209
        ws['B' + str(current_row_number)].border = f_border
210
211
        for i in range(0, ca_len):
212
            col = chr(ord('C') + i)
213
            ws[col + str(current_row_number)].fill = table_fill
214
            ws[col + str(current_row_number)].font = name_font
215
            ws[col + str(current_row_number)].alignment = c_c_alignment
216
            ws[col + str(current_row_number)].border = f_border
217
            ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
218
                " (" + reporting_period_data['units'][i] + "/H)"
219
220
        current_row_number += 1
221
222
        ws['B' + str(current_row_number)].font = title_font
223
        ws['B' + str(current_row_number)].alignment = c_c_alignment
224
        ws['B' + str(current_row_number)].border = f_border
225
        ws['B' + str(current_row_number)] = _('Average Load')
226
227
        for i in range(0, ca_len):
228
            col = chr(ord('C') + i)
229
            ws[col + str(current_row_number)].font = name_font
230
            ws[col + str(current_row_number)].alignment = c_c_alignment
231
            ws[col + str(current_row_number)].border = f_border
232
            ws[col + str(current_row_number)] = round(reporting_period_data['averages'][i], 2) \
233
                if reporting_period_data['averages'][i] is not None else 'N/A'
234
235
        current_row_number += 1
236
237
        ws['B' + str(current_row_number)].font = title_font
238
        ws['B' + str(current_row_number)].alignment = c_c_alignment
239
        ws['B' + str(current_row_number)].border = f_border
240
        ws['B' + str(current_row_number)] = _('Per Unit Area')
241
242
        for i in range(0, ca_len):
243
            col = chr(ord('C') + i)
244
            ws[col + str(current_row_number)].font = name_font
245
            ws[col + str(current_row_number)].alignment = c_c_alignment
246
            ws[col + str(current_row_number)].border = f_border
247
            ws[col + str(current_row_number)] = round(reporting_period_data['averages_per_unit_area'][i], 2) \
248
                if reporting_period_data['averages_per_unit_area'][i] is not None else 'N/A'
249
250
        current_row_number += 1
251
252
        ws['B' + str(current_row_number)].font = title_font
253
        ws['B' + str(current_row_number)].alignment = c_c_alignment
254
        ws['B' + str(current_row_number)].border = f_border
255
        ws['B' + str(current_row_number)] = _('Increment Rate')
256
257
        for i in range(0, ca_len):
258
            col = chr(ord('C') + i)
259
            ws[col + str(current_row_number)].font = name_font
260
            ws[col + str(current_row_number)].alignment = c_c_alignment
261
            ws[col + str(current_row_number)].border = f_border
262
            ws[col + str(current_row_number)] = str(
263
                round(reporting_period_data['averages_increment_rate'][i] * 100, 2)) + "%" \
264
                if reporting_period_data['averages_increment_rate'][i] is not None else "-"
265
266
        current_row_number += 2
267
268
        ws['B' + str(current_row_number)].font = title_font
269
        ws['B' + str(current_row_number)] = name + _('Reporting Period Maximum Load')
270
271
        current_row_number += 1
272
273
        ws.row_dimensions[current_row_number].height = 60
274
        ws['B' + str(current_row_number)].fill = table_fill
275
        ws['B' + str(current_row_number)].border = f_border
276
        for i in range(0, ca_len):
277
            col = chr(ord('C') + i)
278
            ws[col + str(current_row_number)].fill = table_fill
279
            ws[col + str(current_row_number)].font = name_font
280
            ws[col + str(current_row_number)].alignment = c_c_alignment
281
            ws[col + str(current_row_number)].border = f_border
282
            ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
283
                " (" + reporting_period_data['units'][i] + "/H)"
284
285
        current_row_number += 1
286
287
        ws['B' + str(current_row_number)].font = title_font
288
        ws['B' + str(current_row_number)].alignment = c_c_alignment
289
        ws['B' + str(current_row_number)].border = f_border
290
        ws['B' + str(current_row_number)] = _('Maximum Load')
291
292
        for i in range(0, ca_len):
293
            col = chr(ord('C') + i)
294
            ws[col + str(current_row_number)].font = name_font
295
            ws[col + str(current_row_number)].alignment = c_c_alignment
296
            ws[col + str(current_row_number)].border = f_border
297
            ws[col + str(current_row_number)] = round(reporting_period_data['maximums'][i], 2) \
298
                if reporting_period_data['maximums'][i] is not None else 'N/A'
299
300
        current_row_number += 1
301
302
        ws['B' + str(current_row_number)].font = title_font
303
        ws['B' + str(current_row_number)].alignment = c_c_alignment
304
        ws['B' + str(current_row_number)].border = f_border
305
        ws['B' + str(current_row_number)] = _('Per Unit Area')
306
307
        for i in range(0, ca_len):
308
            col = chr(ord('C') + i)
309
            ws[col + str(current_row_number)].font = name_font
310
            ws[col + str(current_row_number)].alignment = c_c_alignment
311
            ws[col + str(current_row_number)].border = f_border
312
            ws[col + str(current_row_number)] = round(reporting_period_data['maximums_per_unit_area'][i], 2) \
313
                if reporting_period_data['maximums_per_unit_area'][i] is not None else 'N/A'
314
315
        current_row_number += 1
316
317
        ws['B' + str(current_row_number)].font = title_font
318
        ws['B' + str(current_row_number)].alignment = c_c_alignment
319
        ws['B' + str(current_row_number)].border = f_border
320
        ws['B' + str(current_row_number)] = _('Increment Rate')
321
322
        for i in range(0, ca_len):
323
            col = chr(ord('C') + i)
324
            ws[col + str(current_row_number)].font = name_font
325
            ws[col + str(current_row_number)].alignment = c_c_alignment
326
            ws[col + str(current_row_number)].border = f_border
327
            ws[col + str(current_row_number)] = str(
328
                round(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \
329
                if reporting_period_data['maximums_increment_rate'][i] is not None else "-"
330
331
        current_row_number += 2
332
333
        ws['B' + str(current_row_number)].font = title_font
334
        ws['B' + str(current_row_number)] = name + _('Reporting Period Load Factor')
335
336
        current_row_number += 1
337
338
        ws.row_dimensions[current_row_number].height = 60
339
        ws['B' + str(current_row_number)].fill = table_fill
340
        ws['B' + str(current_row_number)].border = f_border
341
        for i in range(0, ca_len):
342
            col = chr(ord('C') + i)
343
            ws[col + str(current_row_number)].fill = table_fill
344
            ws[col + str(current_row_number)].font = name_font
345
            ws[col + str(current_row_number)].alignment = c_c_alignment
346
            ws[col + str(current_row_number)].border = f_border
347
            ws[col + str(current_row_number)] = reporting_period_data['names'][i]
348
349
        current_row_number += 1
350
351
        ws['B' + str(current_row_number)].font = title_font
352
        ws['B' + str(current_row_number)].alignment = c_c_alignment
353
        ws['B' + str(current_row_number)].border = f_border
354
        ws['B' + str(current_row_number)] = _('Load Factor')
355
356
        for i in range(0, ca_len):
357
            col = chr(ord('C') + i)
358
            ws[col + str(current_row_number)].font = name_font
359
            ws[col + str(current_row_number)].alignment = c_c_alignment
360
            ws[col + str(current_row_number)].border = f_border
361
            ws[col + str(current_row_number)] = round(reporting_period_data['factors'][i], 2) \
362
                if reporting_period_data['factors'][i] is not None else '-'
363
364
        current_row_number += 1
365
366
        ws['B' + str(current_row_number)].font = title_font
367
        ws['B' + str(current_row_number)].alignment = c_c_alignment
368
        ws['B' + str(current_row_number)].border = f_border
369
        ws['B' + str(current_row_number)] = _('Increment Rate')
370
371
        for i in range(0, ca_len):
372
            col = chr(ord('C') + i)
373
            ws[col + str(current_row_number)].font = name_font
374
            ws[col + str(current_row_number)].alignment = c_c_alignment
375
            ws[col + str(current_row_number)].border = f_border
376
            ws[col + str(current_row_number)] = str(
377
                round(reporting_period_data['factors_increment_rate'][i] * 100, 2)) + "%" \
378
                if reporting_period_data['factors_increment_rate'][i] is not None else "-"
379
380
        current_row_number += 2
381
382
    has_sub_averages_data_flag = True
383
    has_sub_maximums_data_flag = True
384
385
    if "sub_averages" not in report['reporting_period'].keys() or len(report['reporting_period']['sub_averages']) == 0:
386
        has_sub_averages_data_flag = False
387
388
    if "sub_maximums" not in report['reporting_period'].keys() or len(report['reporting_period']['sub_maximums']) == 0:
389
        has_sub_maximums_data_flag = False
390
391
    current_chart_row_number = current_row_number
392
393
    if has_sub_averages_data_flag or has_sub_maximums_data_flag:
394
        if not is_base_period_timestamp_exists_flag:
395
            reporting_period_data = report['reporting_period']
396
            category = reporting_period_data['names']
397
            ca_len = len(category)
398
            times = reporting_period_data['timestamps']
399
            time = times[0]
400
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
401
            ws['B' + str(current_row_number)].font = title_font
402
            ws['B' + str(current_row_number)] = name + _('Detailed Data')
403
404
            current_row_number += 1
405
            chart_start_number = current_row_number
406
            # 1: Stand for blank line  2: Stand for title
407
            current_row_number += real_timestamps_len * 6 + 1 + 2
408
            if has_sub_averages_data_flag:
409
                current_row_number = (current_row_number + ca_len * 6)
410
411
            if has_sub_maximums_data_flag:
412
                current_row_number = (current_row_number + ca_len * 6)
413
414
            table_start_number = current_row_number
415
416
            ws.row_dimensions[current_row_number].height = 60
417
            current_col_number = 2
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)].border = f_border
423
            ws[col + str(current_row_number)] = _('Datetime')
424
425
            current_col_number = 3
426
            col = format_cell.get_column_letter(current_col_number)
427
428
            for i in range(0, ca_len):
429
                if has_sub_averages_data_flag:
430
                    ws[col + str(current_row_number)].fill = table_fill
431
                    ws[col + str(current_row_number)].font = title_font
432
                    ws[col + str(current_row_number)].alignment = c_c_alignment
433
                    ws[col + str(current_row_number)].border = f_border
434
                    ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
435
                        " " + _('Average Load') + "(" + reporting_period_data['units'][i] + "/H)"
436
437
                    current_col_number += 1
438
                    col = format_cell.get_column_letter(current_col_number)
439
440
                if has_sub_maximums_data_flag:
441
                    ws[col + str(current_row_number)].fill = table_fill
442
                    ws[col + str(current_row_number)].font = title_font
443
                    ws[col + str(current_row_number)].alignment = c_c_alignment
444
                    ws[col + str(current_row_number)].border = f_border
445
                    ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
446
                        " " + _('Maximum Load') + "(" + reporting_period_data['units'][i] + "/H)"
447
448
                    current_col_number += 1
449
                    col = format_cell.get_column_letter(current_col_number)
450
451
            current_row_number += 1
452
453
            for i in range(0, len(time)):
454
                current_col_number = 2
455
                col = format_cell.get_column_letter(current_col_number)
456
                ws[col + str(current_row_number)].font = title_font
457
                ws[col + str(current_row_number)].alignment = c_c_alignment
458
                ws[col + str(current_row_number)].border = f_border
459
                ws[col + str(current_row_number)] = time[i]
460
461
                current_col_number = 3
462
                col = format_cell.get_column_letter(current_col_number)
463
                for j in range(0, ca_len):
464
465
                    if has_sub_averages_data_flag:
466
                        ws[col + str(current_row_number)].font = title_font
467
                        ws[col + str(current_row_number)].alignment = c_c_alignment
468
                        ws[col + str(current_row_number)].border = f_border
469
                        ws[col + str(current_row_number)] = round(reporting_period_data['sub_averages'][j][i], 2) \
470
                            if reporting_period_data['sub_averages'][j][i] is not None else None
471
                        current_col_number += 1
472
                        col = format_cell.get_column_letter(current_col_number)
473
474
                    if has_sub_maximums_data_flag:
475
                        ws[col + str(current_row_number)].font = title_font
476
                        ws[col + str(current_row_number)].alignment = c_c_alignment
477
                        ws[col + str(current_row_number)].border = f_border
478
                        ws[col + str(current_row_number)] = round(reporting_period_data['sub_maximums'][j][i], 2) \
479
                            if reporting_period_data['sub_maximums'][j][i] is not None else None
480
                        current_col_number += 1
481
                        col = format_cell.get_column_letter(current_col_number)
482
483
                current_row_number += 1
484
485
            table_end_number = current_row_number - 1
486
487
            current_chart_col_number = 3
488
            current_chart_row_number = chart_start_number
489
490
            for i in range(0, ca_len):
491
                labels = Reference(ws, min_col=2, min_row=table_start_number + 1, max_row=table_end_number)
492
493
                if has_sub_averages_data_flag:
494
                    line = LineChart()
495
                    line.title = _('Reporting Period Average Load') + ' - ' \
496
                        + reporting_period_data['names'][i] + \
497
                        " " + _('Average Load') + "(" + reporting_period_data['units'][i] + "/H)"
498
                    datas = Reference(ws, min_col=current_chart_col_number, min_row=table_start_number,
499
                                      max_row=table_end_number)
500
                    line.add_data(datas, titles_from_data=True)
501
                    line.set_categories(labels)
502
                    line_data = line.series[0]
503
                    line_data.marker.symbol = "circle"
504
                    line_data.smooth = True
505
                    line.x_axis.crosses = 'min'
506
                    line.height = 8.25
507
                    line.width = 24
508
                    line.dLbls = DataLabelList()
509
                    line.dLbls.dLblPos = 't'
510
                    line.dLbls.showVal = True
511
                    ws.add_chart(line, "B" + str(current_chart_row_number))
512
                    current_chart_row_number += 6
513
                    current_chart_col_number += 1
514
515
                if has_sub_maximums_data_flag:
516
                    line = LineChart()
517
                    line.title = _('Reporting Period Maximum Load') + ' - ' \
518
                        + reporting_period_data['names'][i] + \
519
                        " " + _('Maximum Load') + "(" + reporting_period_data['units'][i] + "/H)"
520
                    datas = Reference(ws, min_col=current_chart_col_number, min_row=table_start_number,
521
                                      max_row=table_end_number)
522
                    line.add_data(datas, titles_from_data=True)
523
                    line.set_categories(labels)
524
                    line_data = line.series[0]
525
                    line_data.marker.symbol = "circle"
526
                    line_data.smooth = True
527
                    line.x_axis.crosses = 'min'
528
                    line.height = 8.25
529
                    line.width = 24
530
                    line.dLbls = DataLabelList()
531
                    line.dLbls.dLblPos = 't'
532
                    line.dLbls.showVal = True
533
                    ws.add_chart(line, "B" + str(current_chart_row_number))
534
                    current_chart_row_number += 6
535
                    current_chart_col_number += 1
536
        else:
537
            base_period_data = report['base_period']
538
            reporting_period_data = report['reporting_period']
539
            base_period_timestamps = base_period_data['timestamps']
540
            reporting_period_timestamps = reporting_period_data['timestamps']
541
            # Tip:
542
            #     base_period_data['names'] == reporting_period_data['names']
543
            #     base_period_data['units'] == reporting_period_data['units']
544
            base_period_data_ca_len = len(base_period_data['names'])
545
            reporting_period_data_ca_len = len(reporting_period_data['names'])
546
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
547
            ws['B' + str(current_row_number)].font = title_font
548
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
549
550
            current_row_number += 1
551
            chart_start_number = current_row_number
552
553
            # 1: Stand for blank line  2: Stand for title
554
            current_row_number += real_timestamps_len * 6 + 1 + 2
555
556
            if has_sub_averages_data_flag:
557
                current_row_number = (current_row_number + reporting_period_data_ca_len * 6)
558
559
            if has_sub_maximums_data_flag:
560
                current_row_number = (current_row_number + reporting_period_data_ca_len * 6)
561
562
            table_start_row_number = current_row_number
563
564
            has_data = False
565
566
            if len(base_period_timestamps[0]) or len(reporting_period_timestamps[0]) > 0:
567
                has_data = True
568
569
            if has_data:
570
                ws.row_dimensions[current_row_number].height = 60
571
                current_col_number = 2
572
                col = format_cell.get_column_letter(current_col_number)
573
                ws[col + str(current_row_number)].fill = table_fill
574
                ws[col + str(current_row_number)].font = title_font
575
                ws[col + str(current_row_number)].border = f_border
576
                ws[col + str(current_row_number)].alignment = c_c_alignment
577
                ws[col + str(current_row_number)] = _('Base Period') + " - " + _('Datetime')
578
579
                for i in range(0, base_period_data_ca_len):
580
                    if has_sub_averages_data_flag:
581
                        current_col_number += 1
582
                        col = format_cell.get_column_letter(current_col_number)
583
584
                        ws[col + str(current_row_number)].fill = table_fill
585
                        ws[col + str(current_row_number)].font = title_font
586
                        ws[col + str(current_row_number)].alignment = c_c_alignment
587
                        ws[col + str(current_row_number)] = _('Base Period') + " - " \
588
                            + base_period_data['names'][i] + \
589
                            " " + _('Average Load') + "(" + base_period_data['units'][i] + "/H)"
590
                        ws[col + str(current_row_number)].border = f_border
591
592
                    if has_sub_maximums_data_flag:
593
                        current_col_number += 1
594
                        col = format_cell.get_column_letter(current_col_number)
595
596
                        ws[col + str(current_row_number)].fill = table_fill
597
                        ws[col + str(current_row_number)].font = title_font
598
                        ws[col + str(current_row_number)].alignment = c_c_alignment
599
                        ws[col + str(current_row_number)] = _('Base Period') + " - " \
600
                            + base_period_data['names'][i] + \
601
                            " " + _('Maximum Load') + "(" + base_period_data['units'][i] + "/H)"
602
                        ws[col + str(current_row_number)].border = f_border
603
604
                current_col_number += 1
605
                col = format_cell.get_column_letter(current_col_number)
606
607
                ws[col + str(current_row_number)].fill = table_fill
608
                ws[col + str(current_row_number)].font = title_font
609
                ws[col + str(current_row_number)].border = f_border
610
                ws[col + str(current_row_number)].alignment = c_c_alignment
611
                ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime')
612
613
                for i in range(0, reporting_period_data_ca_len):
614
                    if has_sub_averages_data_flag:
615
                        current_col_number += 1
616
                        col = format_cell.get_column_letter(current_col_number)
617
                        ws[col + str(current_row_number)].fill = table_fill
618
                        ws[col + str(current_row_number)].font = title_font
619
                        ws[col + str(current_row_number)].alignment = c_c_alignment
620
                        ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
621
                            + reporting_period_data['names'][i] + \
622
                            " " + _('Average Load') + "(" + reporting_period_data['units'][i] + "/H)"
623
                        ws[col + str(current_row_number)].border = f_border
624
625
                    if has_sub_maximums_data_flag:
626
                        current_col_number += 1
627
                        col = format_cell.get_column_letter(current_col_number)
628
                        ws[col + str(current_row_number)].fill = table_fill
629
                        ws[col + str(current_row_number)].font = title_font
630
                        ws[col + str(current_row_number)].alignment = c_c_alignment
631
                        ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
632
                            + reporting_period_data['names'][i] + \
633
                            " " + _('Maximum Load') + "(" + \
634
                            reporting_period_data['units'][i] + "/H)"
635
                        ws[col + str(current_row_number)].border = f_border
636
637
                current_row_number += 1
638
639
                max_timestamps_len = len(base_period_timestamps[0]) \
640
                    if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \
641
                    else len(reporting_period_timestamps[0])
642
643
                for i in range(0, max_timestamps_len):
644
                    current_col_number = 2
645
                    col = format_cell.get_column_letter(current_col_number)
646
                    ws[col + str(current_row_number)].font = title_font
647
                    ws[col + str(current_row_number)].alignment = c_c_alignment
648
                    ws[col + str(current_row_number)] = base_period_timestamps[0][i] \
649
                        if i < len(base_period_timestamps[0]) else None
650
                    ws[col + str(current_row_number)].border = f_border
651
652
                    for j in range(0, base_period_data_ca_len):
653
                        if has_sub_averages_data_flag:
654
                            current_col_number += 1
655
                            col = format_cell.get_column_letter(current_col_number)
656
657
                            ws[col + str(current_row_number)].font = title_font
658
                            ws[col + str(current_row_number)].alignment = c_c_alignment
659
                            ws[col + str(current_row_number)] = round(base_period_data['sub_averages'][j][i], 2) \
660
                                if i < len(base_period_data['sub_averages'][j]) \
661
                                and base_period_data['sub_averages'][j][i] is not None else None
662
                            ws[col + str(current_row_number)].border = f_border
663
664
                        if has_sub_maximums_data_flag:
665
                            current_col_number += 1
666
                            col = format_cell.get_column_letter(current_col_number)
667
668
                            ws[col + str(current_row_number)].font = title_font
669
                            ws[col + str(current_row_number)].alignment = c_c_alignment
670
                            ws[col + str(current_row_number)] = round(base_period_data['sub_maximums'][j][i], 2) \
671
                                if i < len(base_period_data['sub_maximums'][j]) \
672
                                and base_period_data['sub_averages'][j][i] is not None else None
673
                            ws[col + str(current_row_number)].border = f_border
674
675
                    current_col_number += 1
676
                    col = format_cell.get_column_letter(current_col_number)
677
678
                    ws[col + str(current_row_number)].font = title_font
679
                    ws[col + str(current_row_number)].alignment = c_c_alignment
680
                    ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \
681
                        if i < len(reporting_period_timestamps[0]) else None
682
                    ws[col + str(current_row_number)].border = f_border
683
684
                    for j in range(0, reporting_period_data_ca_len):
685
                        if has_sub_averages_data_flag:
686
                            current_col_number += 1
687
                            col = format_cell.get_column_letter(current_col_number)
688
689
                            ws[col + str(current_row_number)].font = title_font
690
                            ws[col + str(current_row_number)].alignment = c_c_alignment
691
                            ws[col + str(current_row_number)] = round(reporting_period_data['sub_averages'][j][i], 2) \
692
                                if i < len(reporting_period_data['sub_averages'][j]) \
693
                                and reporting_period_data['sub_averages'][j][i] is not None else None
694
                            ws[col + str(current_row_number)].border = f_border
695
696
                        if has_sub_maximums_data_flag:
697
                            current_col_number += 1
698
                            col = format_cell.get_column_letter(current_col_number)
699
700
                            ws[col + str(current_row_number)].font = title_font
701
                            ws[col + str(current_row_number)].alignment = c_c_alignment
702
                            ws[col + str(current_row_number)] = round(reporting_period_data['sub_maximums'][j][i], 2) \
703
                                if i < len(reporting_period_data['sub_maximums'][j]) \
704
                                and reporting_period_data['sub_maximums'][j][i] is not None else None
705
                            ws[col + str(current_row_number)].border = f_border
706
707
                    current_row_number += 1
708
709
                current_chart_col_number = 3
710
                current_chart_row_number = chart_start_number
711
712
                for i in range(0, reporting_period_data_ca_len):
713
                    labels = Reference(ws, min_col=2 + base_period_data_ca_len * 2 + 1,
714
                                       min_row=table_start_row_number + 1,
715
                                       max_row=table_start_row_number + len(reporting_period_timestamps[0]))
716
717
                    if has_sub_averages_data_flag:
718
                        # line
719
                        line = LineChart()
720
                        line.title = _('Base Period Average Load') + ' / ' \
721
                            + _('Reporting Period Average Load') + ' - ' \
722
                            + reporting_period_data['names'][i] + \
723
                            " " + _('Average Load') + "(" + reporting_period_data['units'][i] + "/H)"
724
                        base_line_data = Reference(ws,
725
                                                   min_col=current_chart_col_number,
726
                                                   min_row=table_start_row_number,
727
                                                   max_row=table_start_row_number
728
                                                   + len(reporting_period_timestamps[0]))
729
730
                        data_distance = base_period_data_ca_len
731
                        if has_sub_maximums_data_flag:
732
                            data_distance *= 2
733
734
                        reporting_line_data = Reference(ws,
735
                                                        min_col=current_chart_col_number + data_distance + 1,
736
                                                        min_row=table_start_row_number,
737
                                                        max_row=table_start_row_number
738
                                                        + len(reporting_period_timestamps[0]))
739
                        line.add_data(base_line_data, titles_from_data=True)
740
                        line.add_data(reporting_line_data, titles_from_data=True)
741
                        line.set_categories(labels)
742
                        for j in range(len(line.series)):
743
                            line.series[j].marker.symbol = "circle"
744
                            line.series[j].smooth = True
745
                        line.x_axis.crosses = 'min'
746
                        line.height = 8.25
747
                        line.width = 24
748
                        line.dLbls = DataLabelList()
749
                        line.dLbls.dLblPos = 't'
750
                        line.dLbls.showVal = True
751
                        line.dLbls.showPercent = False
752
                        chart_col = 'B'
753
                        chart_cell = chart_col + str(current_chart_row_number)
754
                        ws.add_chart(line, chart_cell)
755
                        current_chart_row_number += 6
756
                        current_chart_col_number += 1
757
758
                    if has_sub_maximums_data_flag:
759
                        # line
760
                        line = LineChart()
761
                        line.title = _('Base Period Maximum Load') + ' / ' \
762
                            + _('Reporting Period Maximum Load') + ' - ' \
763
                            + reporting_period_data['names'][i] + \
764
                            " " + _('Maximum Load') + "(" + reporting_period_data['units'][i] + "/H)"
765
                        base_line_data = Reference(ws,
766
                                                   min_col=current_chart_col_number,
767
                                                   min_row=table_start_row_number,
768
                                                   max_row=table_start_row_number
769
                                                   + len(reporting_period_timestamps[0]))
770
771
                        data_distance = base_period_data_ca_len
772
                        if has_sub_averages_data_flag:
773
                            data_distance *= 2
774
775
                        reporting_line_data = Reference(ws,
776
                                                        min_col=current_chart_col_number + data_distance + 1,
777
                                                        min_row=table_start_row_number,
778
                                                        max_row=table_start_row_number
779
                                                        + len(reporting_period_timestamps[0]))
780
                        line.add_data(base_line_data, titles_from_data=True)
781
                        line.add_data(reporting_line_data, titles_from_data=True)
782
                        line.set_categories(labels)
783
                        for j in range(len(line.series)):
784
                            line.series[j].marker.symbol = "circle"
785
                            line.series[j].smooth = True
786
                        line.x_axis.crosses = 'min'
787
                        line.height = 8.25
788
                        line.width = 24
789
                        line.dLbls = DataLabelList()
790
                        line.dLbls.dLblPos = 't'
791
                        line.dLbls.showVal = True
792
                        line.dLbls.showPercent = False
793
                        chart_col = 'B'
794
                        chart_cell = chart_col + str(current_chart_row_number)
795
                        ws.add_chart(line, chart_cell)
796
                        current_chart_row_number += 6
797
                        current_chart_col_number += 1
798
799
                current_row_number += 2
800
801
    ####################################################################################################################
802
    current_sheet_parameters_row_number = current_chart_row_number + 1
803
    if 'parameters' not in report.keys() or \
804
            report['parameters'] is None or \
805
            'names' not in report['parameters'].keys() or \
806
            report['parameters']['names'] is None or \
807
            len(report['parameters']['names']) == 0 or \
808
            'timestamps' not in report['parameters'].keys() or \
809
            report['parameters']['timestamps'] is None or \
810
            len(report['parameters']['timestamps']) == 0 or \
811
            'values' not in report['parameters'].keys() or \
812
            report['parameters']['values'] is None or \
813
            len(report['parameters']['values']) == 0 or \
814
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
815
        pass
816
    else:
817
818
        ################################################################################################################
819
        # new worksheet
820
        ################################################################################################################
821
822
        parameters_data = report['parameters']
823
        parameters_names_len = len(parameters_data['names'])
824
825
        file_name = (re.sub(r'[^A-Z]', '', ws.title))+'_'
826
        parameters_ws = wb.create_sheet(file_name + _('Parameters'))
827
828
        parameters_timestamps_data_max_len = \
829
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
830
831
        # Row height
832
        parameters_ws.row_dimensions[1].height = 102
833
        for i in range(2, 7 + 1):
834
            parameters_ws.row_dimensions[i].height = 42
835
836
        for i in range(8, parameters_timestamps_data_max_len + 10):
837
            parameters_ws.row_dimensions[i].height = 60
838
839
        # Col width
840
        parameters_ws.column_dimensions['A'].width = 1.5
841
842
        parameters_ws.column_dimensions['B'].width = 25.0
843
844
        for i in range(3, 12 + parameters_names_len * 3):
845
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
846
847
        # Img
848
        img = Image("excelexporters/myems.png")
849
        parameters_ws.add_image(img, 'A1')
850
851
        # Title
852
        parameters_ws['B3'].alignment = b_r_alignment
853
        parameters_ws['B3'] = _('Name') + ':'
854
        parameters_ws['C3'].border = b_border
855
        parameters_ws['C3'].alignment = b_c_alignment
856
        parameters_ws['C3'] = name
857
858
        parameters_ws['D3'].alignment = b_r_alignment
859
        parameters_ws['D3'] = _('Period Type') + ':'
860
        parameters_ws['E3'].border = b_border
861
        parameters_ws['E3'].alignment = b_c_alignment
862
        parameters_ws['E3'] = period_type
863
864
        parameters_ws['B4'].alignment = b_r_alignment
865
        parameters_ws['B4'] = _('Reporting Start Datetime') + ':'
866
        parameters_ws['C4'].border = b_border
867
        parameters_ws['C4'].alignment = b_c_alignment
868
        parameters_ws['C4'] = reporting_start_datetime_local
869
870
        parameters_ws['D4'].alignment = b_r_alignment
871
        parameters_ws['D4'] = _('Reporting End Datetime') + ':'
872
        parameters_ws['E4'].border = b_border
873
        parameters_ws['E4'].alignment = b_c_alignment
874
        parameters_ws['E4'] = reporting_end_datetime_local
875
876
        parameters_ws_current_row_number = 6
877
878
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
879
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters')
880
881
        parameters_ws_current_row_number += 1
882
883
        parameters_table_start_row_number = parameters_ws_current_row_number
884
885
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
886
887
        parameters_ws_current_row_number += 1
888
889
        table_current_col_number = 2
890
891
        for i in range(0, parameters_names_len):
892
893
            if len(parameters_data['timestamps'][i]) == 0:
894
                continue
895
896
            col = format_cell.get_column_letter(table_current_col_number)
897
898
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
899
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
900
901
            col = format_cell.get_column_letter(table_current_col_number + 1)
902
903
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
904
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
905
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
906
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
907
            parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
908
909
            table_current_row_number = parameters_ws_current_row_number
910
911
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
912
                col = format_cell.get_column_letter(table_current_col_number)
913
914
                parameters_ws[col + str(table_current_row_number)].border = f_border
915
                parameters_ws[col + str(table_current_row_number)].font = title_font
916
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
917
                parameters_ws[col + str(table_current_row_number)] = value
918
919
                col = format_cell.get_column_letter(table_current_col_number + 1)
920
921
                parameters_ws[col + str(table_current_row_number)].border = f_border
922
                parameters_ws[col + str(table_current_row_number)].font = title_font
923
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
924
                parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
925
926
                table_current_row_number += 1
927
928
            table_current_col_number = table_current_col_number + 3
929
930
        ################################################################################################################
931
        # parameters chart and parameters table
932
        ################################################################################################################
933
934
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
935
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters')
936
937
        current_sheet_parameters_row_number += 1
938
939
        chart_start_row_number = current_sheet_parameters_row_number
940
941
        col_index = 0
942
943
        for i in range(0, parameters_names_len):
944
945
            if len(parameters_data['timestamps'][i]) == 0:
946
                continue
947
948
            line = LineChart()
949
            data_col = 3 + col_index * 3
950
            labels_col = 2 + col_index * 3
951
            col_index += 1
952
            line.title = _('Parameters') + ' - ' + \
953
                parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
954
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
955
                               max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
956
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
957
                                  max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
958
            line.add_data(line_data, titles_from_data=True)
959
            line.set_categories(labels)
960
            line_data = line.series[0]
961
            line_data.marker.symbol = "circle"
962
            line_data.smooth = True
963
            line.x_axis.crosses = 'min'
964
            line.height = 8.25
965
            line.width = 24
966
            line.dLbls = DataLabelList()
967
            line.dLbls.dLblPos = 't'
968
            line.dLbls.showVal = False
969
            line.dLbls.showPercent = False
970
            chart_col = 'B'
971
            chart_cell = chart_col + str(chart_start_row_number)
972
            chart_start_row_number += 6
973
            ws.add_chart(line, chart_cell)
974
975
        current_sheet_parameters_row_number = chart_start_row_number
976
977
        current_sheet_parameters_row_number += 1
978
    ####################################################################################################################
979
    filename = str(uuid.uuid4()) + '.xlsx'
980
    wb.save(filename)
981
982
    return filename
983
984
985
def timestamps_data_all_equal_0(lists):
986
    for i, value in enumerate(list(lists)):
987
        if len(value) > 0:
988
            return False
989
990
    return True
991
992
993
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
994
    max_len = 0
995
    for i, value in enumerate(list(parameters_timestamps_lists)):
996
        if len(value) > max_len:
997
            max_len = len(value)
998
999
    return max_len
1000
1001
1002
def timestamps_data_not_equal_0(lists):
1003
    number = 0
1004
    for i, value in enumerate(list(lists)):
1005
        if len(value) > 0:
1006
            number += 1
1007
    return number
1008
1009
1010 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...
1011
    timestamps = base_period_data['timestamps']
1012
1013
    if len(timestamps) == 0:
1014
        return False
1015
1016
    for timestamp in timestamps:
1017
        if len(timestamp) > 0:
1018
            return True
1019
1020
    return False
1021