Passed
Push — master ( 7266b4...2706fb )
by Guangyu
09:48 queued 13s
created

excelexporters.tenantbatch.generate_excel()   D

Complexity

Conditions 10

Size

Total Lines 155
Code Lines 120

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 120
dl 0
loc 155
rs 4.1999
c 0
b 0
f 0
cc 10
nop 5

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like excelexporters.tenantbatch.generate_excel() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import base64
2
import uuid
3
import os
4
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
5
from openpyxl.drawing.image import Image
6
from openpyxl.utils import column_index_from_string, get_column_letter
7
from openpyxl import Workbook
8
import gettext
9
10
11
########################################################################################################################
12
# PROCEDURES
13
# Step 1: Validate the report data
14
# Step 2: Generate excel file from the report data
15
# Step 3: Encode the excel file to Base64
16
########################################################################################################################
17
18 View Code Duplication
def export(result, space_name, reporting_start_datetime_local, reporting_end_datetime_local, language):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
19
    ####################################################################################################################
20
    # Step 1: Validate the report data
21
    ####################################################################################################################
22
    if result is None:
23
        return None
24
25
    ####################################################################################################################
26
    # Step 2: Generate excel file from the report data
27
    ####################################################################################################################
28
    filename = generate_excel(result,
29
                              space_name,
30
                              reporting_start_datetime_local,
31
                              reporting_end_datetime_local,
32
                              language)
33
    ####################################################################################################################
34
    # Step 3: Encode the excel file to Base64
35
    ####################################################################################################################
36
    binary_file_data = b''
37
    try:
38
        with open(filename, 'rb') as binary_file:
39
            binary_file_data = binary_file.read()
40
    except IOError as ex:
41
        pass
42
43
    # Base64 encode the bytes
44
    base64_encoded_data = base64.b64encode(binary_file_data)
45
    # get the Base64 encoded data using human-readable characters.
46
    base64_message = base64_encoded_data.decode('utf-8')
47
    # delete the file from server
48
    try:
49
        os.remove(filename)
50
    except NotImplementedError as ex:
51
        pass
52
    return base64_message
53
54
55
def generate_excel(report, space_name, reporting_start_datetime_local, reporting_end_datetime_local, language):
56
57
    locale_path = './i18n/'
58
    if language == 'zh_CN':
59
        trans = gettext.translation('myems', locale_path, languages=['zh_CN'])
60
    elif language == 'de':
61
        trans = gettext.translation('myems', locale_path, languages=['de'])
62
    elif language == 'en':
63
        trans = gettext.translation('myems', locale_path, languages=['en'])
64
    else:
65
        trans = gettext.translation('myems', locale_path, languages=['en'])
66
    trans.install()
67
    _ = trans.gettext
68
69
    wb = Workbook()
70
    ws = wb.active
71
    ws.title = "TenantBatch"
72
73
    # Row height
74
    ws.row_dimensions[1].height = 102
75
    for i in range(2, 5 + 1):
76
        ws.row_dimensions[i].height = 42
77
78
    for i in range(6, len(report['tenants']) + 15):
79
        ws.row_dimensions[i].height = 60
80
81
    # Col width
82
    ws.column_dimensions['A'].width = 1.5
83
84
    ws.column_dimensions['B'].width = 25.0
85
86
    for i in range(ord('C'), ord('L')):
87
        ws.column_dimensions[chr(i)].width = 15.0
88
89
    # Font
90
    name_font = Font(name='Arial', size=15, bold=True)
91
    title_font = Font(name='Arial', size=15, bold=True)
92
    data_font = Font(name='Franklin Gothic Book', size=11)
93
94
    table_fill = PatternFill(fill_type='solid', fgColor='1F497D')
95
    f_border = Border(left=Side(border_style='medium', color='00000000'),
96
                      right=Side(border_style='medium', color='00000000'),
97
                      bottom=Side(border_style='medium', color='00000000'),
98
                      top=Side(border_style='medium', color='00000000')
99
                      )
100
    b_border = Border(
101
        bottom=Side(border_style='medium', color='00000000'),
102
    )
103
104
    b_c_alignment = Alignment(vertical='bottom',
105
                              horizontal='center',
106
                              text_rotation=0,
107
                              wrap_text=True,
108
                              shrink_to_fit=False,
109
                              indent=0)
110
    c_c_alignment = Alignment(vertical='center',
111
                              horizontal='center',
112
                              text_rotation=0,
113
                              wrap_text=True,
114
                              shrink_to_fit=False,
115
                              indent=0)
