Passed
Push — master ( ef3fde...570acf )
by Guangyu
06:33 queued 12s
created

generate_excel()   F

Complexity

Conditions 75

Size

Total Lines 757
Code Lines 572

Duplication

Lines 757
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 572
dl 757
loc 757
rs 0
c 0
b 0
f 0
cc 75
nop 5

How to fix   Long Method    Complexity   

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.combinedequipmentcarbon.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.

1
import base64
2
import uuid
3
import os
4
import re
5
from decimal import Decimal
6
from openpyxl.chart import PieChart, LineChart, Reference
7
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
8
from openpyxl.drawing.image import Image
9
from openpyxl import Workbook
10
from openpyxl.chart.label import DataLabelList
11
import openpyxl.utils.cell as format_cell
12
13
14
########################################################################################################################
15
# PROCEDURES
16
# Step 1: Validate the report data
17
# Step 2: Generate excel file
18
# Step 3: Encode the excel file bytes to Base64
19
########################################################################################################################
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
           reporting_start_datetime_local,
25
           reporting_end_datetime_local,
26
           period_type):
27
    ####################################################################################################################
28
    # Step 1: Validate the report data
29
    ####################################################################################################################
30
    if report is None:
31
        return None
32
    print(report)
33
34
    ####################################################################################################################
35
    # Step 2: Generate excel file from the report data
36
    ####################################################################################################################
37
    filename = generate_excel(report,
38
                              name,
39
                              reporting_start_datetime_local,
40
                              reporting_end_datetime_local,
41
                              period_type)
42
    ####################################################################################################################
43
    # Step 3: Encode the excel file to Base64
44
    ####################################################################################################################
45
    binary_file_data = b''
46
    try:
47
        with open(filename, 'rb') as binary_file:
48
            binary_file_data = binary_file.read()
49
    except IOError as ex:
50
        pass
51
52
    # Base64 encode the bytes
53
    base64_encoded_data = base64.b64encode(binary_file_data)
54
    # get the Base64 encoded data using human-readable characters.
55
    base64_message = base64_encoded_data.decode('utf-8')
56
    # delete the file from server
57
    try:
58
        os.remove(filename)
59
    except NotImplementedError as ex:
60
        pass
61
    return base64_message
62
63
64 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...
65
                   name,
66
                   reporting_start_datetime_local,
67
                   reporting_end_datetime_local,
68
                   period_type):
69
    wb = Workbook()
70
    ws = wb.active
71
    ws.title = "CombinedEquipmentCarbon"
72
73
    # Row height
74
    ws.row_dimensions[1].height = 102
75
    for i in range(2, 2000 + 1):
76
        ws.row_dimensions[i].height = 42
77
78
    # Col width
79
    ws.column_dimensions['A'].width = 1.5
80
81
    ws.column_dimensions['B'].width = 25.0
82
83
    for i in range(ord('C'), ord('L')):
84
        ws.column_dimensions[chr(i)].width = 15.0
85
86
    # Font
87
    name_font = Font(name='Arial', size=15, bold=True)
88
    title_font = Font(name='Arial', size=15, bold=True)
89
90
    table_fill = PatternFill(fill_type='solid', fgColor='1F497D')
91
    f_border = Border(left=Side(border_style='medium', color='00000000'),
92
                      right=Side(border_style='medium', color='00000000'),
93
                      bottom=Side(border_style='medium', color='00000000'),
94
                      top=Side(border_style='medium', color='00000000')
95
                      )
96
    b_border = Border(
97
        bottom=Side(border_style='medium', color='00000000'),
98
    )
99
100
    b_c_alignment = Alignment(vertical='bottom',
101
                              horizontal='center',
102
                              text_rotation=0,
103
                              wrap_text=True,
104
                              shrink_to_fit=False,
105
                              indent=0)
106
    c_c_alignment = Alignment(vertical='center',
107
                              horizontal='center',
108
                              text_rotation=0,
109
                              wrap_text=True,
110
                              shrink_to_fit=False,
111
                              indent=0)
112
    b_r_alignment = Alignment(vertical='bottom',
113
                              horizontal='right',
114
                              text_rotation=0,
115
                              wrap_text=True,
116
                              shrink_to_fit=False,
117
                              indent=0)
118
119
    # Img
120
    img = Image("excelexporters/myems.png")
121
    ws.add_image(img, 'A1')
