Code Duplication    Length = 1000-1002 lines in 2 locations

myems-api/excelexporters/combinedequipmentcost.py 1 location

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

myems-api/excelexporters/combinedequipmentcarbon.py 1 location

@@ 71-1070 (lines=1000) @@
68
    return base64_message
69
70
71
def generate_excel(report,
72
                   name,
73
                   base_period_start_datetime_local,
74
                   base_period_end_datetime_local,
75
                   reporting_start_datetime_local,
76
                   reporting_end_datetime_local,
77
                   period_type,
78
                   language):
79
    trans = get_translation(language)
80
    trans.install()
81
    _ = trans.gettext
82
83
    wb = Workbook()
84
    ws = wb.active
85
    ws.title = "CombinedEquipmentCarbon"
86
87
    # Row height
88
    ws.row_dimensions[1].height = 102
89
    for i in range(2, 2000 + 1):
90
        ws.row_dimensions[i].height = 42
91
92
    # Col width
93
    ws.column_dimensions['A'].width = 1.5
94
95
    ws.column_dimensions['B'].width = 25.0
96
97
    for i in range(ord('C'), ord('Z')):
98
        ws.column_dimensions[chr(i)].width = 15.0
99
100
    # Font
101
    name_font = Font(name='Arial', size=15, bold=True)
102
    title_font = Font(name='Arial', size=15, bold=True)
103
104
    table_fill = PatternFill(fill_type='solid', fgColor='90ee90')
105
    f_border = Border(left=Side(border_style='medium'),
106
                      right=Side(border_style='medium'),
107
                      bottom=Side(border_style='medium'),
108
                      top=Side(border_style='medium')
109
                      )
110
    b_border = Border(
111
        bottom=Side(border_style='medium'),
112
    )
113
114
    b_c_alignment = Alignment(vertical='bottom',
115
                              horizontal='center',
116
                              text_rotation=0,
117
                              wrap_text=True,
118
                              shrink_to_fit=False,
119
                              indent=0)
120
    c_c_alignment = Alignment(vertical='center',
121
                              horizontal='center',
122
                              text_rotation=0,
123
                              wrap_text=True,
124
                              shrink_to_fit=False,
125
                              indent=0)
126
    b_r_alignment = Alignment(vertical='bottom',
127
                              horizontal='right',
128
                              text_rotation=0,
129
                              wrap_text=True,
130
                              shrink_to_fit=False,
131
                              indent=0)
132
133
    # Img
134
    img = Image("excelexporters/myems.png")
135
    ws.add_image(img, 'A1')
136
137
    # Title=
138
    ws['B3'].alignment = b_r_alignment
139
    ws['B3'] = _('Name') + ':'
140
    ws['C3'].border = b_border
141
    ws['C3'].alignment = b_c_alignment
142
    ws['C3'] = name
143
144
    ws['D3'].alignment = b_r_alignment
145
    ws['D3'] = _('Period Type') + ':'
146
    ws['E3'].border = b_border
147
    ws['E3'].alignment = b_c_alignment
148
    ws['E3'] = period_type
149
150
    ws['B4'].alignment = b_r_alignment
151
    ws['B4'] = _('Reporting Start Datetime') + ':'
152
    ws['C4'].border = b_border
153
    ws['C4'].alignment = b_c_alignment
154
    ws['C4'] = reporting_start_datetime_local
155
156
    ws['D4'].alignment = b_r_alignment
157
    ws['D4'] = _('Reporting End Datetime') + ':'
158
    ws['E4'].border = b_border
159
    ws['E4'].alignment = b_c_alignment
160
    ws['E4'] = reporting_end_datetime_local
161
162
    is_base_period_timestamp_exists_flag = is_base_period_timestamp_exists(report['base_period'])
163
164
    if is_base_period_timestamp_exists_flag:
165
        ws['B5'].alignment = b_r_alignment
166
        ws['B5'] = _('Base Period Start Datetime') + ':'
167
        ws['C5'].border = b_border
168
        ws['C5'].alignment = b_c_alignment
169
        ws['C5'] = base_period_start_datetime_local
170
171
        ws['D5'].alignment = b_r_alignment
172
        ws['D5'] = _('Base Period End Datetime') + ':'
173
        ws['E5'].border = b_border
174
        ws['E5'].alignment = b_c_alignment
175
        ws['E5'] = base_period_end_datetime_local
176
177
    if "reporting_period" not in report.keys() or \
178
            "names" not in report['reporting_period'].keys() or \
179
            len(report['reporting_period']['names']) == 0:
180
        filename = str(uuid.uuid4()) + '.xlsx'
181
        wb.save(filename)
182
183
        return filename
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
        for i in range(7, 10 + 1):
191
            ws.row_dimensions[i].height = 0.1
192
    else:
193
        ws['B7'].font = title_font
194
        ws['B7'] = name + ' ' + _('Reporting Period Carbon Dioxide Emissions')
195
196
        category = reporting_period_data['names']
197
        ca_len = len(category)
198
199
        ws.row_dimensions[7].height = 60
200
        ws['B8'].fill = table_fill
201
        ws['B8'].border = f_border
202
203
        ws['B9'].font = title_font
204
        ws['B9'].alignment = c_c_alignment
205
        ws['B9'] = _('Carbon Dioxide Emissions')
206
        ws['B9'].border = f_border
