Issues (1577)

excelexporters/combinedequipmentenergyitem.py (6 issues)

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