122
123
    # Title=
124
    ws['B3'].alignment = b_r_alignment
125
    ws['B3'] = 'Name:'
126
    ws['C3'].border = b_border
127
    ws['C3'].alignment = b_c_alignment
128
    ws['C3'] = name
129
130
    ws['D3'].alignment = b_r_alignment
131
    ws['D3'] = 'Period:'
132
    ws['E3'].border = b_border
133
    ws['E3'].alignment = b_c_alignment
134
    ws['E3'] = period_type
135
136
    ws['B4'].alignment = b_r_alignment
137
    ws['B4'] = 'Reporting Start Datetime:'
138
    ws['C4'].border = b_border
139
    ws['C4'].alignment = b_c_alignment
140
    ws['C4'] = reporting_start_datetime_local
141
142
    ws['D4'].alignment = b_r_alignment
143
    ws['D4'] = 'Reporting End Datetime:'
144
    ws['E4'].border = b_border
145
    ws['E4'].alignment = b_c_alignment
146
    ws['E4'] = reporting_end_datetime_local
147
148
    if "reporting_period" not in report.keys() or \
149
            "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0:
150
        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...
151
        wb.save(filename)
152
153
        return filename
154
155
    reporting_period_data = report['reporting_period']
156
157
    has_energy_data_flag = True
158
    if "names" not in reporting_period_data.keys() or \
159
            reporting_period_data['names'] is None or \
160
            len(reporting_period_data['names']) == 0:
161
        has_energy_data_flag = False
162
163
    if has_energy_data_flag:
164
        ws['B6'].font = title_font
165
        ws['B6'] = name + ' ' + 'Reporting Period Carbon Dioxide Emissions'
166
167
        category = reporting_period_data['names']
168
        ca_len = len(category)
169
170
        ws.row_dimensions[7].height = 60
171
        ws['B7'].fill = table_fill
172
        ws['B7'].border = f_border
173
174
        ws['B8'].font = title_font
175
        ws['B8'].alignment = c_c_alignment
176
        ws['B8'] = 'Carbon Dioxide Emissions'
177
        ws['B8'].border = f_border
178
179
        ws['B9'].font = title_font
180
        ws['B9'].alignment = c_c_alignment
181
        ws['B9'] = 'Increment Rate'
182
        ws['B9'].border = f_border
183
184
        col = 'B'
185
186
        for i in range(0, ca_len):
187
            col = chr(ord('C') + i)
188
            ws[col + '7'].fill = table_fill
189
            ws[col + '7'].font = name_font
190
            ws[col + '7'].alignment = c_c_alignment
191
            ws[col + '7'] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
192
            ws[col + '7'].border = f_border
193
194
            ws[col + '8'].font = name_font
195
            ws[col + '8'].alignment = c_c_alignment
196
            ws[col + '8'] = round(reporting_period_data['subtotals'][i], 2)
197
            ws[col + '8'].border = f_border
198
199
            ws[col + '9'].font = name_font
200
            ws[col + '9'].alignment = c_c_alignment
201
            ws[col + '9'] = str(round(reporting_period_data['increment_rates'][i] * 100, 2)) + "%" \
202
                if reporting_period_data['increment_rates'][i] is not None else "-"
203
            ws[col + '9'].border = f_border
204
205
        end_col = chr(ord(col) + 1)
206
        ws[end_col + '7'].fill = table_fill
207
        ws[end_col + '7'].font = name_font
208
        ws[end_col + '7'].alignment = c_c_alignment
209
        ws[end_col + '7'] = "Total (" + reporting_period_data['total_unit'] + ")"
210
        ws[end_col + '7'].border = f_border
211
212
        ws[end_col + '8'].font = name_font
213
        ws[end_col + '8'].alignment = c_c_alignment
214
        ws[end_col + '8'] = round(reporting_period_data['total'], 2)
215
        ws[end_col + '8'].border = f_border
216
217
        ws[end_col + '9'].font = name_font
218
        ws[end_col + '9'].alignment = c_c_alignment
219
        ws[end_col + '9'] = str(round(reporting_period_data['total_increment_rate'] * 100, 2)) + "%" \
220
            if reporting_period_data['total_increment_rate'] is not None else "-"
221
        ws[end_col + '9'].border = f_border
222
223
    else:
224
        for i in range(6, 9 + 1):
225
            ws.row_dimensions[i].height = 0.1