207
208
        ws['B10'].font = title_font
209
        ws['B10'].alignment = c_c_alignment
210
        ws['B10'] = _('Increment Rate')
211
        ws['B10'].border = f_border
212
213
        col = 'B'
214
215
        for i in range(0, ca_len):
216
            col = chr(ord('C') + i)
217
            ws[col + '8'].fill = table_fill
218
            ws[col + '8'].font = name_font
219
            ws[col + '8'].alignment = c_c_alignment
220
            ws[col + '8'] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
221
            ws[col + '8'].border = f_border
222
223
            ws[col + '9'].font = name_font
224
            ws[col + '9'].alignment = c_c_alignment
225
            ws[col + '9'] = round2(reporting_period_data['subtotals'][i], 2)
226
            ws[col + '9'].border = f_border
227
228
            ws[col + '10'].font = name_font
229
            ws[col + '10'].alignment = c_c_alignment
230
            ws[col + '10'] = str(round2(reporting_period_data['increment_rates'][i] * 100, 2)) + "%" \
231
                if reporting_period_data['increment_rates'][i] is not None else "-"
232
            ws[col + '10'].border = f_border
233
234
        end_col = chr(ord(col) + 1)
235
        ws[end_col + '8'].fill = table_fill
236
        ws[end_col + '8'].font = name_font
237
        ws[end_col + '8'].alignment = c_c_alignment
238
        ws[end_col + '8'] = _("Total") + " (" + reporting_period_data['total_unit'] + ")"
239
        ws[end_col + '8'].border = f_border
240
241
        ws[end_col + '9'].font = name_font
242
        ws[end_col + '9'].alignment = c_c_alignment
243
        ws[end_col + '9'] = round2(reporting_period_data['total'], 2)
244
        ws[end_col + '9'].border = f_border
245
246
        ws[end_col + '10'].font = name_font
247
        ws[end_col + '10'].alignment = c_c_alignment
248
        ws[end_col + '10'] = str(round2(reporting_period_data['total_increment_rate'] * 100, 2)) + "%" \
249
            if reporting_period_data['total_increment_rate'] is not None else "-"
250
        ws[end_col + '10'].border = f_border
251
252
    if "toppeaks" not in reporting_period_data.keys() or \
253
            reporting_period_data['toppeaks'] is None or \
254
            len(reporting_period_data['toppeaks']) == 0:
255
        for i in range(12, 18 + 1):
256
            ws.row_dimensions[i].height = 0.1
257
    else:
258
        electricity_index = -1
259
        for i in range(len(reporting_period_data['energy_category_ids'])):
260
            if reporting_period_data['energy_category_ids'][i] == 1:
261
                electricity_index = i
262
                break
263
264
        ws['B12'].font = title_font
265
        ws['B12'] = name + _('Electricity Carbon Dioxide Emissions by Time-Of-Use')
266
267
        ws['B13'].fill = table_fill
268
        ws['B13'].font = name_font
269
        ws['B13'].alignment = c_c_alignment
270
        ws['B13'].border = f_border
271
272
        ws['C13'].fill = table_fill
273
        ws['C13'].font = name_font
274
        ws['C13'].alignment = c_c_alignment
275
        ws['C13'].border = f_border
276
        ws['C13'] = _('Electricity Carbon Dioxide Emissions by Time-Of-Use')
277
278
        ws['D13'].fill = table_fill
279
        ws['D13'].font = name_font
280
        ws['D13'].alignment = c_c_alignment
281
        ws['D13'].border = f_border
282
        ws['D13'] = _('Electricity Carbon Dioxide Emissions Proportion by Time-Of-Use')
283
284
        carbonsum = None
285
286
        if electricity_index >= 0:
287
            carbonsum = round(reporting_period_data['toppeaks'][electricity_index], 2) + \
288
                        round(reporting_period_data['onpeaks'][electricity_index], 2) + \
289
                        round(reporting_period_data['midpeaks'][electricity_index], 2) + \
290
                        round(reporting_period_data['offpeaks'][electricity_index], 2) + \
291
                        round(reporting_period_data['deeps'][electricity_index], 2)
292
293
        ws['B14'].font = title_font
294
        ws['B14'].alignment = c_c_alignment
295
        ws['B14'] = _('TopPeak')
296
        ws['B14'].border = f_border
297
298
        ws['C14'].font = title_font
299
        ws['C14'].alignment = c_c_alignment
300
        ws['C14'].border = f_border
301
        ws['C14'] = round2(reporting_period_data['toppeaks'][electricity_index], 2) if electricity_index >= 0 else "-"
302
303
        ws['D14'].font = title_font
304
        ws['D14'].alignment = c_c_alignment
305
        ws['D14'].border = f_border
306
        ws['D14'] = '{:.2%}'.format(round2(reporting_period_data['toppeaks'][electricity_index], 2) / carbonsum) \
307
            if carbonsum is not None and carbonsum != Decimal(0.0) else " "
308
309
        ws['B15'].font = title_font
310
        ws['B15'].alignment = c_c_alignment
311
        ws['B15'] = _('OnPeak')
312
        ws['B15'].border = f_border
313
314
        ws['C15'].font = title_font
315
        ws['C15'].alignment = c_c_alignment
316
        ws['C15'].border = f_border
