509 lines
21 KiB
Python
509 lines
21 KiB
Python
import os
|
||
import time
|
||
|
||
from DBHelper.MongoHelperInstance import DB_GUA
|
||
from Modules.Models.FinancialIndicatorsModel import FinancialIndicatorsModel
|
||
from Modules.Models.ScoreAndRankModel import CreditIndexScore, ScoreAndRankModel, refs
|
||
from Modules.Rating.RatingObjects import RatingRecord
|
||
from Modules.Rating.RatingUtils import RatingUtils
|
||
from Modules.Reports.ReportDataModel import ReportDataModel
|
||
from Modules.Reports.ReportPathImpl import get_gen_report_path
|
||
from Modules.Reports.ReportPdfImpl import ReportGenerator
|
||
from Utils.CommonUtil import sub_dict
|
||
from Utils.ErrorUtil import APIReturnError
|
||
from Utils.ScoreUtils import ScoreUtils
|
||
|
||
|
||
class RatingImpl(object):
|
||
|
||
@staticmethod
|
||
def before_create(**kwargs):
|
||
"""新建评级前检查"""
|
||
cid = kwargs["cid"]
|
||
RatingUtils.check_cid_legal(kwargs["cid"])
|
||
rating_info = RatingUtils.in_progress_rating(cid)
|
||
|
||
if rating_info:
|
||
item = DB_GUA.find_single_data(
|
||
"评级数据",
|
||
"评级记录",
|
||
{"评级ID": rating_info["评级ID"]},
|
||
["企业名称", "报告期"]
|
||
)
|
||
return_data = dict()
|
||
return_data["企业名称"] = item["企业名称"]
|
||
return_data["报告期"] = item["报告期"]
|
||
else:
|
||
items = DB_GUA.find_all_data_with_single_sort(
|
||
"企业数据",
|
||
"财务数据",
|
||
{"企业ID": cid},
|
||
["企业名称", "报告期"],
|
||
{"报告期": -1}
|
||
)
|
||
report_dates = list()
|
||
for item in items:
|
||
if item["报告期"][5:] == "12-31":
|
||
report_dates.append(item["报告期"])
|
||
# report_dates = report_dates[:1]
|
||
return_data = dict()
|
||
return_data["企业名称"] = items[0]["企业名称"]
|
||
return_data["报告期"] = report_dates
|
||
|
||
return return_data
|
||
|
||
@staticmethod
|
||
def create(**kwargs):
|
||
"""新建评级"""
|
||
|
||
cid = kwargs["cid"]
|
||
report_date = kwargs["report_date"]
|
||
|
||
existed_rating = RatingUtils.in_progress_rating(cid)
|
||
|
||
# 继续评级
|
||
if existed_rating:
|
||
return existed_rating, "继续评级"
|
||
|
||
# 开始评级
|
||
else:
|
||
business_info = DB_GUA.find_single_data(
|
||
"企业数据",
|
||
"工商信息",
|
||
{"企业ID": cid},
|
||
["企业名称", "所在省份", "所在城市"]
|
||
)
|
||
|
||
rating_record = RatingRecord()
|
||
rating_record.rid = RatingUtils.make_new_rid()
|
||
rating_record.report_date = report_date
|
||
rating_record.status = "进行"
|
||
rating_record.cid = cid
|
||
rating_record.company_name = business_info["企业名称"]
|
||
rating_record.province = business_info["所在省份"]
|
||
rating_record.city = business_info["所在城市"]
|
||
|
||
DB_GUA.insert_single_data(
|
||
"评级数据",
|
||
"评级记录",
|
||
rating_record.fields_toggle()
|
||
)
|
||
|
||
return rating_record.fields_toggle(fields=["rid", "cid", "company_name", "report_date"]), "开始评级"
|
||
|
||
@staticmethod
|
||
def financial_analysis(**kwargs):
|
||
"""财务分析"""
|
||
|
||
rid = kwargs['rid']
|
||
cid = kwargs['cid']
|
||
report_date = kwargs['report_date']
|
||
|
||
paid_capital = DB_GUA.find_single_column(
|
||
"企业数据",
|
||
"工商信息",
|
||
{"企业ID": cid},
|
||
"实缴资本(万元)"
|
||
)
|
||
|
||
curr_financial_report = DB_GUA.find_single_data(
|
||
"企业数据",
|
||
"财务数据",
|
||
{"企业ID": cid, "报告期": report_date},
|
||
["资产负债表", "利润表", "补充数据表"]
|
||
)
|
||
|
||
last_financial_report = DB_GUA.find_single_data(
|
||
"企业数据",
|
||
"财务数据",
|
||
{"企业ID": cid, "报告期": RatingUtils.last_report_date(report_date)},
|
||
["资产负债表", "利润表", "补充数据表"]
|
||
)
|
||
|
||
if not paid_capital or not curr_financial_report or not last_financial_report:
|
||
raise APIReturnError("请求失败; 原因: 财务数据缺失", 202)
|
||
|
||
ba_c = curr_financial_report["资产负债表"]
|
||
pr_c = curr_financial_report["利润表"]
|
||
ap_c = curr_financial_report["补充数据表"]
|
||
|
||
ba_l = last_financial_report["资产负债表"]
|
||
pr_l = last_financial_report["利润表"]
|
||
ap_l = last_financial_report["补充数据表"]
|
||
|
||
model = FinancialIndicatorsModel()
|
||
|
||
model.rid = rid
|
||
model.cid = cid
|
||
model.report_date = report_date
|
||
|
||
model.eval_guaranteed_insured_balance_growth_rate(ap_c["担保在保余额"], ap_l["担保在保余额"])
|
||
model.eval_guaranteed_revenue_growth_rate(ap_c["当期担保业务收入"], ap_c["上期担保业务收入"])
|
||
model.eval_growth_rate_of_total_assets(ba_c["资产总计"], ba_l["资产总计"])
|
||
model.eval_cash_assets_ratio(ba_c["流动资产"]["货币资金"], ba_c["非流动资产"]["可供出售金融资产"], ap_c["存出保证金"], ap_c["存入保证金"], ba_c["资产总计"])
|
||
model.eval_current_ratio(ba_c["流动资产"]["流动资产合计"], ba_c["流动负债"]["流动负债合计"])
|
||
model.eval_compensation_reserve_ratio(ap_c["当期代偿金额"], ap_c["未到期责任准备金"], ap_c["担保赔偿准备金"])
|
||
model.eval_compensation_rate(ba_c["流动资产"]["货币资金"], ba_c["非流动资产"]["可供出售金融资产"], ap_c["存出保证金"], ap_c["存入保证金"], ap_c["最大被担保企业融资担保责任余额"])
|
||
model.eval_risk_reserve_adequacy_ratio(ap_c["融资担保责任余额"], ap_c["担保赔偿准备金"], ap_c["未到期责任准备金"], ba_c["所有者权益"]["一般风险准备金"])
|
||
model.eval_single_customer_concentration(ap_c["最大被担保企业融资担保责任余额"], ap_c["融资担保责任余额"])
|
||
model.eval_current_guarantee_compensation_rate(ap_c["当期代偿金额"], ap_c["当期解除担保责任余额"])
|
||
model.eval_current_compensation_recovery_rate(ap_c["当期代偿回收金额"], ap_c["当期代偿金额"])
|
||
model.eval_financing_guarantee_magnification(ap_c["融资担保责任余额"], ba_c["所有者权益"]["所有者权益合计"])
|
||
model.eval_industry_concentration(ap_c["最大单一行业融资担保责任余额"], ap_c["融资担保责任余额"])
|
||
model.eval_return_total_assets(pr_c["净利润"], ba_l["资产总计"], ba_c["资产总计"])
|
||
model.eval_operating_margin(pr_c["营业利润"], pr_c["投资收益"], pr_c["公允价值变动收益"], pr_c["营业总收入"])
|
||
model.eval_roe(pr_c["净利润"], ba_c["所有者权益"]["所有者权益合计"], ba_l["所有者权益"]["所有者权益合计"])
|
||
model.eval_actual_asset_liability_ratio(ba_c["负债合计"], ap_c["未到期责任准备金"], ap_c["担保赔偿准备金"], ba_c["资产总计"])
|
||
model.eval_capital_adequacy_ratio(ba_c["所有者权益"]["所有者权益合计"], ap_c["风险加权资产"])
|
||
model.eval_paid_capital(paid_capital)
|
||
model.eval_guarantee_business_income(ap_c["当期担保业务收入"])
|
||
model.eval_cumulative_guarantee_compensation_rate(ap_c["近三年累计代偿金额"], ap_c["近三年累计解除担保责任金额"])
|
||
model.eval_cumulative_compensation_recovery_rate(ap_c["近三年累计代偿回收金额"], ap_c["近三年累计代偿金额"])
|
||
model.eval_risk_coverage_ratio(ap_c["担保赔偿准备金"], ap_c["近三年累计代偿金额"])
|
||
model.eval_cash_asset_compensation_rate(ba_c["流动资产"]["货币资金"], ba_c["非流动资产"]["可供出售金融资产"], ap_c["存出保证金"], ap_c["存入保证金"], ap_c["融资担保责任余额"])
|
||
model.eval_margin_ratio(ap_c["存入保证金"], ap_c["存出保证金"])
|
||
model.eval_proportion_investment_business_income(pr_c["投资收益"], pr_c["营业总收入"])
|
||
model.eval_investment_income_growth_rate(pr_l["投资收益"], pr_c["投资收益"])
|
||
model.eval_customer_concentration(ap_c["前五大被担保企业融资担保责任余额"], ap_c["融资担保责任余额"])
|
||
model.eval_proportion_income_guarantee_business(ap_c["当期担保业务收入"], pr_c["营业总收入"])
|
||
model.eval_one_proportion_class_assets(ap_c["I类资产"], ba_c["资产总计"], ba_c["流动资产"]["应收代偿款"])
|
||
model.eval_two_proportion_class_assets(ap_c["II类资产"], ba_c["资产总计"], ba_c["流动资产"]["应收代偿款"])
|
||
model.eval_three_proportion_class_assets(ap_c["III类资产"], ba_c["资产总计"], ba_c["流动资产"]["应收代偿款"])
|
||
|
||
financial_indicators = model.fields_toggle()
|
||
|
||
DB_GUA.upsert_single_data(
|
||
"评级数据",
|
||
"财务分析",
|
||
{"评级ID": rid},
|
||
financial_indicators
|
||
)
|
||
|
||
return_data = {
|
||
"代偿能力": sub_dict(
|
||
financial_indicators,
|
||
[
|
||
"代偿保障率(%)",
|
||
"代偿准备金比率(%)",
|
||
"现金类资产比率(%)",
|
||
"风险准备金充足率(%)",
|
||
"流动比率(%)",
|
||
"现金类资产代偿保障率(%)",
|
||
"保证金比率(%)"
|
||
]
|
||
),
|
||
"成长能力": sub_dict(
|
||
financial_indicators,
|
||
[
|
||
"担保在保余额增长率(%)",
|
||
"担保收入增长率(%)",
|
||
"资产总额增长率(%)"
|
||
]
|
||
),
|
||
"担保资产质量": sub_dict(
|
||
financial_indicators,
|
||
[
|
||
"客户集中度(%)",
|
||
"单一客户集中度(%)",
|
||
"当期担保代偿率(%)",
|
||
"融资担保放大倍数(倍)",
|
||
"行业集中度(%)",
|
||
"当期代偿回收率(%)",
|
||
"近三年累计担保代偿率(%)",
|
||
"近三年累计代偿回收率(%)",
|
||
"风险覆盖率(%)"
|
||
]
|
||
),
|
||
"企业规模": sub_dict(
|
||
financial_indicators,
|
||
[
|
||
"实收资本(亿元)",
|
||
"担保业务收入(万元)"
|
||
]
|
||
),
|
||
"盈利能力": sub_dict(
|
||
financial_indicators,
|
||
[
|
||
"总资产收益率(%)",
|
||
"营业利润率(%)",
|
||
"净资产收益率(%)",
|
||
"投资业务收入占比(%)",
|
||
"投资收益增长率(%)",
|
||
"担保业务收入占比(%)"
|
||
]
|
||
),
|
||
"资本结构": sub_dict(
|
||
financial_indicators,
|
||
[
|
||
"实际资产负债率(%)",
|
||
"资本充足率(%)",
|
||
"I类资产占比(%)",
|
||
"II类资产占比(%)",
|
||
"III类资产占比(%)"
|
||
]
|
||
)
|
||
}
|
||
|
||
return return_data
|
||
|
||
@staticmethod
|
||
def risk_analysis(**kwargs):
|
||
"""风险分析"""
|
||
|
||
cid = kwargs["cid"]
|
||
report_date = kwargs["report_date"]
|
||
|
||
item = DB_GUA.find_single_data(
|
||
"企业数据",
|
||
"风险信息",
|
||
{"企业ID": cid, "报告期": report_date},
|
||
["失信被执行人", "被执行人", "终本案件", "限制消费令", "行政处罚", "法律诉讼(被告)"]
|
||
)
|
||
|
||
result = list()
|
||
|
||
if item:
|
||
for key in item:
|
||
data = {
|
||
"风险因素": key,
|
||
"数量(近三年)": item[key],
|
||
"详情": "-"
|
||
}
|
||
result.append(data)
|
||
return result
|
||
|
||
@staticmethod
|
||
def score_and_rank(**kwargs):
|
||
""""""
|
||
|
||
rid = kwargs["rid"]
|
||
|
||
rating_record = DB_GUA.find_single_data(
|
||
"评级数据",
|
||
"评级记录",
|
||
{"评级ID": rid},
|
||
["企业ID", "报告期"]
|
||
)
|
||
|
||
if rating_record:
|
||
cid = rating_record["企业ID"]
|
||
report_date = rating_record["报告期"]
|
||
else:
|
||
raise APIReturnError("打分失败; 原因: 不存在此记录", 202)
|
||
|
||
indicators = DB_GUA.find_single_data(
|
||
"评级数据",
|
||
"财务分析",
|
||
{"评级ID": rid},
|
||
[
|
||
"代偿保障率(%)", "代偿准备金比率(%)", "现金类资产比率(%)", "风险准备金充足率(%)",
|
||
"流动比率(%)", "担保在保余额增长率(%)", "担保收入增长率(%)", "资产总额增长率(%)",
|
||
"单一客户集中度(%)", "当期担保代偿率(%)", "融资担保放大倍数(倍)", "行业集中度(%)",
|
||
"当期代偿回收率(%)", "实收资本(亿元)", "担保业务收入(万元)", "总资产收益率(%)",
|
||
"营业利润率(%)", "净资产收益率(%)", "实际资产负债率(%)", "资本充足率(%)"
|
||
]
|
||
)
|
||
|
||
if not indicators:
|
||
raise APIReturnError("打分失败; 原因: 不存在财务指标数据", 202)
|
||
|
||
index_score = CreditIndexScore()
|
||
|
||
index_score.score_compensation_rate(indicators["代偿保障率(%)"])
|
||
index_score.score_compensation_reserve_ratio(indicators["代偿准备金比率(%)"])
|
||
index_score.score_cash_assets_ratio(indicators["现金类资产比率(%)"])
|
||
index_score.score_risk_reserve_adequacy_ratio(indicators["风险准备金充足率(%)"])
|
||
index_score.score_current_ratio(indicators["流动比率(%)"])
|
||
index_score.score_compensation()
|
||
|
||
index_score.score_guaranteed_insured_balance_growth_rate(indicators["担保在保余额增长率(%)"])
|
||
index_score.score_guaranteed_revenue_growth_rate(indicators["担保收入增长率(%)"])
|
||
index_score.score_growth_rate_of_total_assets(indicators["资产总额增长率(%)"])
|
||
index_score.score_growth_ability()
|
||
|
||
index_score.score_single_customer_concentration(indicators["单一客户集中度(%)"])
|
||
index_score.score_current_guarantee_compensation_rate(indicators["当期担保代偿率(%)"])
|
||
index_score.score_financing_guarantee_magnification(indicators["融资担保放大倍数(倍)"])
|
||
index_score.score_industry_concentration(indicators["行业集中度(%)"])
|
||
index_score.score_current_compensation_recovery_rate(indicators["当期代偿回收率(%)"])
|
||
index_score.score_guaranteed_asset_quality()
|
||
|
||
index_score.score_paid_capital(indicators["实收资本(亿元)"])
|
||
index_score.score_guarantee_business_income(indicators["担保业务收入(万元)"])
|
||
index_score.score_enterprise_size()
|
||
|
||
index_score.score_return_total_assets(indicators["总资产收益率(%)"])
|
||
index_score.score_operating_margin(indicators["营业利润率(%)"])
|
||
index_score.score_roe(indicators["净资产收益率(%)"])
|
||
index_score.score_profitability()
|
||
|
||
index_score.score_actual_asset_liability_ratio(indicators["实际资产负债率(%)"])
|
||
index_score.score_capital_adequacy_ratio(indicators["资本充足率(%)"])
|
||
index_score.score_capital_structure()
|
||
|
||
dimension_score = sub_dict(index_score.fields_toggle(), ["代偿能力", "成长能力", "担保资产质量", "企业规模", "盈利能力", "资本结构"])
|
||
total_score = round(sum(dimension_score.values()), 2)
|
||
|
||
rank_level = ScoreUtils.eval_rank_level(total_score)
|
||
|
||
score_rank_model = ScoreAndRankModel()
|
||
score_rank_model.rid = kwargs["rid"]
|
||
score_rank_model.cid = cid
|
||
score_rank_model.report_date = report_date
|
||
score_rank_model.rank_score = total_score
|
||
score_rank_model.rank_level = rank_level
|
||
score_rank_model.credit_index_score = index_score
|
||
|
||
score_rank_data = score_rank_model.fields_toggle()
|
||
|
||
DB_GUA.upsert_single_data(
|
||
"评级数据",
|
||
"得分级别",
|
||
{"评级ID": rid},
|
||
score_rank_data
|
||
)
|
||
|
||
dimensions = {
|
||
"代偿能力": ["代偿保障率(%)", "代偿准备金比率(%)", "现金类资产比率(%)", "风险准备金充足率(%)", "流动比率(%)"],
|
||
"成长能力": ["担保在保余额增长率(%)", "担保收入增长率(%)", "资产总额增长率(%)"],
|
||
"担保资产质量": ["单一客户集中度(%)", "当期担保代偿率(%)", "融资担保放大倍数(倍)", "行业集中度(%)", "当期代偿回收率(%)"],
|
||
"企业规模": ["实收资本(亿元)", "担保业务收入(万元)"],
|
||
"盈利能力": ["总资产收益率(%)", "营业利润率(%)", "净资产收益率(%)"],
|
||
"资本结构": ["实际资产负债率(%)", "资本充足率(%)"]
|
||
}
|
||
|
||
result = {
|
||
"信用级别": score_rank_data["信用级别"],
|
||
"信用得分": score_rank_data["信用得分"],
|
||
"代偿能力": {"表格": [], "合计": dimension_score["代偿能力"]},
|
||
"成长能力": {"表格": [], "合计": dimension_score["成长能力"]},
|
||
"担保资产质量": {"表格": [], "合计": dimension_score["担保资产质量"]},
|
||
"企业规模": {"表格": [], "合计": dimension_score["企业规模"]},
|
||
"盈利能力": {"表格": [], "合计": dimension_score["盈利能力"]},
|
||
"资本结构": {"表格": [], "合计": dimension_score["资本结构"]},
|
||
}
|
||
|
||
for dimension in dimensions:
|
||
for i in dimensions[dimension]:
|
||
data = {
|
||
"指标": i,
|
||
"数值": indicators[i],
|
||
"标准分": refs[i]["weight"],
|
||
"实际得分": score_rank_data["信用指标得分"][i]
|
||
}
|
||
result[dimension]["表格"].append(data)
|
||
|
||
return result
|
||
|
||
@staticmethod
|
||
def report_data(**kwargs):
|
||
|
||
rid = kwargs["rid"]
|
||
|
||
record_item = DB_GUA.find_single_data(
|
||
"评级数据",
|
||
"评级记录",
|
||
{"评级ID": rid},
|
||
["企业ID", "企业名称", "报告期"]
|
||
)
|
||
|
||
if not record_item:
|
||
raise APIReturnError("该rid不存在", 202)
|
||
|
||
cid = record_item["企业ID"]
|
||
name = record_item["企业名称"]
|
||
year = '{}年'.format(int(record_item["报告期"][:4])+1)
|
||
industry = "货币金融服务"
|
||
title = '{}-{}-主体信用评价报告'.format(year, name)
|
||
|
||
model = ReportDataModel()
|
||
result = model.mock_report_data(
|
||
rid=rid,
|
||
cid=cid,
|
||
name=name,
|
||
year=year,
|
||
industry=industry,
|
||
title=title
|
||
)
|
||
|
||
return result
|
||
|
||
@staticmethod
|
||
def edit_report_data(**kwargs):
|
||
rid = kwargs['rid']
|
||
content = kwargs['content']
|
||
|
||
DB_GUA.update_single_data(
|
||
'评级数据',
|
||
'报告数据',
|
||
{'评级ID': rid},
|
||
{'报告内容': content, '生成日期': time.strftime('%Y-%m-%d', time.localtime())}
|
||
)
|
||
|
||
@staticmethod
|
||
def report_file(**kwargs):
|
||
|
||
rid = kwargs["rid"]
|
||
|
||
record_item = DB_GUA.find_single_data(
|
||
"评级数据",
|
||
"报告数据",
|
||
{"评级ID": rid},
|
||
["企业名称", "报告内容", "报告标题"]
|
||
)
|
||
|
||
if not record_item:
|
||
raise APIReturnError("该rid不存在", 202)
|
||
|
||
record_item['生成日期'] = time.strftime('%Y-%m-%d', time.localtime())
|
||
report_file_name = '{}.pdf'.format(record_item['报告标题'])
|
||
pdf_report = ReportGenerator(name=report_file_name, text_model=record_item)
|
||
pdf_report.gen_report()
|
||
file_id = DB_GUA.upsert_file(
|
||
'评级数据',
|
||
'报告PDF',
|
||
report_file_name
|
||
)
|
||
|
||
DB_GUA.upsert_single_data(
|
||
"评级数据",
|
||
"评级记录",
|
||
{"评级ID": rid},
|
||
{"评级报告": file_id}
|
||
)
|
||
|
||
report_path = get_gen_report_path(name=report_file_name)
|
||
os.remove(report_path)
|
||
# 保存PDF报告成功,返回FileID;保存PDF报告文件失败,返回False
|
||
return file_id if file_id else False
|
||
|
||
@staticmethod
|
||
def submit(**kwargs):
|
||
""""""
|
||
|
||
rid = kwargs["rid"]
|
||
|
||
item = DB_GUA.find_single_data(
|
||
"评级数据",
|
||
"得分级别",
|
||
{"评级ID": rid},
|
||
["信用得分", "信用级别"]
|
||
)
|
||
|
||
item["评级时间"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||
item["评级状态"] = "完成"
|
||
|
||
record = RatingRecord()
|
||
record.set_instance(data=item)
|
||
|
||
DB_GUA.update_single_data(
|
||
"评级数据",
|
||
"评级记录",
|
||
{"评级ID": rid},
|
||
record.fields_toggle()
|
||
)
|
||
|
||
@staticmethod
|
||
def delete(**kwargs):
|
||
""""""
|