226
227
    has_ele_peak_flag = True
228
    if "toppeaks" not in reporting_period_data.keys() or \
229
            reporting_period_data['toppeaks'] is None or \
230
            len(reporting_period_data['toppeaks']) == 0:
231
        has_ele_peak_flag = False
232
233
    if has_ele_peak_flag:
234
        ws['B12'].font = title_font
235
        ws['B12'] = name + 'Electricity Carbon Dioxide Emissions by Time-Of-Use'
236
237
        ws['B13'].fill = table_fill
238
        ws['B13'].font = name_font
239
        ws['B13'].alignment = c_c_alignment
240
        ws['B13'].border = f_border
241
242
        ws['C13'].fill = table_fill
243
        ws['C13'].font = name_font
244
        ws['C13'].alignment = c_c_alignment
245
        ws['C13'].border = f_border
246
        ws['C13'] = 'Electricity Carbon Dioxide Emissions by Time-Of-Use'
247
248
        ws['D13'].fill = table_fill
249
        ws['D13'].font = name_font
250
        ws['D13'].alignment = c_c_alignment
251
        ws['D13'].border = f_border
252
        ws['D13'] = 'Electricity Carbon Dioxide Emissions Proportion by Time-Of-Use'
253
254
        carbonsum = round(reporting_period_data['toppeaks'][0], 2) + round(reporting_period_data['onpeaks'][0], 2) + \
255
            round(reporting_period_data['midpeaks'][0], 2) + round(reporting_period_data['offpeaks'][0], 2)
256
257
        ws['B14'].font = title_font
258
        ws['B14'].alignment = c_c_alignment
259
        ws['B14'] = 'TopPeak'
260
        ws['B14'].border = f_border
261
262
        ws['C14'].font = title_font
263
        ws['C14'].alignment = c_c_alignment
264
        ws['C14'].border = f_border
265
        ws['C14'] = round(reporting_period_data['toppeaks'][0], 2)
266
267
        ws['D14'].font = title_font
268
        ws['D14'].alignment = c_c_alignment
269
        ws['D14'].border = f_border
270
        ws['D14'] = '{:.2%}'.format(round(reporting_period_data['toppeaks'][0], 2) / carbonsum) \
271
            if carbonsum is not None and carbonsum != Decimal(0.0) else " "
272
273
        ws['B15'].font = title_font
274
        ws['B15'].alignment = c_c_alignment
275
        ws['B15'] = 'OnPeak'
276
        ws['B15'].border = f_border
277
278
        ws['C15'].font = title_font
279
        ws['C15'].alignment = c_c_alignment
280
        ws['C15'].border = f_border
281
        ws['C15'] = round(reporting_period_data['onpeaks'][0], 2)
282
283
        ws['D15'].font = title_font
284
        ws['D15'].alignment = c_c_alignment
285
        ws['D15'].border = f_border
286
        ws['D15'] = '{:.2%}'.format(round(reporting_period_data['onpeaks'][0], 2) / carbonsum) \
287
            if carbonsum is not None and carbonsum != Decimal(0.0) else " "
288
289
        ws['B16'].font = title_font
290
        ws['B16'].alignment = c_c_alignment
291
        ws['B16'] = 'MidPeak'
292
        ws['B16'].border = f_border
293
294
        ws['C16'].font = title_font
295
        ws['C16'].alignment = c_c_alignment
296
        ws['C16'].border = f_border
297
        ws['C16'] = round(reporting_period_data['midpeaks'][0], 2)
298
299
        ws['D16'].font = title_font
300
        ws['D16'].alignment = c_c_alignment
301
        ws['D16'].border = f_border
302
        ws['D16'] = '{:.2%}'.format(round(reporting_period_data['midpeaks'][0], 2) / carbonsum) \
303
            if carbonsum is not None and carbonsum != Decimal(0.0) else " "
304
305
        ws['B17'].font = title_font
306
        ws['B17'].alignment = c_c_alignment
307
        ws['B17'] = 'OffPeak'
308
        ws['B17'].border = f_border
309
310
        ws['C17'].font = title_font
311
        ws['C17'].alignment = c_c_alignment
312
        ws['C17'].border = f_border
313
        ws['C17'] = round(reporting_period_data['offpeaks'][0], 2)
314
315
        ws['D17'].font = title_font
316
        ws['D17'].alignment = c_c_alignment