317
        ws['C15'] = round2(reporting_period_data['onpeaks'][electricity_index], 2) if electricity_index >= 0 else "-"
318
319
        ws['D15'].font = title_font
320
        ws['D15'].alignment = c_c_alignment
321
        ws['D15'].border = f_border
322
        ws['D15'] = '{:.2%}'.format(round2(reporting_period_data['onpeaks'][electricity_index], 2) / carbonsum) \
323
            if carbonsum is not None and carbonsum != Decimal(0.0) else " "
324
325
        ws['B16'].font = title_font
326
        ws['B16'].alignment = c_c_alignment
327
        ws['B16'] = _('MidPeak')
328
        ws['B16'].border = f_border
329
330
        ws['C16'].font = title_font
331
        ws['C16'].alignment = c_c_alignment
332
        ws['C16'].border = f_border
333
        ws['C16'] = round2(reporting_period_data['midpeaks'][electricity_index], 2) if electricity_index >= 0 else "-"
334
335
        ws['D16'].font = title_font
336
        ws['D16'].alignment = c_c_alignment
337
        ws['D16'].border = f_border
338
        ws['D16'] = '{:.2%}'.format(round2(reporting_period_data['midpeaks'][electricity_index], 2) / carbonsum) \
339
            if carbonsum is not None and carbonsum != Decimal(0.0) else " "
340
341
        ws['B17'].font = title_font
342
        ws['B17'].alignment = c_c_alignment
343
        ws['B17'] = _('OffPeak')
344
        ws['B17'].border = f_border
345
346
        ws['C17'].font = title_font
347
        ws['C17'].alignment = c_c_alignment
348
        ws['C17'].border = f_border
349
        ws['C17'] = round2(reporting_period_data['offpeaks'][electricity_index], 2) if electricity_index >= 0 else "-"
350
351
        ws['D17'].font = title_font
352
        ws['D17'].alignment = c_c_alignment
353
        ws['D17'].border = f_border
354
        ws['D17'] = '{:.2%}'.format(round2(reporting_period_data['offpeaks'][electricity_index], 2) / carbonsum) \
355
            if carbonsum is not None and carbonsum != Decimal(0.0) else " "
356
357
        pie = PieChart()
358
        pie.title = name + _('Electricity Carbon Dioxide Emissions by Time-Of-Use')
359
        labels = Reference(ws, min_col=2, min_row=14, max_row=17)
360
        pie_data = Reference(ws, min_col=3, min_row=13, max_row=17)
361
        pie.add_data(pie_data, titles_from_data=True)
362
        pie.set_categories(labels)
363
        pie.height = 6.6
364
        pie.width = 9
365
        s1 = pie.series[0]
366
        s1.dLbls = DataLabelList()
367
        s1.dLbls.showCatName = False
368
        s1.dLbls.showVal = False
369
        s1.dLbls.showPercent = True
370
        ws.add_chart(pie, "E13")
371
372
    ################################################
373
374
    current_row_number = 19
375
    if "subtotals" not in reporting_period_data.keys() or \
376
            reporting_period_data['subtotals'] is None or \
377
            len(reporting_period_data['subtotals']) == 0:
378
        for i in range(21, 29 + 1):
379
            current_row_number = 30
380
            ws.row_dimensions[i].height = 0.1
381
    else:
382
        ws['B' + str(current_row_number)].font = title_font
383
        ws['B' + str(current_row_number)] = name + ' ' + _('Carbon Dioxide Emissions Proportion')
384
385
        current_row_number += 1
386
387
        table_start_row_number = current_row_number
388
389
        ws['B' + str(current_row_number)].fill = table_fill
390
        ws['B' + str(current_row_number)].font = name_font
391
        ws['B' + str(current_row_number)].alignment = c_c_alignment
392
        ws['B' + str(current_row_number)].border = f_border
393
394
        ws['C' + str(current_row_number)].fill = table_fill
395
        ws['C' + str(current_row_number)].font = name_font
396
        ws['C' + str(current_row_number)].alignment = c_c_alignment
397
        ws['C' + str(current_row_number)].border = f_border
398
        ws['C' + str(current_row_number)] = _('Carbon Dioxide Emissions')
399
400
        ws['D' + str(current_row_number)].fill = table_fill
401
        ws['D' + str(current_row_number)].font = name_font
402
        ws['D' + str(current_row_number)].alignment = c_c_alignment
403
        ws['D' + str(current_row_number)].border = f_border
404
        ws['D' + str(current_row_number)] = _('Carbon Dioxide Emissions Proportion')
405
406
        current_row_number += 1
407
408
        ca_len = len(reporting_period_data['names'])
409
        carbonsum = Decimal(0.0)
410
        for i in range(0, ca_len):
411
            carbonsum = round(reporting_period_data['subtotals'][i], 2) + carbonsum
412
        for i in range(0, ca_len):
413
            ws['B' + str(current_row_number)].font = title_font
414
            ws['B' + str(current_row_number)].alignment = c_c_alignment
415
            ws['B' + str(current_row_number)] = reporting_period_data['names'][i]
416
            ws['B' + str(current_row_number)].border = f_border
417
418
            ws['C' + str(current_row_number)].font = title_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)] = round2(reporting_period_data['subtotals'][i], 2)
422
423
            ws['D' + str(current_row_number)].font = title_font
424
            ws['D' + str(current_row_number)].alignment = c_c_alignment
