Merge branch 'OG' into 'master'

update ESG打分模型

See merge request root/tfse_rating!33
This commit is contained in:
王思川 2022-02-17 08:46:01 +00:00
commit f75d16d939
8 changed files with 514 additions and 164 deletions

View File

@ -1,6 +1,9 @@
import copy
from Esg.scripts.environmental import environmental_rating
from Esg.scripts.governance import governance_rating
from Esg.scripts.social import social_rating
from common.scripts import read_json_file
class EsgModel:
@ -36,20 +39,70 @@ class EsgModel:
self.cid = param['企业ID']
self.company = param['企业名称']
self.period = param['评价年度']
self.questionnaire = param['填报问卷']
self.esg_score = self.esg_rating_scripts()
self.esg_score = self.esg_rating_scripts(param)
def esg_rating_scripts(self):
@staticmethod
def esg_rating_scripts(param):
"""
esg打分方法
Parameters:
-
param dict 数据模板
Returns:
score dict 分数
"""
score = dict()
score['环境'] = environmental_rating(self.questionnaire)
score['社会责任'] = social_rating(self.questionnaire)
score['公司治理'] = governance_rating(self.questionnaire)
score['合计'] = sum(score.values())
score['环境得分'] = environmental_rating(param)
score['社会得分'] = social_rating(param)
score['公司治理得分'] = governance_rating(param)
score['合计'] = score['环境得分']['合计'] + score['社会得分']['合计'] + score['公司治理得分']['合计']
return score
def esg_rating_result(self):
"""
整合打分结果
Parameters:
score dict 打分结果
Returns:
result dict esg得分
"""
score = copy.deepcopy(self.esg_score)
result = dict()
result['企业名称'] = self.company
result['企业ID'] = self.cid
result['评价ID'] = self.rid
result['评价年度'] = self.period
result['评价等级'] = self.score_rank(score['合计'])
result['环境得分'] = score['环境得分']
result['环境得分'] = score['环境得分']
result['社会得分'] = score['环境得分']
result['公司治理得分'] = score['环境得分']
result['合计'] = score['合计']
return result
@staticmethod
def score_rank(param):
"""
描述
Parameters:
param float esg分数合计
Returns:
result str 评价等级
"""
if param >= 80:
level = 'A'
elif param >= 50:
level = 'B'
elif param >= 30:
level = 'C'
else:
level = 'D'
return level
if __name__ == '__main__':
m = EsgModel()
data = read_json_file('/Esg/static/template_data.json')
m.prepare_params(data)
r = m.esg_rating_result()

View File