317
        ws['D17'].border = f_border
318
        ws['D17'] = '{:.2%}'.format(round(reporting_period_data['offpeaks'][0], 2) / carbonsum) \
319
            if carbonsum is not None and carbonsum != Decimal(0.0) else " "
320
321
        pie = PieChart()
322
        pie.title = name + 'Electricity Carbon Dioxide Emissions by Time-Of-Use'
323
        labels = Reference(ws, min_col=2, min_row=14, max_row=17)
324
        pie_data = Reference(ws, min_col=3, min_row=13, max_row=17)
325
        pie.add_data(pie_data, titles_from_data=True)
326
        pie.set_categories(labels)
327
        pie.height = 6.6
328
        pie.width = 9
329
        s1 = pie.series[0]
330
        s1.dLbls = DataLabelList()
331
        s1.dLbls.showCatName = False
332
        s1.dLbls.showVal = True
333
        s1.dLbls.showPercent = True
334
        ws.add_chart(pie, "E13")
335
336
    else:
337
        for i in range(12, 18 + 1):
338
            ws.row_dimensions[i].height = 0.1
339
340
    ################################################
341
342
    current_row_number = 19
343
344
    has_subtotals_data_flag = True
345
    if "subtotals" not in reporting_period_data.keys() or \
346
            reporting_period_data['subtotals'] is None or \
347
            len(reporting_period_data['subtotals']) == 0:
348
        has_subtotals_data_flag = False
349
350
    if has_subtotals_data_flag:
351
        ws['B' + str(current_row_number)].font = title_font
352
        ws['B' + str(current_row_number)] = name + ' ' + 'Carbon Dioxide Emissions Proportion'
353
354
        current_row_number += 1
355
356
        table_start_row_number = current_row_number
357
358
        ws['B' + str(current_row_number)].fill = table_fill
359
        ws['B' + str(current_row_number)].font = name_font
360
        ws['B' + str(current_row_number)].alignment = c_c_alignment
361
        ws['B' + str(current_row_number)].border = f_border
362
363
        ws['C' + str(current_row_number)].fill = table_fill
364
        ws['C' + str(current_row_number)].font = name_font
365
        ws['C' + str(current_row_number)].alignment = c_c_alignment
366
        ws['C' + str(current_row_number)].border = f_border
367
        ws['C' + str(current_row_number)] = 'Carbon Dioxide Emissions'
368
369
        ws['D' + str(current_row_number)].fill = table_fill
370
        ws['D' + str(current_row_number)].font = name_font
371
        ws['D' + str(current_row_number)].alignment = c_c_alignment
372
        ws['D' + str(current_row_number)].border = f_border
373
        ws['D' + str(current_row_number)] = 'Carbon Dioxide Emissions Proportion'
374
375
        current_row_number += 1
376
377
        ca_len = len(reporting_period_data['names'])
378
        carbonsum = Decimal(0.0)
379
        for i in range(0, ca_len):
380
            carbonsum = round(reporting_period_data['subtotals'][i], 2) + carbonsum
381
        for i in range(0, ca_len):
382
            ws['B' + str(current_row_number)].font = title_font
383
            ws['B' + str(current_row_number)].alignment = c_c_alignment
384
            ws['B' + str(current_row_number)] = reporting_period_data['names'][i]
385
            ws['B' + str(current_row_number)].border = f_border
386
387
            ws['C' + str(current_row_number)].font = title_font
388
            ws['C' + str(current_row_number)].alignment = c_c_alignment
389
            ws['C' + str(current_row_number)].border = f_border
390
            ws['C' + str(current_row_number)] = round(reporting_period_data['subtotals'][i], 2)
391
392
            ws['D' + str(current_row_number)].font = title_font
393
            ws['D' + str(current_row_number)].alignment = c_c_alignment
394
            ws['D' + str(current_row_number)].border = f_border
395
            ws['D' + str(current_row_number)] = '{:.2%}'.format(round(
396
                reporting_period_data['subtotals'][i], 2) / carbonsum) if \
397
                carbonsum is not None and carbonsum != Decimal(0.0) else " "
398
            current_row_number += 1
399
400
        table_end_row_number = current_row_number - 1
401
402
        pie = PieChart()
403
        pie.title = name + ' ' + 'Carbon Dioxide Emissions Proportion'
404
        labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