425
            ws['D' + str(current_row_number)].border = f_border
426
            ws['D' + str(current_row_number)] = '{:.2%}'.format(round2(
427
                reporting_period_data['subtotals'][i], 2) / carbonsum) if \
428
                carbonsum is not None and carbonsum != Decimal(0.0) else " "
429
            current_row_number += 1
430
431
        table_end_row_number = current_row_number - 1
432
433
        pie = PieChart()
434
        pie.title = name + ' ' + _('Carbon Dioxide Emissions Proportion')
435
        labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
436
        pie_data = Reference(ws, min_col=3, min_row=table_start_row_number, max_row=table_end_row_number)
437
        pie.add_data(pie_data, titles_from_data=True)
438
        pie.set_categories(labels)
439
        pie.height = 6.6
440
        pie.width = 9
441
        s1 = pie.series[0]
442
        s1.dLbls = DataLabelList()
443
        s1.dLbls.showCatName = False
444
        s1.dLbls.showVal = False
445
        s1.dLbls.showPercent = True
446
        table_cell = 'E' + str(table_start_row_number)
447
        ws.add_chart(pie, table_cell)
448
449
        if ca_len < 4:
450
            current_row_number = current_row_number - ca_len + 4
451
452
        current_row_number += 1
453
454
    ####################################################################################################################
455
    table_start_draw_flag = current_row_number + 1
456
457
    if "timestamps" not in reporting_period_data.keys() or \
458
            reporting_period_data['timestamps'] is None or \
459
            len(reporting_period_data['timestamps']) == 0:
460
        pass
461
    else:
462
        if not is_base_period_timestamp_exists_flag:
463
            reporting_period_data = report['reporting_period']
464
            times = reporting_period_data['timestamps']
465
            ca_len = len(report['reporting_period']['names'])
466
            real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
467
            ws['B' + str(current_row_number)].font = title_font
468
            ws['B' + str(current_row_number)] = name + ' ' + _('Detailed Data')
469
470
            current_row_number += 1
471
            # 1: Stand for blank line  2: Stand for title
472
            current_row_number += ca_len * 6 + real_timestamps_len * 6 + 1 + 2
473
            table_start_row_number = current_row_number
474
475
            time = times[0]
476
            has_data = False
477
478
            if len(time) > 0:
479
                has_data = True
480
481
            if has_data:
482
483
                ws.row_dimensions[current_row_number].height = 60
484
                current_col_number = 2
485
                col = format_cell.get_column_letter(current_col_number)
486
                ws[col + str(current_row_number)].fill = table_fill
487
                ws[col + str(current_row_number)].font = title_font
488
                ws[col + str(current_row_number)].border = f_border
489
                ws[col + str(current_row_number)].alignment = c_c_alignment
490
                ws[col + str(current_row_number)] = _('Datetime')
491
492
                for i in range(0, ca_len):
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)].alignment = c_c_alignment
499
                    ws[col + str(current_row_number)] = reporting_period_data['names'][i] + \
500
                        " (" + reporting_period_data['units'][i] + ")"
501
                    ws[col + str(current_row_number)].border = f_border
502
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)] = _('Total') + '(' + report['reporting_period']['total_unit'] + ')'
509
                ws[col + str(current_row_number)].border = f_border
510
511
                current_row_number += 1
512
513
                for i in range(0, len(time)):
514
                    current_col_number = 2
515
                    col = format_cell.get_column_letter(current_col_number)
516
517
                    ws[col + str(current_row_number)].font = title_font
518
                    ws[col + str(current_row_number)].alignment = c_c_alignment
519
                    ws[col + str(current_row_number)] = time[i]
520
                    ws[col + str(current_row_number)].border = f_border
521
522
                    total = Decimal(0.0)
523
524
                    for j in range(0, ca_len):
525
                        current_col_number += 1
526
                        col = format_cell.get_column_letter(current_col_number)
527
528
                        ws[col + str(current_row_number)].font = title_font
529
                        ws[col + str(current_row_number)].alignment = c_c_alignment
530
                        ws[col + str(current_row_number)] = round2(reporting_period_data['values'][j][i], 2)
531
                        total += reporting_period_data['values'][j][i]
532
                        ws[col + str(current_row_number)].border = f_border
533
534
                    current_col_number += 1
535
                    col = format_cell.get_column_letter(current_col_number)
536
                    ws[col + str(current_row_number)].font = title_font
537
                    ws[col + str(current_row_number)].alignment = c_c_alignment
538
                    ws[col + str(current_row_number)] = round2(total, 2)
539
                    ws[col + str(current_row_number)].border = f_border
540
541
                    current_row_number += 1
542
543
                table_end_row_number = current_row_number - 1
544
545
                current_col_number = 2
546
                col = format_cell.get_column_letter(current_col_number)
547
548
                ws[col + str(current_row_number)].font = title_font
549
                ws[col + str(current_row_number)].alignment = c_c_alignment
550
                ws[col + str(current_row_number)] = _('Subtotal')
551
                ws[col + str(current_row_number)].border = f_border
552
553
                subtotals = Decimal(0.0)
554
555
                for i in range(0, ca_len):
556
                    current_col_number += 1
557
                    col = format_cell.get_column_letter(current_col_number)
558
                    ws[col + str(current_row_number)].font = title_font
