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

is_base_period_timestamp_exists()   A

Complexity

Conditions 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 11
Ratio 100 %

Importance

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