405
        pie_data = Reference(ws, min_col=3, min_row=table_start_row_number, max_row=table_end_row_number)
406
        pie.add_data(pie_data, titles_from_data=True)
407
        pie.set_categories(labels)
408
        pie.height = 6.6
409
        pie.width = 9
410
        s1 = pie.series[0]
411
        s1.dLbls = DataLabelList()
412
        s1.dLbls.showCatName = False
413
        s1.dLbls.showVal = True
414
        s1.dLbls.showPercent = True
415
        table_cell = 'E' + str(table_start_row_number)
416
        ws.add_chart(pie, table_cell)
417
418
        if ca_len < 4:
419
            current_row_number = current_row_number - ca_len + 4
420
421
    else:
422
        for i in range(21, 29 + 1):
423
            current_row_number = 30
424
            ws.row_dimensions[i].height = 0.1
425
426
    ###############################################
427
428
    current_row_number += 1
429
430
    has_detail_data_flag = True
431
432
    table_start_draw_flag = current_row_number + 1
433
434
    if "timestamps" not in reporting_period_data.keys() or \
435
            reporting_period_data['timestamps'] is None or \
436
            len(reporting_period_data['timestamps']) == 0:
437
        has_detail_data_flag = False
438
439
    if has_detail_data_flag:
440
        reporting_period_data = report['reporting_period']
441
        times = reporting_period_data['timestamps']
442
        ca_len = len(report['reporting_period']['names'])
443
        real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
444
        ws['B' + str(current_row_number)].font = title_font
445
        ws['B' + str(current_row_number)] = name + ' ' + 'Detailed Data'
446
447
        table_start_row_number = (current_row_number + 1) + ca_len * 6 + real_timestamps_len * 7
448
        current_row_number = table_start_row_number
449
450
        time = times[0]
451
        has_data = False
452
453
        if len(time) > 0:
454
            has_data = True
455
456
        if has_data:
457
458
            ws.row_dimensions[current_row_number].height = 60
459
            ws['B' + str(current_row_number)].fill = table_fill
460
            ws['B' + str(current_row_number)].border = f_border
461
            ws['B' + str(current_row_number)].font = title_font
462
            ws['B' + str(current_row_number)].alignment = c_c_alignment
463
            ws['B' + str(current_row_number)] = 'Datetime'
464
465
            col = 'B'
466
467
            for i in range(0, ca_len):
468
                col = chr(ord('C') + i)
469
470
                ws[col + str(current_row_number)].fill = table_fill
471
                ws[col + str(current_row_number)].font = title_font
472
                ws[col + str(current_row_number)].alignment = c_c_alignment
473
                ws[col + str(current_row_number)] = \
474
                    reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
475
                ws[col + str(current_row_number)].border = f_border
476
477
            end_col = chr(ord(col) + 1)
478
479
            ws[end_col + str(current_row_number)].fill = table_fill
480
            ws[end_col + str(current_row_number)].font = title_font
481
            ws[end_col + str(current_row_number)].alignment = c_c_alignment
482
            ws[end_col + str(current_row_number)] = "Total (" + reporting_period_data['total_unit'] + ")"
483
            ws[end_col + str(current_row_number)].border = f_border
484
485
            current_row_number += 1
486
487
            for i in range(0, len(time)):
488
                ws['B' + str(current_row_number)].font = title_font
489
                ws['B' + str(current_row_number)].alignment = c_c_alignment
490
                ws['B' + str(current_row_number)] = time[i]
491
                ws['B' + str(current_row_number)].border = f_border
492
493
                col = 'B'
494
495
                periodic_sum = Decimal(0.0)
496
497
                for j in range(0, ca_len):
498
                    col = chr(ord('C') + j)
499
500
                    ws[col + str(current_row_number)].font = title_font
501
                    ws[col + str(current_row_number)].alignment = c_c_alignment
502
                    value = round(reporting_period_data['values'][j][i], 2)
503
                    periodic_sum += value
504
                    ws[col + str(current_row_number)] = value
505
                    ws[col + str(current_row_number)].border = f_border
506
507
                end_col = chr(ord(col) + 1)
508
                ws[end_col + str(current_row_number)].font = title_font
509
                ws[end_col + str(current_row_number)].alignment = c_c_alignment
510
                ws[end_col + str(current_row_number)] = round(periodic_sum, 2)