559
                    ws[col + str(current_row_number)].alignment = c_c_alignment
560
                    ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2)
561
                    subtotals += reporting_period_data['subtotals'][i]
562
                    ws[col + str(current_row_number)].border = f_border
563
564
                    # line
565
                    line = LineChart()
566
                    line.title = _('Reporting Period Carbon Dioxide Emissions') + ' - ' \
567
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
568
                    labels = Reference(ws, min_col=2, min_row=table_start_row_number + 1, max_row=table_end_row_number)
569
                    line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
570
                                          max_row=table_end_row_number)
571
                    line.add_data(line_data, titles_from_data=True)
572
                    line.set_categories(labels)
573
                    line_data = line.series[0]
574
                    line_data.marker.symbol = "auto"
575
                    line_data.smooth = True
576
                    line.x_axis.crosses = 'min'
577
                    line.height = 8.25
578
                    line.width = 24
579
                    chart_col = 'B'
580
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
581
                    ws.add_chart(line, chart_cell)
582
583
                current_col_number += 1
584
                col = format_cell.get_column_letter(current_col_number)
585
                ws[col + str(current_row_number)].font = title_font
586
                ws[col + str(current_row_number)].alignment = c_c_alignment
587
                ws[col + str(current_row_number)] = round2(subtotals, 2)
588
                ws[col + str(current_row_number)].border = f_border
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
636
                current_col_number += 1
637
                col = format_cell.get_column_letter(current_col_number)
638
                ws[col + str(current_row_number)].fill = table_fill
639
                ws[col + str(current_row_number)].font = title_font
640
                ws[col + str(current_row_number)].alignment = c_c_alignment
641
                ws[col + str(current_row_number)] = _('Base Period') + " - " \
642
                    + _('Total') + '(' + report['reporting_period']['total_unit'] + ')'
643
                ws[col + str(current_row_number)].border = f_border
644
645
                current_col_number += 1
646
                col = format_cell.get_column_letter(current_col_number)
647
648
                ws[col + str(current_row_number)].fill = table_fill
649
                ws[col + str(current_row_number)].font = title_font
650
                ws[col + str(current_row_number)].border = f_border
651
                ws[col + str(current_row_number)].alignment = c_c_alignment
652
                ws[col + str(current_row_number)] = _('Reporting Period') + " - " + _('Datetime')
653
654
                for i in range(0, reporting_period_data_ca_len):
655
                    current_col_number += 1
656
                    col = format_cell.get_column_letter(current_col_number)
657
                    ws[col + str(current_row_number)].fill = table_fill
658
                    ws[col + str(current_row_number)].font = title_font
659
                    ws[col + str(current_row_number)].alignment = c_c_alignment
660
                    ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
661
                        + reporting_period_data['names'][i] + " (" + \
662
                        reporting_period_data['units'][i] + ")"
663
                    ws[col + str(current_row_number)].border = f_border
664
665
                current_col_number += 1
666
                col = format_cell.get_column_letter(current_col_number)
667
                ws[col + str(current_row_number)].fill = table_fill
668
                ws[col + str(current_row_number)].font = title_font
669
                ws[col + str(current_row_number)].alignment = c_c_alignment
670
                ws[col + str(current_row_number)] = _('Reporting Period') + " - " \
671
                    + _('Total') + '(' + report['reporting_period']['total_unit'] + ')'
672
                ws[col + str(current_row_number)].border = f_border
673
674
                current_row_number += 1
675
676
                max_timestamps_len = len(base_period_timestamps[0]) \
677
                    if len(base_period_timestamps[0]) >= len(reporting_period_timestamps[0]) \
678
                    else len(reporting_period_timestamps[0])
679
680
                for i in range(0, max_timestamps_len):
681
                    current_col_number = 2
682
                    col = format_cell.get_column_letter(current_col_number)
683
                    ws[col + str(current_row_number)].font = title_font
684
                    ws[col + str(current_row_number)].alignment = c_c_alignment
685
                    ws[col + str(current_row_number)] = base_period_timestamps[0][i] \
686
                        if i < len(base_period_timestamps[0]) else None
687
                    ws[col + str(current_row_number)].border = f_border
688
689
                    base_period_total = Decimal(0.0)
690
691
                    for j in range(0, base_period_data_ca_len):
692
                        current_col_number += 1
693
                        col = format_cell.get_column_letter(current_col_number)
694
695
                        ws[col + str(current_row_number)].font = title_font
696
                        ws[col + str(current_row_number)].alignment = c_c_alignment
697
                        ws[col + str(current_row_number)] = round2(base_period_data['values'][j][i], 2) \
698
                            if i < len(base_period_data['values'][j]) else None
699
                        if i < len(base_period_timestamps[0]):
700
                            base_period_total += base_period_data['values'][j][i]
701
                        ws[col + str(current_row_number)].border = f_border
702
703
                    current_col_number += 1
704
                    col = format_cell.get_column_letter(current_col_number)
705
                    ws[col + str(current_row_number)].font = title_font
706
                    ws[col + str(current_row_number)].alignment = c_c_alignment
707
                    ws[col + str(current_row_number)] = round2(base_period_total, 2) \
708
                        if i < len(base_period_timestamps[0]) else None
709
                    ws[col + str(current_row_number)].border = f_border
710
711
                    current_col_number += 1
