Issues (1577)

excelexporters/combinedequipmentsaving.py (4 issues)

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