511
                ws[end_col + str(current_row_number)].border = f_border
512
513
                current_row_number += 1
514
515
            table_end_row_number = current_row_number - 1
516
517
            ws['B' + str(current_row_number)].font = title_font
518
            ws['B' + str(current_row_number)].alignment = c_c_alignment
519
            ws['B' + str(current_row_number)] = 'Subtotal'
520
            ws['B' + str(current_row_number)].border = f_border
521
522
            col = 'B'
523
524
            for i in range(0, ca_len):
525
                col = chr(ord('C') + i)
526
                ws[col + str(current_row_number)].font = title_font
527
                ws[col + str(current_row_number)].alignment = c_c_alignment
528
                ws[col + str(current_row_number)] = round(reporting_period_data['subtotals'][i], 2)
529
                ws[col + str(current_row_number)].border = f_border
530
531
                # line
532
                line = LineChart()
533
                line.title = 'Reporting Period Carbon Dioxide Emissions - ' + \
534
                             ws.cell(column=3 + i, row=table_start_row_number).value
535
                labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
536
                line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number, max_row=table_end_row_number)
537
                line.add_data(line_data, titles_from_data=True)
538
                line.set_categories(labels)
539
                line_data = line.series[0]
540
                line_data.marker.symbol = "circle"
541
                line_data.smooth = True
542
                line.x_axis.crosses = 'min'
543
                line.height = 8.25
544
                line.width = 24
545
                line.dLbls = DataLabelList()
546
                line.dLbls.dLblPos = 't'
547
                line.dLbls.showVal = True
548
                line.dLbls.showPercent = False
549
                chart_col = 'B'
550
                chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
551
                ws.add_chart(line, chart_cell)
552
553
            end_col = chr(ord(col) + 1)
554
            ws[end_col + str(current_row_number)].font = title_font
555
            ws[end_col + str(current_row_number)].alignment = c_c_alignment
556
            ws[end_col + str(current_row_number)] = round(reporting_period_data['total'], 2)
557
            ws[end_col + str(current_row_number)].border = f_border
558
559
            current_row_number += 1
560
561
    else:
562
        for i in range(30, 69 + 1):
563
            current_row_number = 70
564
            ws.row_dimensions[i].height = 0.1
565
566
    ####################################################################################################################
567
568
    has_associated_equipment_flag = True
569
570
    if "associated_equipment" not in report.keys() or \
571
            "energy_category_names" not in report['associated_equipment'].keys() or \
572
            len(report['associated_equipment']["energy_category_names"]) == 0 \
573
            or 'associated_equipment_names_array' not in report['associated_equipment'].keys() \
574
            or report['associated_equipment']['associated_equipment_names_array'] is None \
575
            or len(report['associated_equipment']['associated_equipment_names_array']) == 0 \
576
            or len(report['associated_equipment']['associated_equipment_names_array'][0]) == 0:
577
        has_associated_equipment_flag = False
578
579
    if has_associated_equipment_flag:
580
        associated_equipment = report['associated_equipment']
581
        current_row_number += 1
582
583
        ws['B' + str(current_row_number)].font = title_font
584
        ws['B' + str(current_row_number)] = name + ' ' + 'Associated Equipment Data'
585
586
        current_row_number += 1
587
588
        ws.row_dimensions[current_row_number].height = 60
589
        ws['B' + str(current_row_number)].fill = table_fill
590
        ws['B' + str(current_row_number)].font = name_font
591
        ws['B' + str(current_row_number)].alignment = c_c_alignment
592
        ws['B' + str(current_row_number)].border = f_border
593
        ws['B' + str(current_row_number)] = 'Associated Equipment'
594
        ca_len = len(associated_equipment['energy_category_names'])
595
596
        for i in range(0, ca_len):
597
            col = chr(ord('C') + i)
598
            ws[col + str(current_row_number)].fill = table_fill
599
            ws[col + str(current_row_number)].font = name_font
600
            ws[col + str(current_row_number)].alignment = c_c_alignment
601
            ws[col + str(current_row_number)].border = f_border
602
            ws[col + str(current_row_number)] = \
603
                reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
604
605
        end_col = chr(ord('B') + ca_len + 1)
606
        ws[end_col + str(current_row_number)].fill = table_fill
607
        ws[end_col + str(current_row_number)].font = name_font
608
        ws[end_col + str(current_row_number)].alignment = c_c_alignment