116
    b_r_alignment = Alignment(vertical='bottom',
117
                              horizontal='right',
118
                              text_rotation=0,
119
                              wrap_text=True,
120
                              shrink_to_fit=False,
121
                              indent=0)
122
123
    # Img
124
    img = Image("excelexporters/myems.png")
125
    ws.add_image(img, 'A1')
126
127
    # Title
128
    ws['B3'].alignment = b_r_alignment
129
    ws['B3'] = _('Space') + ':'
130
    ws['C3'].border = b_border
131
    ws['C3'].alignment = b_c_alignment
132
    ws['C3'] = space_name
133
134
    ws['B4'].alignment = b_r_alignment
135
    ws['B4'] = _('Reporting Start Datetime') + ':'
136
    ws['C4'].border = b_border
137
    ws['C4'].alignment = b_c_alignment
138
    ws['C4'] = reporting_start_datetime_local
139
140
    ws['B5'].alignment = b_r_alignment
141
    ws['B5'] = _('Reporting End Datetime') + ':'
142
    ws['C5'].border = b_border
143
    ws['C5'].alignment = b_c_alignment
144
    ws['C5'] = reporting_end_datetime_local
145
146
    # Title
147
    ws['B7'].border = f_border
148
    ws['B7'].font = name_font
149
    ws['B7'].alignment = c_c_alignment
150
    ws['B7'].fill = table_fill
151
    ws['B7'] = _('Name') + ':'
152
153
    ws['C7'].border = f_border
154
    ws['C7'].alignment = c_c_alignment
155
    ws['C7'].font = name_font
156
    ws['C7'].fill = table_fill
157
    ws['C7'] = _('Space') + ':'
158
159
    ca_len = len(report['energycategories'])
160
161
    for i in range(0, ca_len):
162
        col = get_column_letter(column_index_from_string('D') + i * 2)
163
        ws[col + '7'].fill = table_fill
164
        ws[col + '7'].font = name_font
165
        ws[col + '7'].alignment = c_c_alignment
166
        ws[col + '7'] = report['energycategories'][i]['name'] + \
167
            " (" + report['energycategories'][i]['unit_of_measure'] + ")"
168
        ws[col + '7'].border = f_border
169
170
        col = get_column_letter(column_index_from_string(col) + 1)
171
        ws[col + '7'].fill = table_fill
172
        ws[col + '7'].font = name_font
173
        ws[col + '7'].alignment = c_c_alignment
174
        ws[col + '7'] = report['energycategories'][i]['name'] + \
175
            " " + _('Maximum Load') + " (" + report['energycategories'][i]['unit_of_measure'] + ")"
176
        ws[col + '7'].border = f_border
177
178
    current_row_number = 8
179
    for i in range(0, len(report['tenants'])):
180
181
        ws['B' + str(current_row_number)].font = title_font
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable str does not seem to be defined.
Loading history...
182
        ws['B' + str(current_row_number)].border = f_border
183
        ws['B' + str(current_row_number)].alignment = c_c_alignment
184
        ws['B' + str(current_row_number)] = report['tenants'][i]['tenant_name']
185
186
        ws['C' + str(current_row_number)].font = title_font
187
        ws['C' + str(current_row_number)].border = f_border
188
        ws['C' + str(current_row_number)].alignment = c_c_alignment
189
        ws['C' + str(current_row_number)] = report['tenants'][i]['space_name']
190
191
        ca_len = len(report['tenants'][i]['values'])
192
        for j in range(0, ca_len):
193
            col = get_column_letter(column_index_from_string('D') + j * 2)
194
            ws[col + str(current_row_number)].font = title_font
195
            ws[col + str(current_row_number)].border = f_border
196
            ws[col + str(current_row_number)].alignment = c_c_alignment
197
            ws[col + str(current_row_number)] = report['tenants'][i]['values'][j]
198
199
            col = get_column_letter(column_index_from_string(col) + 1)
200
            ws[col + str(current_row_number)].font = title_font
201
            ws[col + str(current_row_number)].border = f_border
202
            ws[col + str(current_row_number)].alignment = c_c_alignment
203
            ws[col + str(current_row_number)] = report['tenants'][i]['maximum'][j]
204
        current_row_number += 1
205
206
    filename = str(uuid.uuid4()) + '.xlsx'
207
    wb.save(filename)
208
209
    return filename
210