@ -1,4 +1,4 @@
from common.scripts import read_json_file
import operator
def environmental_rating(param):
@ -9,25 +9,36 @@ def environmental_rating(param):
Returns:
score float 环境部分得分
"""
result = dict()
result['单位收入二氧化碳排放'] = calculation_01(param)
result['单位收入的能耗'] = calculation_02(param)
result['单位收入的耗水'] = calculation_03(param)
result['绿色业务收入占比(%'] = calculation_04(param)
result['公司是否有温室气体减排目标'] = calculation_05(param)
result['企业是否有节能目标'] = calculation_06(param)
result['企业是否有节约用水目标'] = calculation_07(param)
result['是否有绿色业务'] = calculation_08(param)
result['近三年是否被环境或水务等监管部门处罚'] = calculation_09(param)
result['国家双碳目标对企业业务是否有不利影响'] = calculation_10(param)
result['国家双碳目标对企业业务是否有有利影响'] = calculation_11(param)
result['企业是否使用风电、光电、水电等清洁能源,是否使用清洁交通工具'] = calculation_02(param)
fraction = list()
if calculation_09(param) == 'E=0':
if result['近三年是否被环境或水务等监管部门处罚'] == 'E=0':
score = 0
else:
fraction.append(calculation_01(param))
fraction.append(calculation_02(param))
fraction.append(calculation_03(param))
fraction.append(calculation_04(param))
fraction.append(calculation_05(param))
fraction.append(calculation_06(param))
fraction.append(calculation_07(param))
fraction.append(calculation_08(param))
fraction.append(calculation_10(param))
fraction.append(calculation_11(param))
fraction.append(calculation_12(param))
for key, value in result.items():
if key == '近三年是否被环境或水务等监管部门处罚':
continue
else:
fraction.append(value)
score = sum(fraction)
return score
result['合计'] = score
return result
def calculation_01(param):
@ -38,6 +49,8 @@ def calculation_01(param):
Returns:
score int 得分
"""
# Parameter
three_year_data = sorted(param['环境问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
def calculation_co2(data):
"""
@ -62,15 +75,15 @@ def calculation_01(param):
amount = sum(total)
return amount
year_2020 = calculation_co2(param['环境问卷']['近三年公司数据'][0])
year_2019 = calculation_co2(param['环境问卷']['近三年公司数据'][1])
year_2018 = calculation_co2(param['环境问卷']['近三年公司数据'][2])
year_begin = calculation_co2(three_year_data[0])
year_middle = calculation_co2(three_year_data[1])
year_end = calculation_co2(three_year_data[2])
factor_01 = ((year_2020/year_2018)**(1/2)-1) <= -0.04 and year_2018 >= year_2019 >= year_2020
factor_02 = -0.04 < ((year_2020/year_2018)**(1/2)-1) <= -0.03 and year_2018 >= year_2019 >= year_2020
factor_03 = -0.03 < ((year_2020/year_2018)**(1/2)-1) <= -0.02 and year_2018 >= year_2019 >= year_2020
factor_04 = -0.02 < ((year_2020/year_2018)**(1/2)-1) <= 0.01 and year_2018 >= year_2019 >= year_2020
factor_05 = -0.01 < ((year_2020/year_2018)**(1/2)-1) <= 0 and year_2018 >= year_2019 >= year_2020
factor_01 = ((year_end/year_begin)**(1/2)-1) <= -0.04 and year_begin >= year_middle >= year_end
factor_02 = -0.04 < ((year_end/year_begin)**(1/2)-1) <= -0.03 and year_begin >= year_middle >= year_end
factor_03 = -0.03 < ((year_end/year_begin)**(1/2)-1) <= -0.02 and year_begin >= year_middle >= year_end
factor_04 = -0.02 < ((year_end/year_begin)**(1/2)-1) <= 0.01 and year_begin >= year_middle >= year_end
factor_05 = -0.01 < ((year_end/year_begin)**(1/2)-1) <= 0 and year_begin >= year_middle >= year_end
if factor_01:
score = 15
@ -96,6 +109,9 @@ def calculation_02(param):
Returns:
score int 得分
"""
# Parameter
three_year_data = sorted(param['环境问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
def calculation_co2(data):
"""
计算每年能耗
@ -119,14 +135,14 @@ def calculation_02(param):
amount = sum(total)
return amount
year_2020 = calculation_co2(param['环境问卷']['近三年公司数据'][0])
year_2019 = calculation_co2(param['环境问卷']['近三年公司数据'][1])
year_2018 = calculation_co2(param['环境问卷']['近三年公司数据'][2])
year_begin = calculation_co2(three_year_data[0])
year_middle = calculation_co2(three_year_data[1])
year_end = calculation_co2(three_year_data[2])
factor_01 = ((year_2020/year_2018)**(1/2)-1) <= -0.028 and year_2018 >= year_2019 >= year_2020
factor_02 = -0.028 < ((year_2020/year_2018)**(1/2)-1) <= -0.02 and year_2018 >= year_2019 >= year_2020
factor_03 = -0.02 < ((year_2020/year_2018)**(1/2)-1) <= -0.01 and year_2018 >= year_2019 >= year_2020
factor_04 = -0.01 < ((year_2020/year_2018)**(1/2)-1) <= 0 and year_2018 >= year_2019 >= year_2020
factor_01 = ((year_end/year_begin)**(1/2)-1) <= -0.028 and year_begin >= year_middle >= year_end
factor_02 = -0.028 < ((year_end/year_begin)**(1/2)-1) <= -0.02 and year_begin >= year_middle >= year_end
factor_03 = -0.02 < ((year_end/year_begin)**(1/2)-1) <= -0.01 and year_begin >= year_middle >= year_end
factor_04 = -0.01 < ((year_end/year_begin)**(1/2)-1) <= 0 and year_begin >= year_middle >= year_end
if factor_01:
score = 11
@ -150,12 +166,15 @@ def calculation_03(param):
Returns:
score int 得分
"""
year_2020 = param['环境问卷']['近三年公司数据'][0]['水(吨)']
year_2019 = param['环境问卷']['近三年公司数据'][1]['水(吨)']
year_2018 = param['环境问卷']['近三年公司数据'][2]['水(吨)']
# Parameter
three_year_data = sorted(param['环境问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor_01 = ((year_2020/year_2018)**(1/2)-1) <= -0.01 and year_2018 >= year_2019 >= year_2020
factor_02 = -0.01 < ((year_2020/year_2018)**(1/2)-1) <= 0 and year_2018 >= year_2019 >= year_2020
year_begin = three_year_data[0]['水(吨)']
year_middle = three_year_data[1]['水(吨)']
year_end = three_year_data[2]['水(吨)']
factor_01 = ((year_end/year_begin)**(1/2)-1) <= -0.01 and year_begin >= year_middle >= year_end
factor_02 = -0.01 < ((year_end/year_begin)**(1/2)-1) <= 0 and year_begin >= year_middle >= year_end
if factor_01:
score = 6
@ -175,8 +194,11 @@ def calculation_04(param):
Returns:
score int 得分
"""
income = param['公司收入'][0]
green_income = param['环境问卷']['近三年公司数据'][0]['绿色业务收入(万元)']
# Parameter
three_year_data = sorted(param['环境问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
income = param['公司收入'][three_year_data[2]['年份']]
green_income = three_year_data[2]['绿色业务收入(万元)']
prop = round(green_income / income, 2)
if prop >= 50:
@ -201,6 +223,7 @@ def calculation_05(param):
Returns:
score int 得分
"""
# Parameter
answer = param['环境问卷']['其他类型问卷'][0]
if answer[0] == '' and answer[1] is not None:
@ -335,9 +358,3 @@ def calculation_12(param):
score = 0
return score
if __name__ == '__main__':
data = read_json_file('/Esg/static/template_data.json')
E_score = environmental_rating(data)
print(E_score)

View File

@ -1,4 +1,4 @@
from common.scripts import read_json_file
import operator
def governance_rating(param):
@ -9,20 +9,25 @@ def governance_rating(param):
Returns:
score float 治理部分得分
"""
result = dict()
result['企业性质'] = calculation_01(param)
result['公司是否设有董事会'] = calculation_02(param)
result['公司是否设有监事会'] = calculation_03(param)
result['董监高平均拥有的行业经验年数'] = calculation_04(param)
result['董监高近三年离职率'] = calculation_05(param)
result['公司近三年信息披露及时、可靠、完备、审计质量'] = calculation_06(param)
result['公司董事会近三年年均开会次数'] = calculation_07(param)
result['净资产收益率'] = calculation_08(param)
result['公司是否有审计报告'] = calculation_09(param)
fraction = list()
for value in result.values():
fraction.append(value)
fraction.append(calculation_01(param))
fraction.append(calculation_02(param))
fraction.append(calculation_03(param))
fraction.append(calculation_04(param))
fraction.append(calculation_05(param))
fraction.append(calculation_06(param))
fraction.append(calculation_07(param))
fraction.append(calculation_08(param))
fraction.append(calculation_09(param))
score = sum(fraction)
result['合计'] = score
return score
return result
def calculation_01(param):
@ -165,12 +170,14 @@ def calculation_08(param):
Returns:
score int 得分
"""
data = param['治理问卷']['近三年公司数据']
year_2020 = data[0]['公司净利润(万元)'] / data[0]['公司净资产(万元)'] * 100
year_2019 = data[1]['公司净利润(万元)'] / data[1]['公司净资产(万元)'] * 100
year_2018 = data[2]['公司净利润(万元)'] / data[2]['公司净资产(万元)'] * 100
# Parameter
three_year_data = sorted(param['治理问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
average = (year_2020 + year_2019 + year_2018)/3
year_begin = three_year_data[0]['公司净利润(万元)'] / three_year_data[0]['公司净资产(万元)'] * 100
year_middle = three_year_data[1]['公司净利润(万元)'] / three_year_data[1]['公司净资产(万元)'] * 100
year_end = three_year_data[2]['公司净利润(万元)'] / three_year_data[2]['公司净资产(万元)'] * 100
average = (year_end + year_middle + year_begin)/3
if average >= 15:
score = 6
@ -192,20 +199,16 @@ def calculation_09(param):
Returns:
score int 得分
"""
data = param['治理问卷']['近三年公司数据']
year_2020 = data[0]['公司是否有审计报告']
year_2019 = data[1]['公司是否有审计报告']
year_2018 = data[2]['公司是否有审计报告']
# Parameter
three_year_data = sorted(param['治理问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
if year_2020 == year_2019 == year_2018 == '':
year_begin = three_year_data[0]['公司是否有审计报告']
year_middle = three_year_data[1]['公司是否有审计报告']
year_end = three_year_data[2]['公司是否有审计报告']
if year_end == year_middle == year_begin == '':
score = 2
else:
score = 0
return score
if __name__ == '__main__':
data = read_json_file('/Esg/static/template_data.json')
S_score = governance_rating(data)
print(S_score)

View File

@ -1,4 +1,4 @@
from common.scripts import read_json_file
import operator
def social_rating(param):
@ -9,28 +9,39 @@ def social_rating(param):
Returns:
score float 社会部分得分
"""
result = dict()
result['离职人数占比'] = calculation_01(param)
result['人均薪酬涨幅'] = calculation_02(param)
result['劳动合同中的工作时长(周)'] = calculation_03(param)
result['劳动纠纷'] = calculation_04(param)
result['安全事故'] = calculation_05(param)
result['提供培训'] = calculation_06(param)
result['社保缴纳是否符合当地标准'] = calculation_07(param)
result['公积金缴纳是否符合当地标准'] = calculation_08(param)
result['是否提供员工体检'] = calculation_09(param)
result['是否提供带薪假期'] = calculation_10(param)
result['公司从前三大供货商拿货占比'] = calculation_11(param)
result['公司前3大客户销量占比'] = calculation_12(param)
result['公司返修、退回、投诉产品比例(%'] = calculation_13(param)
result['扶贫+捐赠规模(万元)'] = calculation_14(param)
result['司法风险'] = calculation_15(param)
fraction = list()
if calculation_15(param) == 'S=0':
if result['司法风险'] == 'S=0':
score = 0
else:
fraction.append(calculation_01(param))
fraction.append(calculation_02(param))
fraction.append(calculation_03(param))
fraction.append(calculation_04(param))
fraction.append(calculation_05(param))
fraction.append(calculation_06(param))
fraction.append(calculation_07(param))
fraction.append(calculation_08(param))
fraction.append(calculation_09(param))
fraction.append(calculation_10(param))
fraction.append(calculation_11(param))
fraction.append(calculation_12(param))
fraction.append(calculation_13(param))
fraction.append(calculation_14(param))
for key, value in result.items():
if key == '司法风险':
continue
else:
fraction.append(value)
score = sum(fraction)
return score
result['合计'] = score
return result
def calculation_01(param):
@ -41,13 +52,15 @@ def calculation_01(param):
Returns:
score int 得分
"""
social_data = param['社会问卷']['近三年公司数据']
year_2020 = round(social_data[0]['当年离职人数'] / social_data[0]['员工总数'], 2)
year_2019 = round(social_data[1]['当年离职人数'] / social_data[1]['员工总数'], 2)
year_2018 = round(social_data[2]['当年离职人数'] / social_data[2]['员工总数'], 2)
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor_01 = (year_2018 + year_2019 + year_2020)/3*100 <= 20
factor_02 = 20 < (year_2018 + year_2019 + year_2020)/3*100 <= 30
year_begin = round(three_year_data[0]['当年离职人数'] / three_year_data[0]['员工总数'], 2)
year_middle = round(three_year_data[1]['当年离职人数'] / three_year_data[1]['员工总数'], 2)
year_end = round(three_year_data[2]['当年离职人数'] / three_year_data[2]['员工总数'], 2)
factor_01 = (year_begin + year_middle + year_end) / 3 * 100 <= 20
factor_02 = 20 < (year_begin + year_middle + year_end) / 3 * 100 <= 30
if factor_01:
score = 5
@ -67,10 +80,13 @@ def calculation_02(param):
Returns:
score int 得分
"""
year_2020 = param['社会问卷']['近三年公司数据'][0]['人均薪酬水平(元/月)']
year_2018 = param['社会问卷']['近三年公司数据'][2]['人均薪酬水平(元/月)']
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor = (year_2020/year_2018)**(1/2) - 1 >= 0.03
year_begin = three_year_data[0]['人均薪酬水平(元/月)']
year_end = three_year_data[2]['人均薪酬水平(元/月)']
factor = (year_end / year_begin) ** (1 / 2) - 1 >= 0.03
if factor:
score = 2
@ -88,11 +104,14 @@ def calculation_03(param):
Returns:
score int 得分
"""
year_2020 = param['社会问卷']['近三年公司数据'][0]['劳动合同要求工作时长(每周小时数)']
year_2019 = param['社会问卷']['近三年公司数据'][1]['劳动合同要求工作时长(每周小时数)']
year_2018 = param['社会问卷']['近三年公司数据'][2]['劳动合同要求工作时长(每周小时数)']
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor = (year_2020 + year_2019 + year_2018) / 3 <= 45
year_begin = three_year_data[0]['劳动合同要求工作时长(每周小时数)']
year_middle = three_year_data[1]['劳动合同要求工作时长(每周小时数)']
year_end = three_year_data[2]['劳动合同要求工作时长(每周小时数)']
factor = (year_end + year_middle + year_begin) / 3 <= 45
if factor:
score = 4
@ -110,11 +129,14 @@ def calculation_04(param):
Returns:
score int 得分
"""
year_2020 = param['社会问卷']['近三年公司数据'][0]['劳资纠纷次数']
year_2019 = param['社会问卷']['近三年公司数据'][1]['劳资纠纷次数']
year_2018 = param['社会问卷']['近三年公司数据'][2]['劳资纠纷次数']
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor = (year_2020 + year_2019 + year_2018) <= 0
year_begin = three_year_data[0]['劳资纠纷次数']
year_middle = three_year_data[1]['劳资纠纷次数']
year_end = three_year_data[2]['劳资纠纷次数']
factor = (year_end + year_middle + year_begin) <= 0
if factor:
score = 3
@ -132,11 +154,14 @@ def calculation_05(param):
Returns:
score int 得分
"""
year_2020 = param['社会问卷']['近三年公司数据'][0]['安全事故发生次数']
year_2019 = param['社会问卷']['近三年公司数据'][1]['安全事故发生次数']
year_2018 = param['社会问卷']['近三年公司数据'][2]['安全事故发生次数']
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor = (year_2020 + year_2019 + year_2018) <= 0
year_begin = three_year_data[0]['安全事故发生次数']
year_middle = three_year_data[1]['安全事故发生次数']
year_end = three_year_data[2]['安全事故发生次数']
factor = (year_end + year_middle + year_begin) <= 0
if factor:
score = 3
@ -154,12 +179,15 @@ def calculation_06(param):
Returns:
score int 得分
"""
year_2020 = param['社会问卷']['近三年公司数据'][0]['组织培训次数']
year_2019 = param['社会问卷']['近三年公司数据'][1]['组织培训次数']
year_2018 = param['社会问卷']['近三年公司数据'][2]['组织培训次数']
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor_01 = (year_2020 + year_2019 + year_2018) >= 4
factor_02 = (year_2020 + year_2019 + year_2018) >= 1
year_begin = three_year_data[0]['组织培训次数']
year_middle = three_year_data[1]['组织培训次数']
year_end = three_year_data[2]['组织培训次数']
factor_01 = (year_end + year_middle + year_begin) >= 4
factor_02 = (year_end + year_middle + year_begin) >= 1
if factor_01:
score = 5
@ -251,10 +279,13 @@ def calculation_11(param):
Returns:
score int 得分
"""
year_2020 = param['社会问卷']['近三年公司数据'][0]['公司从前3大供应商拿货占全部供应商比例%']
year_2018 = param['社会问卷']['近三年公司数据'][2]['公司从前3大供应商拿货占全部供应商比例%']
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor = year_2018 >= year_2020
year_begin = three_year_data[0]['公司从前3大供应商拿货占全部供应商比例%']
year_end = three_year_data[2]['公司从前3大供应商拿货占全部供应商比例%']
factor = year_begin >= year_end
if factor:
score = 1
@ -272,10 +303,13 @@ def calculation_12(param):
Returns:
score int 得分
"""
year_2020 = param['社会问卷']['近三年公司数据'][0]['公司前3大客户销售额占全部销售比例%']
year_2018 = param['社会问卷']['近三年公司数据'][2]['公司前3大客户销售额占全部销售比例%']
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor = year_2018 >= year_2020
year_begin = three_year_data[0]['公司前3大客户销售额占全部销售比例%']
year_end = three_year_data[2]['公司前3大客户销售额占全部销售比例%']
factor = year_begin >= year_end
if factor:
score = 1
@ -293,10 +327,13 @@ def calculation_13(param):
Returns:
score int 得分
"""
year_2020 = param['社会问卷']['近三年公司数据'][0]['返修、退回、投诉产品对应销售额占全部销售比例(%']
year_2018 = param['社会问卷']['近三年公司数据'][2]['返修、退回、投诉产品对应销售额占全部销售比例(%']
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor = year_2018 >= year_2020
year_end = three_year_data[0]['返修、退回、投诉产品对应销售额占全部销售比例(%']
year_begin = three_year_data[2]['返修、退回、投诉产品对应销售额占全部销售比例(%']
factor = year_begin >= year_end
if factor:
score = 1
@ -314,11 +351,14 @@ def calculation_14(param):
Returns:
score int 得分
"""
year_2020 = param['社会问卷']['近三年公司数据'][0]['扶贫+捐赠规模(万元)']
year_2019 = param['社会问卷']['近三年公司数据'][1]['扶贫+捐赠规模(万元)']
year_2018 = param['社会问卷']['近三年公司数据'][2]['扶贫+捐赠规模(万元)']
# Parameter
three_year_data = sorted(param['社会问卷']['近三年公司数据'], key=operator.itemgetter('年份'), reverse=False)
factor_01 = (year_2020 + year_2019 + year_2018) > 0
year_begin = three_year_data[0]['扶贫+捐赠规模(万元)']
year_middle = three_year_data[1]['扶贫+捐赠规模(万元)']
year_end = three_year_data[2]['扶贫+捐赠规模(万元)']
factor_01 = (year_end + year_middle + year_begin) > 0
if factor_01:
score = 5
@ -346,9 +386,3 @@ def calculation_15(param):
score = 0
return score
if __name__ == '__main__':
data = read_json_file('/Esg/static/template_data.json')
S_score = social_rating(data)
print(S_score)

View File

@ -2,8 +2,13 @@
"评价ID": "EsfsSg02",
"企业ID": "Z1tfsw6r",
"企业名称": "远东资信评估有限公司",
"评价年度": "2021年",
"所属行业": ["制造业", "化学工业"],
"公司收入": [200232, 253014, 190123],
"公司收入": {
"2018年": 203156,
"2019年": 203156,
"2020年": 203156
},
"环境问卷": {
"近三年公司数据": [
{

View File

@ -11,17 +11,18 @@ from Report.scripts.PdfStyle import cover_space, cover_company_style, cover_repo
chapter_style, \
section_style, adjust_line_width, para_style_single, para_style_bold, table_name, table_unit, table_mark, \
adjust_table_widths, adjust_table_style, Seashell4, toc_style_1, table_content_style, toc_style_2, darkGolden, \
adjust_table_data
adjust_table_data, para_bold_style, para_style_esg
from Report.scripts.path_tool import gen_pdf_path, get_pic_path
from common.scripts import read_json_file
# 页码起始设置
offset = 3
# offset = 3
class HeaderAndFooterCanvas(canvas.Canvas):
def __init__(self, *args, **kwargs):
canvas.Canvas.__init__(self, *args, **kwargs)
self._saved_page_states = []
self.offeset = 2
def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
@ -29,16 +30,12 @@ class HeaderAndFooterCanvas(canvas.Canvas):
def draw_header_and_footer(self, page_count):
# 把封面加上
# if self._pageNumber == 1:
# self.drawImage(get_pic_path(picName='cover.png'), 0, 0, 596, 842)
self.setFont("Helvetica", 7)
if self._pageNumber > offset:
if self._pageNumber > self.offeset:
self.setFont('pingbold', 8)
self.setFillColor(HexColor(Seashell4))
self.drawString(74, 805, "远东资信评估有限公司")
self.drawString(74, 40, "%d / %d" % (self._pageNumber - offset, page_count - offset))
self.drawString(74, 40, "%d / %d" % (self._pageNumber - self.offeset, page_count - self.offeset))
self.setStrokeColor(darkGolden)
self.setLineWidth(2.5)
@ -57,10 +54,11 @@ class HeaderAndFooterCanvas(canvas.Canvas):
class MyDocTemplate(BaseDocTemplate):
def __init__(self, filename, **kw):
self.allowSplitting = 0
self.allowSplitting = 1
BaseDocTemplate.__init__(self, filename, **kw)
template = PageTemplate('normal', [Frame(2.5 * cm, 2.5 * cm, 15 * cm, 25 * cm, id='F1')])
self.addPageTemplates(template)
self.offeset = kw['offeset']
def afterFlowable(self, flowable):
if flowable.__class__.__name__ == 'Paragraph':
@ -74,7 +72,7 @@ class MyDocTemplate(BaseDocTemplate):
else:
return
e = (level, text, self.page - offset)
e = (level, text, self.page - self.offeset)
self.notify('TOCEntry', e)
@ -83,19 +81,26 @@ class ReportGenerator:
def __init__(self, **kwargs):
# 文本数据
self.text_model = kwargs['text_model']
# 调用模板在临时报告文件夹中创建指定名称的PDF文档
self.doc = MyDocTemplate(gen_pdf_path(name=kwargs['name']))
if '报告类型' in self.text_model:
# 调用模板在临时报告文件夹中创建指定名称的PDF文档
self.doc = MyDocTemplate(gen_pdf_path(name=kwargs['name']), offeset=2)
else:
self.doc = MyDocTemplate(gen_pdf_path(name=kwargs['name']), offeset=3)
# 内容框
self.story = list()
# 生成报告
def gen_report(self):
self.gen_cover()
self.gen_menu()
self.gen_main_part()
# 将内容输出到PDF中
self.doc.multiBuild(self.story, canvasmaker=HeaderAndFooterCanvas)
if '报告类型' in self.text_model:
self.gen_esg_cover()
self.gen_menu()
self.gen_esg_part()
self.doc.multiBuild(self.story, canvasmaker=HeaderAndFooterCanvas)
else:
self.gen_cover()
self.gen_menu()
self.gen_main_part()
self.doc.multiBuild(self.story, canvasmaker=HeaderAndFooterCanvas)
# 设置章节、小节标题
def set_head(self, text, sty):
@ -123,6 +128,15 @@ class ReportGenerator:
self.story.append(Paragraph(data['生成日期'], cover_time_style))
self.story.append(PageBreak())
def gen_esg_cover(self):
data = self.text_model
self.story.append(Paragraph('.', cover_space))
self.story.append(Paragraph(data['企业名称'], cover_company_style))
self.story.append(Paragraph('ESG评价报告', cover_report_style))
self.story.append(Image(get_pic_path(pic_name='ydzx.png'), width=202, height=37))
self.story.append(Paragraph(data['生成日期'], cover_time_style))
self.story.append(PageBreak())
# 正文
def gen_main_part(self):
data = self.text_model['报告内容']
@ -161,3 +175,18 @@ class ReportGenerator:
style = adjust_table_style(part['表格'])
td = adjust_table_data(part['表格'])
self.story.append(Table(td, style=style))
def gen_esg_part(self):
data = self.text_model['报告内容']
for chapter in data:
self.set_head(chapter['章节'], chapter_style)
for section in chapter['章节内容']:
# 段落
if list(section.keys())[0] == '段落':
self.story.append(Paragraph(adjust_line_width(section['段落'], 8), para_style_single))
if __name__ == '__main__':
text_data = read_json_file('/Report/static/ReportTemplates/ESG报告.json')
m = ReportGenerator(name=text_data['企业名称'], text_model=text_data)
m.gen_report()

View File

@ -52,16 +52,23 @@ table_name = PS(name="table_name", fontName="pingbold", fontSize=8, leading=16,
table_unit = PS(name="table_unit", fontName="SimHei", fontSize=6, leading=8, alignment=TA_RIGHT, spaceBefore=2)
table_mark = PS(name="table_mark", fontName="SimHei", fontSize=6, leading=16, alignment=TA_LEFT, spaceBefore=2)
table_style = getSampleStyleSheet()
table_style.add(ParagraphStyle(fontName='SimHei', name='Song', leading=12, fontSize=8, spaceBefore=2, alignment=TA_CENTER))
table_style.add(ParagraphStyle(fontName='SimHei', name='Long', leading=12, fontSize=8, spaceBefore=2, alignment=TA_LEFT))
table_style.add(ParagraphStyle(fontName='SimHei', name='Longs', leading=9, fontSize=6, spaceBefore=2, alignment=TA_LEFT))
table_style.add(ParagraphStyle(fontName='SimHei', name='Songs', leading=9, fontSize=6, spaceBefore=2, alignment=TA_CENTER))
table_style.add(ParagraphStyle(fontName='SimHei', name='Song_small', leading=7, fontSize=5, spaceBefore=2, alignment=TA_CENTER))
table_style.add(
ParagraphStyle(fontName='SimHei', name='Song', leading=12, fontSize=8, spaceBefore=2, alignment=TA_CENTER))
table_style.add(
ParagraphStyle(fontName='SimHei', name='Long', leading=12, fontSize=8, spaceBefore=2, alignment=TA_LEFT))
table_style.add(
ParagraphStyle(fontName='SimHei', name='Longs', leading=9, fontSize=6, spaceBefore=2, alignment=TA_LEFT))
table_style.add(
ParagraphStyle(fontName='SimHei', name='Songs', leading=9, fontSize=6, spaceBefore=2, alignment=TA_CENTER))
table_style.add(
ParagraphStyle(fontName='SimHei', name='Song_small', leading=7, fontSize=5, spaceBefore=2, alignment=TA_CENTER))
# para
para_style_single = PS(name="para_style_single", fontName="SimHei", fontSize=8, leading=18, alignment=TA_LEFT,
spaceBefore=6)
para_style_normal = PS(name="para_style_normal", fontName="SimHei", fontSize=8, leading=18, alignment=TA_LEFT,
spaceBefore=6, firstLineIndent=16)
para_style_esg = PS(name="para_style_esg", fontName="SimHei", fontSize=10, leading=18, alignment=TA_LEFT,
spaceBefore=6)
para_style_bold = PS(name="para_style_bold", fontName="pingbold", fontSize=10, leading=18, alignment=TA_LEFT,
spaceBefore=6)
para_bold_style = PS(name="para_style", fontName="pingbold", fontSize=9, leading=18, alignment=TA_LEFT, spaceBefore=6)

View File

@ -0,0 +1,202 @@
{
"企业名称": "远东资信评估有限公司",
"生成日期": "2022-02-14",
"报告类型": "ESG",
"报告内容": [
{
"章节": "声明",
"章节内容": [
{
"段落": "本ESG评价报告主要基于公司提供信息依据合理的标准和程序做出的独立分析和判断。远东资信评估有限公司不对因使用本报告意见而产生的后果承担责任。本报告可能存在固有局限性例如信息主要由公司提供而远东资信无法对信息正确性进行分辨。"
},
{
"段落": "为减少企业填写、搜集信息工作量也为了标准化之目的我们对模型做了简化处理。如果企业有意愿进一步了解ESG我们很愿意提供有针对性、线下、定制化的咨询服务。"
},
{
"段落": "评价不是目的,为企业提供帮助是我们的初衷。"
}
]
},
{
"章节": "远东资信",
"章节内容": [
{
"段落": "远东资信评估有限公司以下简称“远东资信”成立于1988年是中国第一家社会化专业资信评估公司是信用评级领域的头部公司。在绿色低碳方面远东资信已在绿色金融、碳金融、ESG领域积累了丰富经验。"
},
{
"段落": "远东资信受天府股交中心委托将为挂牌企业提供ESG服务。"
},
{
"段落": "联系电话:{}"
},
{
"段落": "联系人:{}"
}
]
},
{
"章节": "ESG",
"章节内容": [
{
"段落": "ESG是“环境Environmental”、“社会Social”和“公司治理Governance”的简称关注的是企业与环境的相互影响、履行社会责任的情况和公司治理绩效。ESG与企业业绩水平和长远发展存在密切关系已受到全世界企业、投资者的广泛认可。"
},
{
"段落": "在港上市公司已经在按照监管要求披露ESG报告A股上市公司也开始发布社会责任报告、可持续发展报告、ESG报告。证监会正在制定相关信息披露制度以使A股上市公司能按照要求披露标准化的ESG信息。"
}
]
},
{
"章节": "模型说明",
"章节内容": [
{
"段落": "我们的ESG模型参考了国际主流ESG体系架构结合中国资本市场发展情况、监管政策和公司ESG实践形成了本土化特色指标体系此外这次是受股交中心委托对挂牌中小企业做ESG评价因此指标考虑了中小企业特征。我们将指标细分为基础指标和调节指标对于基础指标我们按照重要性赋予分值合计100分调节指标是在公司基础分数之上给予加减分处理比如公司被监管处罚过或者有绿色低碳业务等。"
},
{
"段落": "在此基础上,我们对公司划分等级,如下"
},
{
"段落": "A——对应中小企业ESG为优秀级别"
},
{
"段落": "B——对应中小企业ESG为正常级别"
},
{
"段落": "C——对应中小企业ESG为关注级别"
},
{
"段落": "D——对应中小企业ESG为不合格级别"
}
]
},
{
"章节": "基本信息",
"章节内容": [
{
"段落": "公司名称:{}"
},
{
"段落": "所属行业:{}"
}
]
},
{
"章节": "公司ESG等级",
"章节内容": [
{
"段落": "经分析公司ESG等级为{}"
}
]
},
{
"章节": "环境部分",
"章节内容": [
{
"段落": "我们重点关注的环境因素包括二氧化碳排放、能耗、资源消耗、绿色业务等情况。"
},
{
"段落": "二氧化碳——二氧化碳主要来自1企业直接消耗的燃料比如燃气、汽柴油等所导致的温室气体排放2企业购买并使用电力等所产生的间接排放。"
},
{
"段落": "二氧化碳排放——{date_range}年,公司总的二氧化碳排放(单位:千克){co2_emissions}。"
},
{
"段落": "单位二氧化碳排放——{date_range}年,公司每万元收入二氧化碳排放(单位:千克){CO2_year_01}、{CO2_year_02}、{CO2_year_03}。{year_02}年、{year_03}年同比分别为{year01_on_year02}、{year02_on_year03}。{year_03}年,同行业公司该指标区间为{industry_ indicators},该指标均值为{industry_ indicators_average},该指标中位数为{industry_ indicators_median},公司较之行业中位数{median_comparison}。"
},
{
"段落": "能耗——能耗包括企业消耗的电量、汽柴油等。为表述方便,我们将不同能源消耗均转为以兆焦耳做单位。"
},
{
"段落": "能耗——{date_range}年,公司总的能耗(单位:兆焦耳){energy_consumption_year_01}、{energy_consumption_year_02}、{energy_consumption_year_03}。"
},
{
"段落": "单位能耗——{date_range}年,公司每万元收入能耗(单位:兆焦耳){sec_year_01}、{sec_year_02}、{sec_year_03}。{year_02}年、{year_03}年同比增长分别为{}、{}。{year_03}年,同行业公司该指标区间为{industry_ indicators},该指标均值为{industry_ indicators_average},该指标中位数为{industry_ indicators_median},公司较之行业中位数{median_comparison}。"
},
{
"段落": "能耗折算标准煤——{date_range}年,公司总的能耗折算为标准煤(单位:千克){standard_coal_year_01}、{standard_coal_year_02}、{standard_coal_year_03}。。"
},
{
"段落": "单位能耗折算标准煤——{date_range}年,公司每万元收入能耗折算为标准煤(单位:千克){standard_coal_year_01}、{standard_coal_year_02}、{standard_coal_year_03}。。"
},
{
"段落": "耗水——{date_range}年,公司总耗水(单位:吨){consume water_year_01}、{consume water_year_02}、{consume water_year_03}。"
},
{
"段落": "单位耗水——{date_range}年,公司每万元收入耗水(单位:吨){iwc_year_01}、{iwc_year_01}、{iwc_year_01}。{year_02}年、{year_03}年同比增长分别为{year01_on_year02}、{year02_on_year03}。{year_03}年,同行业公司该指标区间为{industry_ indicators},该指标均值为{industry_ indicators_average},该指标中位数为{industry_ indicators_median},公司较之行业中位数{median_comparison}。"
},
{
"段落": "{describe}"
},
{
"段落": "{describe}"
}
]
},
{
"章节": "社会部分",
"章节内容": [
{
"段落": "我们重点关注的社会因素包括雇佣、供应链、产品、社会贡献等。"
},
{
"段落": "离职率——{date_range}年,公司离职比例为{turnover_ratio_year_01}、{turnover_ratio_year_02}、{turnover_ratio_year_03}。{year_03}年,同行业公司该指标区间为{industry_ indicators},该指标均值为{industry_ indicators_average},该指标中位数为{industry_ indicators_median},公司较之行业中位数{median_comparison}。"
},
{
"段落": "人均薪酬水平——{date_range}年,公司人均薪酬水平为{salary_level_year_01}、{salary_level_year_02}、{salary_level_year_03}。{}年、{}年同比增长分别为{}、{}。{}年,同行业公司该指标区间为{},该指标均值为{},该指标中位数为{},公司较之行业中位数{}。"
},
{
"段落": "劳动纠纷——公司在近三年出现了劳动纠纷,这影响了公司的社会得分。"
},
{
"段落": "安全事故——公司在近三年出现了安全事故,这影响了公司的社会得分。"
},
{
"段落": "提供培训——{date_range}年,公司培训次数为{}、{}、{}。{year_03}年,同行业公司该指标均值为{}。"
},
{
"段落": "产品返修、退回、投诉——{date_range}年,公司返修、退回、投诉产品比例(%{rrc_year_01}、{rrc_year_02}、{rrc_year_03}。{year_03}年,同行业公司该指标均值为{industry_ indicators_average}。"
},
{
"段落": "扶贫和捐赠——公司在近三年有过扶贫、捐赠行为,这提高了公司社会得分。"
},
{
"段落": "法律诉讼作为被告、被执行人、失信人、行政处罚、税收违法、严重违法、经营异常——经查公司存在1项或多项的法律诉讼作为被告、被执行人、失信人、行政处罚、税收违法、严重违法、经营异常情况这影响了公司社会分数。"
}
]
},
{
"章节": "公司治理部分",
"章节内容": [
{
"段落": "我们重点关注的公司治理因素包括企业性质、董监高、专业能力、信息披露等。"
},
{
"段落": "董事会——公司未设立董事会,这影响了公司在治理方面的得分。"
},
{
"段落": "监事会——公司未设立监事会,这影响了公司在治理方面的得分。"
},
{
"段落": "董监高专业性——公司董监高平均拥有的行业经验年数{experience_year},同行业公司该指标均值为{industry_ indicators_average}。"
},
{
"段落": "董监高稳定性——公司董监高近3年离职率较高这影响了公司在治理方面的得分。"
},
{
"段落": "董事会——公司董事会近三年年均开会次数{},同行业公司该指标均值为{industry_ indicators_average}。"
}
]
},
{
"章节": "跋文",
"章节内容": [
{
"段落": "我们不确定企业有足够的耐心填写调查问卷因此我们提供的问卷模板是非常简化的相应的模型也做了简化处理。我们不确定企业有足够的耐心阅读ESG报告因此在内容上我们尽量做的简单明了。"
},
{
"段落": "我们能确定的是ESG对企业发展非常有帮助而我们在这方面有着深入的理解和丰富的经验可以为企业提供帮助欢迎有兴趣的企业咨询。"
}
]
}
]
}