609
        ws[end_col + str(current_row_number)].border = f_border
610
        ws[end_col + str(current_row_number)] = "Total" + " (" + reporting_period_data['units'][i] + ")"
0 ignored issues
show
introduced by
The variable i does not seem to be defined in case the for loop on line 75 is not entered. Are you sure this can never be the case?
Loading history...
611
612
        associated_equipment_len = len(associated_equipment['associated_equipment_names_array'][0])
613
614
        for i in range(0, associated_equipment_len):
615
            current_row_number += 1
616
            row = str(current_row_number)
617
            value = Decimal(0.0)
618
619
            ws['B' + row].font = title_font
620
            ws['B' + row].alignment = c_c_alignment
621
            ws['B' + row] = associated_equipment['associated_equipment_names_array'][0][i]
622
            ws['B' + row].border = f_border
623
624
            for j in range(0, ca_len):
625
                col = chr(ord('C') + j)
626
                ws[col + row].font = title_font
627
                ws[col + row].alignment = c_c_alignment
628
                ws[col + row] = round(associated_equipment['subtotals_array'][j][i], 2)
629
                value += round(associated_equipment['subtotals_array'][j][i], 2)
630
                ws[col + row].border = f_border
631
632
            end_col = chr(ord(col) + 1)
0 ignored issues
show
introduced by
The variable col does not seem to be defined for all execution paths.
Loading history...
633
            ws[end_col + row].font = title_font
634
            ws[end_col + row].alignment = c_c_alignment
635
            ws[end_col + row] = round(value, 2)
636
            ws[end_col + row].border = f_border
637
638
    ####################################################################################################################
639
    current_sheet_parameters_row_number = table_start_draw_flag + ca_len * 6 + 1
0 ignored issues
show
introduced by
The variable ca_len does not seem to be defined for all execution paths.
Loading history...
640
    has_parameters_names_and_timestamps_and_values_data = True
641
    if 'parameters' not in report.keys() or \
642
            report['parameters'] is None or \
643
            'names' not in report['parameters'].keys() or \
644
            report['parameters']['names'] is None or \
645
            len(report['parameters']['names']) == 0 or \
646
            'timestamps' not in report['parameters'].keys() or \
647
            report['parameters']['timestamps'] is None or \
648
            len(report['parameters']['timestamps']) == 0 or \
649
            'values' not in report['parameters'].keys() or \
650
            report['parameters']['values'] is None or \
651
            len(report['parameters']['values']) == 0 or \
652
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
653
        has_parameters_names_and_timestamps_and_values_data = False
654
    if has_parameters_names_and_timestamps_and_values_data:
655
656
        ###############################
657
        # new worksheet
658
        ###############################
659
660
        parameters_data = report['parameters']
661
        parameters_names_len = len(parameters_data['names'])
662
663
        file_name = (re.sub(r'[^A-Z]', '', ws.title))+'_'
664
        parameters_ws = wb.create_sheet(file_name + 'Parameters')
665
666
        parameters_timestamps_data_max_len = \
667
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
668
669
        # Row height
670
        parameters_ws.row_dimensions[1].height = 102
671
        for i in range(2, 7 + 1):
672
            parameters_ws.row_dimensions[i].height = 42
673
674
        for i in range(8, parameters_timestamps_data_max_len + 10):
675
            parameters_ws.row_dimensions[i].height = 60
676
677
        # Col width
678
        parameters_ws.column_dimensions['A'].width = 1.5
679
680
        parameters_ws.column_dimensions['B'].width = 25.0
681
682
        for i in range(3, 12 + parameters_names_len * 3):
683
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
684
685
        # Img
686
        img = Image("excelexporters/myems.png")
687
        parameters_ws.add_image(img, 'A1')
688
689
        # Title
690
        parameters_ws['B3'].alignment = b_r_alignment
691
        parameters_ws['B3'] = 'Name:'
692
        parameters_ws['C3'].border = b_border
693
        parameters_ws['C3'].alignment = b_c_alignment
694
        parameters_ws['C3'] = name
695
696
        parameters_ws['D3'].alignment = b_r_alignment
697
        parameters_ws['D3'] = 'Period:'
698
        parameters_ws['E3'].border = b_border
699
        parameters_ws['E3'].alignment = b_c_alignment
700
        parameters_ws['E3'] = period_type
