Code Duplication    Length = 995-998 lines in 2 locations

myems-api/excelexporters/spacecarbon.py 1 location

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

myems-api/excelexporters/spacecost.py 1 location

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