excelexporters.equipmentstatistics.export()   B
last analyzed

Complexity

Conditions 5

Size

Total Lines 45
Code Lines 31

Duplication

Lines 45
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 31
dl 45
loc 45
rs 8.6693
c 0
b 0
f 0
cc 5
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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