712
                    col = format_cell.get_column_letter(current_col_number)
713
714
                    ws[col + str(current_row_number)].font = title_font
715
                    ws[col + str(current_row_number)].alignment = c_c_alignment
716
                    ws[col + str(current_row_number)] = reporting_period_timestamps[0][i] \
717
                        if i < len(reporting_period_timestamps[0]) else None
718
                    ws[col + str(current_row_number)].border = f_border
719
720
                    reporting_period_total = Decimal(0.0)
721
722
                    for j in range(0, reporting_period_data_ca_len):
723
                        current_col_number += 1
724
                        col = format_cell.get_column_letter(current_col_number)
725
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)] = round2(reporting_period_data['values'][j][i], 2) \
729
                            if i < len(reporting_period_data['values'][j]) else None
730
                        if i < len(reporting_period_timestamps[0]):
731
                            reporting_period_total += reporting_period_data['values'][j][i]
732
                        ws[col + str(current_row_number)].border = f_border
733
734
                    current_col_number += 1
735
                    col = format_cell.get_column_letter(current_col_number)
736
                    ws[col + str(current_row_number)].font = title_font
737
                    ws[col + str(current_row_number)].alignment = c_c_alignment
738
                    ws[col + str(current_row_number)] = round2(reporting_period_total, 2) \
739
                        if i < len(reporting_period_timestamps[0]) else None
740
                    ws[col + str(current_row_number)].border = f_border
741
742
                    current_row_number += 1
743
744
                current_col_number = 2
745
                col = format_cell.get_column_letter(current_col_number)
746
                ws[col + str(current_row_number)].font = title_font
747
                ws[col + str(current_row_number)].alignment = c_c_alignment
748
                ws[col + str(current_row_number)] = _('Subtotal')
749
                ws[col + str(current_row_number)].border = f_border
750
751
                base_period_subtotals = Decimal(0.0)
752
753
                for i in range(0, base_period_data_ca_len):
754
                    current_col_number += 1
755
                    col = format_cell.get_column_letter(current_col_number)
756
                    ws[col + str(current_row_number)].font = title_font
757
                    ws[col + str(current_row_number)].alignment = c_c_alignment
758
                    ws[col + str(current_row_number)] = round2(base_period_data['subtotals'][i], 2)
759
                    base_period_subtotals += base_period_data['subtotals'][i]
760
                    ws[col + str(current_row_number)].border = f_border
761
762
                current_col_number += 1
763
                col = format_cell.get_column_letter(current_col_number)
764
                ws[col + str(current_row_number)].font = title_font
765
                ws[col + str(current_row_number)].alignment = c_c_alignment
766
                ws[col + str(current_row_number)] = round2(base_period_subtotals, 2)
767
                ws[col + str(current_row_number)].border = f_border
768
769
                current_col_number += 1
770
                col = format_cell.get_column_letter(current_col_number)
771
772
                ws[col + str(current_row_number)].font = title_font
773
                ws[col + str(current_row_number)].alignment = c_c_alignment
774
                ws[col + str(current_row_number)] = _('Subtotal')
775
                ws[col + str(current_row_number)].border = f_border
776
777
                reporting_period_subtotals = Decimal(0.0)
778
779
                for i in range(0, reporting_period_data_ca_len):
780
                    current_col_number += 1
781
                    col = format_cell.get_column_letter(current_col_number)
782
                    ws[col + str(current_row_number)].font = title_font
783
                    ws[col + str(current_row_number)].alignment = c_c_alignment
784
                    ws[col + str(current_row_number)] = round2(reporting_period_data['subtotals'][i], 2)
785
                    reporting_period_subtotals += reporting_period_data['subtotals'][i]
786
                    ws[col + str(current_row_number)].border = f_border
787
788
                current_col_number += 1
789
                col = format_cell.get_column_letter(current_col_number)
790
                ws[col + str(current_row_number)].font = title_font
791
                ws[col + str(current_row_number)].alignment = c_c_alignment
792
                ws[col + str(current_row_number)] = round2(reporting_period_subtotals, 2)
793
                ws[col + str(current_row_number)].border = f_border
794
795
                for i in range(0, reporting_period_data_ca_len):
796
                    # line
797
                    line = LineChart()
798
                    line.title = _('Base Period Carbon Dioxide Emissions') + " / " \
799
                        + _('Reporting Period Carbon Dioxide Emissions') + ' - ' \
800
                        + reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + ")"
801
                    labels = Reference(ws, min_col=2 + base_period_data_ca_len + 1 + 1,
802
                                       min_row=table_start_row_number + 1,
803
                                       max_row=table_start_row_number + len(reporting_period_timestamps[0]))
804
                    base_line_data = Reference(ws, min_col=3 + i, min_row=table_start_row_number,
805
                                               max_row=table_start_row_number + len(reporting_period_timestamps[0]))
806
                    reporting_line_data = Reference(ws, min_col=3 + base_period_data_ca_len + 1 + 1 + i,
807
                                                    min_row=table_start_row_number,
808
                                                    max_row=table_start_row_number
809
                                                    + len(reporting_period_timestamps[0]))
810
                    line.add_data(base_line_data, titles_from_data=True)
811
                    line.add_data(reporting_line_data, titles_from_data=True)
812
                    line.set_categories(labels)
813
                    for j in range(len(line.series)):
