Passed
Push — master ( 107ae9...7e7300 )
by Guangyu
12:14 queued 12s
created

excelexporters.storesaving.export()   B

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