701
702
        parameters_ws['B4'].alignment = b_r_alignment
703
        parameters_ws['B4'] = 'Reporting Start Datetime:'
704
        parameters_ws['C4'].border = b_border
705
        parameters_ws['C4'].alignment = b_c_alignment
706
        parameters_ws['C4'] = reporting_start_datetime_local
707
708
        parameters_ws['D4'].alignment = b_r_alignment
709
        parameters_ws['D4'] = 'Reporting End Datetime:'
710
        parameters_ws['E4'].border = b_border
711
        parameters_ws['E4'].alignment = b_c_alignment
712
        parameters_ws['E4'] = reporting_end_datetime_local
713
714
        parameters_ws_current_row_number = 6
715
716
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
717
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + 'Parameters'
718
719
        parameters_ws_current_row_number += 1
720
721
        parameters_table_start_row_number = parameters_ws_current_row_number
722
723
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
724
725
        parameters_ws_current_row_number += 1
726
727
        table_current_col_number = 2
728
729
        for i in range(0, parameters_names_len):
730
731
            if len(parameters_data['timestamps'][i]) == 0:
732
                continue
733
734
            col = format_cell.get_column_letter(table_current_col_number)
735
736
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
737
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
738
739
            col = format_cell.get_column_letter(table_current_col_number + 1)
740
741
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
742
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
743
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
744
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
745
            parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
746
747
            table_current_row_number = parameters_ws_current_row_number
748
749
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
750
                col = format_cell.get_column_letter(table_current_col_number)
751
752
                parameters_ws[col + str(table_current_row_number)].border = f_border
753
                parameters_ws[col + str(table_current_row_number)].font = title_font
754
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
755
                parameters_ws[col + str(table_current_row_number)] = value
756
757
                col = format_cell.get_column_letter(table_current_col_number + 1)
758
759
                parameters_ws[col + str(table_current_row_number)].border = f_border
760
                parameters_ws[col + str(table_current_row_number)].font = title_font
761
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
762
                parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
763
764
                table_current_row_number += 1
765
766
            table_current_col_number = table_current_col_number + 3
767
768
        ################################################################################################################
769
        # parameters chart and parameters table
770
        ################################################################################################################
771
772
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
773
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + 'Parameters'
774
775
        current_sheet_parameters_row_number += 1
776
777
        chart_start_row_number = current_sheet_parameters_row_number
778
779
        col_index = 0
780
781
        for i in range(0, parameters_names_len):
782
783
            if len(parameters_data['timestamps'][i]) == 0:
784
                continue
785
786
            line = LineChart()
787
            data_col = 3 + col_index * 3
788
            labels_col = 2 + col_index * 3
789
            col_index += 1
790
            line.title = 'Parameters - ' + \
791
                         parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
792
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
793
                               max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
794
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
795
                                  max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
796
            line.add_data(line_data, titles_from_data=True)
797
            line.set_categories(labels)
798
            line_data = line.series[0]
799
            line_data.marker.symbol = "circle"
800
            line_data.smooth = True
801
            line.x_axis.crosses = 'min'
802
            line.height = 8.25
803
            line.width = 24
804
            line.dLbls = DataLabelList()
805
            line.dLbls.dLblPos = 't'
806
            line.dLbls.showVal = False
807
            line.dLbls.showPercent = False
808
            chart_col = 'B'
809
            chart_cell = chart_col + str(chart_start_row_number)
810
            chart_start_row_number += 6
811
            ws.add_chart(line, chart_cell)
812
813
        current_sheet_parameters_row_number = chart_start_row_number
814
815
        current_sheet_parameters_row_number += 1
816
    ####################################################################################################################
817
    filename = str(uuid.uuid4()) + '.xlsx'
818
    wb.save(filename)
819
820
    return filename
821
822
823
def timestamps_data_all_equal_0(lists):
824
    for i, value in enumerate(list(lists)):
825
        if len(value) > 0:
826
            return False
827
828
    return True
829
830
831
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
832
    max_len = 0
833
    for i, value in enumerate(list(parameters_timestamps_lists)):
834
        if len(value) > max_len:
835
            max_len = len(value)
836
837
    return max_len
838
839
840
def timestamps_data_not_equal_0(lists):
841
    number = 0
842
    for i, value in enumerate(list(lists)):
843
        if len(value) > 0:
844
            number += 1
845
    return number
846