814
                        line.series[j].marker.symbol = "auto"
815
                        line.series[j].smooth = True
816
                    line.x_axis.crosses = 'min'
817
                    line.height = 8.25
818
                    line.width = 24
819
                    chart_col = 'B'
820
                    chart_cell = chart_col + str(table_start_draw_flag + 6 * i)
821
                    ws.add_chart(line, chart_cell)
822
823
                current_row_number += 2
824
825
    ####################################################################################################################
826
827
    if "associated_equipment" not in report.keys() or \
828
            "energy_category_names" not in report['associated_equipment'].keys() or \
829
            len(report['associated_equipment']["energy_category_names"]) == 0 \
830
            or 'associated_equipment_names_array' not in report['associated_equipment'].keys() \
831
            or report['associated_equipment']['associated_equipment_names_array'] is None \
832
            or len(report['associated_equipment']['associated_equipment_names_array']) == 0 \
833
            or len(report['associated_equipment']['associated_equipment_names_array'][0]) == 0:
834
        pass
835
    else:
836
        associated_equipment = report['associated_equipment']
837
        current_row_number += 1
838
839
        ws['B' + str(current_row_number)].font = title_font
840
        ws['B' + str(current_row_number)] = name + ' ' + _('Associated Equipment Data')
841
842
        current_row_number += 1
843
844
        ws.row_dimensions[current_row_number].height = 60
845
        ws['B' + str(current_row_number)].fill = table_fill
846
        ws['B' + str(current_row_number)].font = name_font
847
        ws['B' + str(current_row_number)].alignment = c_c_alignment
848
        ws['B' + str(current_row_number)].border = f_border
849
        ws['B' + str(current_row_number)] = _('Associated Equipment')
850
        ca_len = len(associated_equipment['energy_category_names'])
851
852
        for i in range(0, ca_len):
853
            col = chr(ord('C') + i)
854
            ws[col + str(current_row_number)].fill = table_fill
855
            ws[col + str(current_row_number)].font = name_font
856
            ws[col + str(current_row_number)].alignment = c_c_alignment
857
            ws[col + str(current_row_number)].border = f_border
858
            ws[col + str(current_row_number)] = \
859
                associated_equipment['energy_category_names'][i] + " (" + associated_equipment['units'][i] + ")"
860
861
        end_col = chr(ord('B') + ca_len + 1)
862
        ws[end_col + str(current_row_number)].fill = table_fill
863
        ws[end_col + str(current_row_number)].font = name_font
864
        ws[end_col + str(current_row_number)].alignment = c_c_alignment
865
        ws[end_col + str(current_row_number)].border = f_border
866
        ws[end_col + str(current_row_number)] = _("Total") + " (" + reporting_period_data['units'][i] + ")"
867
868
        associated_equipment_len = len(associated_equipment['associated_equipment_names_array'][0])
869
870
        for i in range(0, associated_equipment_len):
871
            current_row_number += 1
872
            row = str(current_row_number)
873
            value = Decimal(0.0)
874
875
            ws['B' + row].font = title_font
876
            ws['B' + row].alignment = c_c_alignment
877
            ws['B' + row] = associated_equipment['associated_equipment_names_array'][0][i]
878
            ws['B' + row].border = f_border
879
880
            for j in range(0, ca_len):
881
                col = chr(ord('C') + j)
882
                ws[col + row].font = title_font
883
                ws[col + row].alignment = c_c_alignment
884
                ws[col + row] = round2(associated_equipment['subtotals_array'][j][i], 2)
885
                value += round(associated_equipment['subtotals_array'][j][i], 2)
886
                ws[col + row].border = f_border
887
888
            end_col = chr(ord(col) + 1)
889
            ws[end_col + row].font = title_font
890
            ws[end_col + row].alignment = c_c_alignment
891
            ws[end_col + row] = round2(value, 2)
892
            ws[end_col + row].border = f_border
893
894
    ####################################################################################################################
895
    current_sheet_parameters_row_number = table_start_draw_flag + len(reporting_period_data['names']) * 6 + 1
896
    if 'parameters' not in report.keys() or \
897
            report['parameters'] is None or \
898
            'names' not in report['parameters'].keys() or \
899
            report['parameters']['names'] is None or \
900
            len(report['parameters']['names']) == 0 or \
901
            'timestamps' not in report['parameters'].keys() or \
902
            report['parameters']['timestamps'] is None or \
903
            len(report['parameters']['timestamps']) == 0 or \
904
            'values' not in report['parameters'].keys() or \
905
            report['parameters']['values'] is None or \
906
            len(report['parameters']['values']) == 0 or \
907
            timestamps_data_all_equal_0(report['parameters']['timestamps']):
908
        pass
909
    else:
910
        ################################################################################################################
911
        # new worksheet
912
        ################################################################################################################
913
914
        parameters_data = report['parameters']
915
        parameters_names_len = len(parameters_data['names'])
916
917
        file_name = (re.sub(r'[^A-Z]', '', ws.title)) + '_'
918
        parameters_ws = wb.create_sheet(file_name + _('Parameters'))
919
920
        parameters_timestamps_data_max_len = \
921
            get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
922
923
        # Row height
924
        parameters_ws.row_dimensions[1].height = 102
925
        for i in range(2, 7 + 1):
926
            parameters_ws.row_dimensions[i].height = 42
