guarantee-admin-api-v0.2/Modules/Rating/RatingImpl.py

534 lines
22 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 confirm(**kwargs):
rid = kwargs["rid"]
result = DB_GUA.find_single_data(
"评级数据",
"得分级别",
{"评级ID": rid},
["信用得分", "信用级别"]
)
record = DB_GUA.find_single_data(
"评级数据",
"评级记录",
{"评级ID": rid},
["企业名称", "评级ID", "企业ID", "评级报告"]
)
item = {
"企业名称": record["企业名称"],
"评级ID": record["评级ID"],
"企业ID": record["企业ID"],
"信用级别": result["信用级别"],
"评级报告": "/admin/file/credit_report?file_id={}".format(record["评级报告"])
}
return item
@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):
""""""