927
928
        for i in range(8, parameters_timestamps_data_max_len + 10):
929
            parameters_ws.row_dimensions[i].height = 60
930
931
        # Col width
932
        parameters_ws.column_dimensions['A'].width = 1.5
933
934
        parameters_ws.column_dimensions['B'].width = 25.0
935
936
        for i in range(3, 12 + parameters_names_len * 3):
937
            parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
938
939
        # Img
940
        img = Image("excelexporters/myems.png")
941
        parameters_ws.add_image(img, 'A1')
942
943
        # Title
944
        parameters_ws['B3'].alignment = b_r_alignment
945
        parameters_ws['B3'] = _('Name') + ':'
946
        parameters_ws['C3'].border = b_border
947
        parameters_ws['C3'].alignment = b_c_alignment
948
        parameters_ws['C3'] = name
949
950
        parameters_ws['D3'].alignment = b_r_alignment
951
        parameters_ws['D3'] = _('Period Type') + ':'
952
        parameters_ws['E3'].border = b_border
953
        parameters_ws['E3'].alignment = b_c_alignment
954
        parameters_ws['E3'] = period_type
955
956
        parameters_ws['B4'].alignment = b_r_alignment
957
        parameters_ws['B4'] = _('Reporting Start Datetime') + ':'
958
        parameters_ws['C4'].border = b_border
959
        parameters_ws['C4'].alignment = b_c_alignment
960
        parameters_ws['C4'] = reporting_start_datetime_local
961
962
        parameters_ws['D4'].alignment = b_r_alignment
963
        parameters_ws['D4'] = _('Reporting End Datetime') + ':'
964
        parameters_ws['E4'].border = b_border
965
        parameters_ws['E4'].alignment = b_c_alignment
966
        parameters_ws['E4'] = reporting_end_datetime_local
967
968
        parameters_ws_current_row_number = 6
969
970
        parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
971
        parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' ' + _('Parameters')
972
973
        parameters_ws_current_row_number += 1
974
975
        parameters_table_start_row_number = parameters_ws_current_row_number
976
977
        parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
978
979
        parameters_ws_current_row_number += 1
980
981
        table_current_col_number = 2
982
983
        for i in range(0, parameters_names_len):
984
985
            if len(parameters_data['timestamps'][i]) == 0:
986
                continue
987
988
            col = format_cell.get_column_letter(table_current_col_number)
989
990
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
991
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
992
993
            col = format_cell.get_column_letter(table_current_col_number + 1)
994
995
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
996
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
997
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
998
            parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
999
            parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
1000
1001
            table_current_row_number = parameters_ws_current_row_number
1002
1003
            for j, value in enumerate(list(parameters_data['timestamps'][i])):
1004
                col = format_cell.get_column_letter(table_current_col_number)
1005
1006
                parameters_ws[col + str(table_current_row_number)].border = f_border
1007
                parameters_ws[col + str(table_current_row_number)].font = title_font
1008
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
1009
                parameters_ws[col + str(table_current_row_number)] = value
1010
1011
                col = format_cell.get_column_letter(table_current_col_number + 1)
1012
1013
                parameters_ws[col + str(table_current_row_number)].border = f_border
1014
                parameters_ws[col + str(table_current_row_number)].font = title_font
1015
                parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
1016
                parameters_ws[col + str(table_current_row_number)] = round2(parameters_data['values'][i][j], 2)
1017
1018
                table_current_row_number += 1
1019
1020
            table_current_col_number = table_current_col_number + 3
1021
1022
        ################################################################################################################
1023
        # parameters chart and parameters table
1024
        ################################################################################################################
1025
1026
        ws['B' + str(current_sheet_parameters_row_number)].font = title_font
1027
        ws['B' + str(current_sheet_parameters_row_number)] = name + ' ' + _('Parameters')
1028
1029
        current_sheet_parameters_row_number += 1
1030
1031
        chart_start_row_number = current_sheet_parameters_row_number
1032
1033
        col_index = 0
1034
1035
        for i in range(0, parameters_names_len):
1036
1037
            if len(parameters_data['timestamps'][i]) == 0:
1038
                continue
1039
1040
            line = LineChart()
1041
            data_col = 3 + col_index * 3
1042
            labels_col = 2 + col_index * 3
1043
            col_index += 1
1044
            line.title = _('Parameters') + ' - ' + \
1045
                parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
1046
            labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
1047
                               max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
1048
            line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
1049
                                  max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
1050
            line.add_data(line_data, titles_from_data=True)
1051
            line.set_categories(labels)
1052
            line_data = line.series[0]
1053
            line_data.marker.symbol = "auto"
1054
            line_data.smooth = True
1055
            line.x_axis.crosses = 'min'
1056
            line.height = 8.25
1057
            line.width = 24
1058
            chart_col = 'B'
1059
            chart_cell = chart_col + str(chart_start_row_number)
1060
            chart_start_row_number += 6
1061
            ws.add_chart(line, chart_cell)
1062
1063
        current_sheet_parameters_row_number = chart_start_row_number
1064
1065
        current_sheet_parameters_row_number += 1
1066
    ####################################################################################################################
1067
    filename = str(uuid.uuid4()) + '.xlsx'
1068
    wb.save(filename)
1069
1070
    return filename
1071
1072
1073
def timestamps_data_all_equal_0(lists):