30d85698 by chenyao

将uat-tmp所有内容合并到uat-tmp-cy分支上

2 parents cbe57bd2 ea1e7a1e
......@@ -55,6 +55,7 @@ class LoginView(ObtainJSONWebToken, GenericView):
'role': user_role.role if user_role else -1
}
rh.set_token(res.data.get('token')[-10:], user.username)
rh.set_token(res.data.get('token')[-11:], user_role.role if user_role else -1)
return response.ok(data=data)
......@@ -85,9 +86,10 @@ class IWALoginView(IWABaseView, GenericView):
is_valid, data = self.validate(q_number)
if is_valid:
rh.set_token(data.get('token')[-10:], data.get('user_name'))
user_role = UserRole.objects.filter(auth_user_id=data.get('user_id')).first()
data['role'] = user_role.role if user_role else -1
rh.set_token(data.get('token')[-10:], data.get('user_name'))
rh.set_token(data.get('token')[-11:], user_role.role if user_role else -1)
return response.ok(data=data)
else:
self.no_permission(data)
......
......@@ -98,6 +98,8 @@ RES_SHEET_HEADER = ('页码', '图片序号', '检测图片序号', '结果')
RES_SUCCESS = '识别成功'
RES_SUCCESS_OTHER = '识别成功(其他类)'
RES_SUCCESS_EMPTY = '识别成功(空数据)'
RES_SUCCESS_FINANCIAL_STATEMENT = '识别成功(财务报表类)'
RES_SUCCESS_DOWN_PAYMENT = '识别成功(首付款支付承诺书类)'
RES_FAILED = '识别失败'
RES_FAILED_1 = '识别失败(阶段1)'
RES_FAILED_2 = '识别失败(阶段2)'
......@@ -1247,6 +1249,9 @@ FSM_CONTRACT_WEP_FIELD = 'fsm_wep_ocr'
FSM_CONTRACT_MSI_FIELD = 'fsm_msi_ocr'
FSM_CONTRACT_SC_FIELD = 'fsm_sc_ocr'
FSM_CONTRACT_SC2_FIELD = 'fsm_sc2_ocr'
FS_FIELD = 'fs_ocr'
FSS_FIELD = 'fss_ocr'
DP_FIELD = 'dp_ocr'
BS_CLASSIFY = 10089
......@@ -1303,6 +1308,9 @@ COMPARE_FIELDS = (
HIL_CONTRACT_1_FIELD,
HIL_CONTRACT_2_FIELD,
HIL_CONTRACT_3_FIELD,
FS_FIELD,
FSS_FIELD,
DP_FIELD,
)
PRE_COMPARE_FIELDS = (
......@@ -1498,12 +1506,15 @@ SE_DYSYR_VALUE = '无'
SE_LAYOUT_VALUE = '旧版-旧打印、新版-新打印'
SE_GB_NEW_FIELD = ['vinNo']
SE_GB_USED_FIELD = ['customerName', 'idNum', 'date']
SE_BS_FIELD = ['户名', '打印日期', '流水日期', '(担保人1)户名', '(担保人1)打印日期', '(担保人1)流水日期', '(担保人2)户名', '(担保人2)打印日期', '(担保人2)流水日期']
SE_BS_FIELD = ['户名', '打印日期', '流水日期', '(担保人1)户名', '(担保人1)打印日期', '(担保人1)流水日期', '(担保人2)户名', '(担保人2)打印日期', '(担保人2)流水日期', '类型']
SE_HMH_FIELD = ['借款人/承租人姓名', '借款人/承租人证件号', '申请号', '渠道', '签字']
SE_BD_FIELD = ['被保险人姓名', '被保险人证件号码', '车架号', '机动车损失保险金额', '第三者责任保险金额', '绝对免赔率', '保险起始日期', '保险截止日期', '保单章', '第一受益人', '保险费合计']
JDMPV_VALUE = ['-', '--', '0%', '0.00', '/', '0', '']
JYPZ_TYPE_1 = ['二手车交易凭证']
JYPZ_TYPE_2 = ['BMW官方认证二手车交易凭证', '二手车交易凭证']
SE_FS_FIELD = ['Hash值', '公章', '财年', '资产负债表内容', '利润表内容']
SE_FSS_FIELD = ['公司名称', '公章']
SE_DP_FIELD = ['渠道', '姓名', '证件号码', '合同编号(含版本号)', '承诺人签字-电子', '承诺人签字日期-电子']
SE_BANK_FIELD = ['accountNo', 'bankName']
SE_DDA_FIELD = ['applicationId(1)', 'applicationId(2)', 'bankName', 'companyName', 'customerName', 'idNum', 'accountHolderName', 'accountNo']
......@@ -1606,7 +1617,7 @@ SE_HIL_CON_1_MAP = {
'承租人姓名': (1, 1, 7, '承租人-姓名', None),
'承租人证件号': (1, 1, 7, '承租人-证件号码', None),
'承租人签字': (6, 6, 7, '签字页-承租人姓名', None),
'承租人签字': (6, 6, 7, '签字页-承租人签章', None),
'共同承租人姓名': (1, 1, 7, '保证人1-姓名', None),
'共同承租人证件号': (1, 1, 7, '保证人1-证件号码', None),
......@@ -1634,7 +1645,7 @@ SE_HIL_CON_2_MAP = {
'融资租赁期限': (1, None, 3, '融资租赁期限', None),
'抵押人': (1, None, 3, '抵押人姓名/名称', None),
'抵押人证件号码': (1, None, 3, '抵押人证件号码', None),
'抵押人签字': (2, None, 3, '签字页-抵押人姓名', None),
'抵押人签字': (2, None, 3, '签字页-抵押人签章', None),
'抵押人配偶': (1, None, 3, '抵押人配偶姓名/名称', None),
'抵押人配偶证件号码': (1, None, 3, '抵押人配偶证件号码', None),
'抵押人配偶签字': (2, None, 3, '签字页-抵押人配偶姓名', None),
......@@ -1817,8 +1828,12 @@ BS_EN = 'Bank Statement'
HIL_CONTRACT_1_EN = '售后回租合同'
HIL_CONTRACT_2_EN = '车辆租赁抵押合同'
HIL_CONTRACT_3_EN = '车辆处置协议'
FS_EN = 'Financial Statement'
FSS_EN = 'Financial Statement Supplementary'
DP_EN = 'Down Payment'
DDA_NO_FIND = '需人工查看DDA或截图'
FS_NO_FIND = '未提供财报或财报不完整'
SKIP_CARD = {SME_BL_EN}
......@@ -1990,8 +2005,8 @@ BD_COMPARE_LOGIC = {
'机动车损失保险金额': ('机动车损失保险金额', 'se_amount_lte_compare', {}, '保单车损险异常'),
'第三者责任保险金额': ('机动车第三者责任保险金额', 'se_amount_lte_compare', {}, '保单三者险异常'),
'绝对免赔率': ('机动车损失保险绝对免赔率/绝对免赔额', 'se_one_compare', {}, '保单无绝对免赔项'),
'保险起始日期': ('保险起始日期', 'se_bd_date_compare', {'start': True}, '保单起始时间有误'),
'保险截止日期': ('保险截止日期', 'se_bd_date_compare', {}, '保单截止时间有误'),
'保险起始日期': ('保险起始日期', 'se_bd_date_2_compare', {'start': True}, '保单保险期间错误'),
'保险截止日期': ('保险截止日期', 'se_bd_date_2_compare', {}, '保单保险期间错误'),
'保单章': ('保单章', 'se_common_compare', {}, '保单无保单章'),
'第一受益人': ('特别约定第一受益人', 'se_common_compare', {}, '保单第一受益人需人工核查'),
'保险费合计': ('保险费合计', 'se_amount_lte_compare', {}, '保单保费疑似无法覆盖ASP保险融资'),
......@@ -2001,12 +2016,13 @@ BS_COMPARE_LOGIC = {
'户名': ('role', 'se_bs_one_compare', {}, '主共借人未提供银行流水'),
'(担保人1)户名': ('role', 'se_bs_name_compare', {}, '担保人1未提供银行流水'),
'(担保人2)户名': ('role', 'se_bs_name_compare', {}, '担保人2未提供银行流水'),
'打印日期': ('print_time', 'se_bs_print_date_compare', {'days': 15}, '主共借人银行流水打印日期超过15天'),
'(担保人1)打印日期': ('print_time', 'se_bs_print_date_compare', {'days': 15}, '担保人1银行流水打印日期超过15天'),
'(担保人2)打印日期': ('print_time', 'se_bs_print_date_compare', {'days': 15}, '担保人2银行流水打印日期超过15天'),
'流水日期': ('timedelta', 'se_bs_date_compare', {}, '主共借人银行流水日期不满足3个月'),
'(担保人1)流水日期': ('timedelta', 'se_bs_date_compare', {}, '担保人1银行流水日期不满足3个月'),
'(担保人2)流水日期': ('timedelta', 'se_bs_date_compare', {}, '担保人2银行流水日期不满足3个月'),
'打印日期': ('print_time', 'se_bs_print_date_compare', {'days': 30}, '主共借人银行流水打印日期超过30天'),
'(担保人1)打印日期': ('print_time', 'se_bs_print_date_compare', {'days': 30}, '担保人1银行流水打印日期超过30天'),
'(担保人2)打印日期': ('print_time', 'se_bs_print_date_compare', {'days': 30}, '担保人2银行流水打印日期超过30天'),
'流水日期': ('timedelta', 'se_bs_date_compare', {}, '主共借人银行流水区间异常,请核查'),
'(担保人1)流水日期': ('timedelta', 'se_bs_date_compare', {}, '担保人1银行流水区间异常,请核查'),
'(担保人2)流水日期': ('timedelta', 'se_bs_date_compare', {}, '担保人2银行流水区间异常,请核查'),
'类型': ('bankStatement_type', 'se_bs_type_compare', {}, '高风险经销商流水类型异常'),
}
BS_COMPARE_LOGIC_AUTO = {
......@@ -2016,9 +2032,10 @@ BS_COMPARE_LOGIC_AUTO = {
'打印日期': ('print_time', 'se_bs_print_date_compare', {'days': 30}, '主共借人银行流水打印日期超过30天'),
'(担保人1)打印日期': ('print_time', 'se_bs_print_date_compare', {'days': 30}, '担保人1银行流水打印日期超过30天'),
'(担保人2)打印日期': ('print_time', 'se_bs_print_date_compare', {'days': 30}, '担保人2银行流水打印日期超过30天'),
'流水日期': ('timedelta', 'se_bs_date_compare', {}, '主共借人银行流水日期不满足2个月'),
'(担保人1)流水日期': ('timedelta', 'se_bs_date_compare', {}, '担保人1银行流水日期不满足2个月'),
'(担保人2)流水日期': ('timedelta', 'se_bs_date_compare', {}, '担保人2银行流水日期不满足2个月'),
'流水日期': ('timedelta', 'se_bs_date_compare', {}, '主共借人银行流水区间异常,请核查'),
'(担保人1)流水日期': ('timedelta', 'se_bs_date_compare', {}, '担保人1银行流水区间异常,请核查'),
'(担保人2)流水日期': ('timedelta', 'se_bs_date_compare', {}, '担保人2银行流水区间异常,请核查'),
'类型': ('bankStatement_type', 'se_bs_type_compare', {}, '高风险经销商流水类型异常'),
}
SPECIAL_REASON = '主共借人未提供银行流水,含担保人需人工查看直系亲属关系'
......@@ -2053,7 +2070,7 @@ HIL_CONTRACT_1_COMPARE_LOGIC = {
'承租人姓名': ('承租人姓名', 'se_name_compare', {}, '售后回租合同承租人姓名与系统不一致'),
'承租人证件号': ('承租人证件号', 'se_common_compare', {}, '售后回租合同承租人证件号与系统不一致'),
'承租人签字': ('承租人签字', 'se_contain_compare', {}, '售后回租合同承租人签字与系统不一致'),
'承租人签字': ('承租人签字', 'se_common_compare', {}, '售后回租合同承租人签字与系统不一致'),
'共同承租人姓名': ('共同承租人姓名', 'se_name_compare', {}, '售后回租合同共同承租人姓名与系统不一致'),
'共同承租人&抵押人姓名': ('共同承租人&抵押人姓名', 'se_name_compare', {}, '售后回租合同共同承租人&抵押人姓名与系统不一致'),
......@@ -2083,7 +2100,7 @@ HIL_CONTRACT_2_COMPARE_LOGIC = {
'融资租赁期限': ('融资租赁期限', 'se_common_compare', {}, '车辆租赁抵押合同融资租赁期限与系统不一致'),
'抵押人': ('抵押人', 'se_name_compare', {}, '车辆租赁抵押合同抵押人姓名与系统不一致'),
'抵押人证件号码': ('抵押人证件号码', 'se_common_compare', {}, '车辆租赁抵押合同抵押人证件号码与系统不一致'),
'抵押人签字': ('抵押人签字', 'se_contain_compare', {}, '车辆租赁抵押合同抵押人签字与系统承租人姓名不一致'),
'抵押人签字': ('抵押人签字', 'se_common_compare', {}, '车辆租赁抵押合同抵押人签字与系统承租人姓名不一致'),
'抵押人配偶': ('抵押人配偶', 'se_name_compare', {}, '车辆租赁抵押合同抵押人配偶姓名与系统不一致'),
'抵押人配偶证件号码': ('抵押人配偶证件号码', 'se_common_compare', {}, '车辆租赁抵押合同抵押人配偶证件号码与系统不一致'),
'抵押人配偶签字': ('抵押人配偶签字', 'se_contain_compare', {}, '车辆租赁抵押合同抵押人签字与系统承租人配偶姓名不一致'),
......@@ -2098,7 +2115,7 @@ HIL_CONTRACT_3_COMPARE_LOGIC = {
'合同编号-正文': ('合同编号-正文', 'se_common_compare', {}, '车辆处置协议正文合同编号与系统不一致'),
'姓名/名称': ('姓名/名称', 'se_name_compare', {}, '车辆处置协议签字页客户姓名与系统不一致'),
'自然人身份证件号码/法人执照号码': ('自然人身份证件号码/法人执照号码', 'se_common_compare', {}, '车辆处置协议签字页客户证件号码与系统不一致'),
'承租人签字': ('承租人签字', 'se_contain_compare', {}, '车辆处置协议承租人签字与系统承租人姓名不一致'),
'承租人签字': ('承租人签字', 'se_common_compare', {}, '车辆处置协议承租人签字与系统承租人姓名不一致'),
}
HT_QRS_COMPARE_LOGIC = {
......@@ -2159,6 +2176,29 @@ HT_COMPARE_LOGIC = {
'无ASP产品': ('无ASP产品', 'se_self_compare_other_asp', {}, GZS_REASON_1),
}
# 格式:'xueao给的excel字段名':('数据库字段名','比对逻辑','特殊处理可以忽略','比对不合格时的返回内容')
FS_COMPARE_LOGIC = {
'Hash值': ('code', 'hash_code_compare', {}, '财报Hash值与系统不一致'),
'公章': ('stamp', 'stamp_dict_compare', {}, '财报无公章'),
'财年': ('财年', 'fiscal_year_compare', {}, '财报所属财年错误'),
'资产负债表内容': ('资产负债表内容', 'input_list_not_zero_compare', {}, '财报资产负债表为空'),
'利润表内容': ('利润表内容', 'input_list_not_zero_compare', {}, '财报利润表为空'),
}
FSS_COMPARE_LOGIC = {
'公司名称': ('title', 'se_company_compare', {}, '财报情况说明公司名称错误'),
'公章': ('stamp', 'stamp_str_compare', {}, '财报情况说明无公章'),
}
DP_COMPARE_LOGIC = {
'渠道': ('financial_org_name', 'se_common_compare', {'remove_space': True}, '首付款支付承诺书渠道错误'),
'姓名': ('main_borrower_name', 'se_common_compare', {'remove_all_space': True}, '首付款支付承诺书姓名与系统不一致'),
'证件号码': ('main_borrower_id_no', 'se_common_compare', {'remove_space': True}, '首付款支付承诺书证件号码与系统不一致'),
'合同编号(含版本号)': ('apply_no', 'se_common_compare', {'remove_space': True}, '首付款支付承诺书合同编号与系统不一致'),
'承诺人签字-电子': ('promisor_signature', 'se_common_compare', {'remove_all_space': True}, '首付款支付承诺书承诺人签字与系统不一致'),
'承诺人签字日期-电子': ('promisor_signature_date', 'se_have_compare', {}, 'N-首付款支付承诺书缺少签字日期'),
}
AFC_HT_DATE_FIELDS = ['主借人日期', '共借人日期', '保证人日期1', '保证人日期2']
# MVC_OCR_FIELD = 'mvc_ocr'
......@@ -2187,6 +2227,9 @@ SE_COMPARE_FIELD = {
HIL_CONTRACT_1_EN: (HIL_CONTRACT_1_FIELD, HIL_CONTRACT_1_COMPARE_LOGIC, False),
HIL_CONTRACT_2_EN: (HIL_CONTRACT_2_FIELD, HIL_CONTRACT_2_COMPARE_LOGIC, False),
HIL_CONTRACT_3_EN: (HIL_CONTRACT_3_FIELD, HIL_CONTRACT_3_COMPARE_LOGIC, False),
FS_EN: (FS_FIELD, FS_COMPARE_LOGIC, False),
FSS_EN: (FSS_FIELD, FSS_COMPARE_LOGIC, False),
DP_EN: (DP_FIELD, DP_COMPARE_LOGIC, False),
}
SE_COMPARE_FIELD_AUTO = {
......@@ -2534,6 +2577,23 @@ FSM_ACTIVITED_STATUS = {
"APARD": "Activated-Review done",
}
# 财务报表分类标签
FINANCIAL_STATEMENT_CLASSIFY_LIST = [97, 98, 99]
# 财务报表sheet名称
FINANCIAL_SHEET_NAME = "财务报表"
# 财报情况说明分类标签
FINANCIAL_EXPLANATION_CLASSIFY_LIST = [100]
# 财报情况说明sheet名称
FINANCIAL_EXPLANATION_SHEET_NAME = "财报情况说明"
# 首付款支付承诺书分类标签
DOWN_PAYMENT_CLASSIFY_LIST = [96]
# 首付款支付承诺书sheet名称
DOWN_PAYMENT_SHEET_NAME = "首付款支付承诺书"
NEW_FILE_COMPARE_SET = [96]
# Jira-4562 - 银行流水首页提取关键词
INCOME_KEYWORDS_LIST = ["养老金", "社保", "代发工资", "工资入账", "奖金", "养老保险", "代发", "工资"]
INCOME_KEYWORDS_DICT = {
......
......@@ -4,5 +4,10 @@ from . import views
urlpatterns = [
path(r'', views.DocView.as_view()),
path(r'query/employee', views.EmployeeView.as_view()),
path(r'query/greenBookHistoryFile', views.SearchGBHistoryFileView.as_view()),
path(r'download/greenBookHistoryFile', views.DownloadGBHistoryFileView.as_view()),
path(r'invoice/downloadExcel', views.InvoiceExcelView.as_view()),
path(r'invoice/queryInfo', views.InvoiceQueryInfoView.as_view()),
path(r'contract/v1', views.SEContractView.as_view()),
]
......
......@@ -162,7 +162,7 @@ class Command(BaseCommand, LoggerMixin):
@staticmethod
def get_path(name, img_output_dir, wb_output_dir, pdf_output_dir):
time_stamp = datetime.now().strftime('%Y-%m-%d_%H:%M:%S')
time_stamp = datetime.now().strftime('%Y-%m-%d_%H_%M_%S')
new_name = '{0}_{1}'.format(time_stamp, name)
img_save_path = os.path.join(img_output_dir, new_name)
pdf_save_path = os.path.join(pdf_output_dir, new_name)
......
......@@ -320,7 +320,7 @@ class Command(BaseCommand, LoggerMixin):
true_file_set.add(os_error_filename_set.pop())
for name in true_file_set:
time.sleep(10)
unique_folder_name = '{0}_{1}'.format(datetime.now().strftime('%Y-%m-%d_%H:%M:%S'), name)
unique_folder_name = '{0}_{1}'.format(datetime.now().strftime('%Y-%m-%d_%H_%M_%S'), name)
path = os.path.join(input_dir, name)
try:
......
......@@ -272,7 +272,7 @@ class Command(BaseCommand, LoggerMixin):
@staticmethod
def get_path(name, img_output_dir, wb_output_dir, pdf_output_dir, seperate_dir_map):
time_stamp = datetime.now().strftime('%Y-%m-%d_%H:%M:%S')
time_stamp = datetime.now().strftime('%Y-%m-%d_%H_%M_%S')
new_name = '{0}_{1}'.format(time_stamp, name)
img_save_path = os.path.join(img_output_dir, new_name)
pdf_save_path = os.path.join(pdf_output_dir, new_name)
......
......@@ -186,7 +186,7 @@ class Command(BaseCommand, LoggerMixin):
@staticmethod
def get_path(name, img_output_dir, wb_output_dir, pdf_output_dir):
time_stamp = datetime.now().strftime('%Y-%m-%d_%H:%M:%S')
time_stamp = datetime.now().strftime('%Y-%m-%d_%H_%M_%S')
new_name = '{0}_{1}'.format(time_stamp, name)
img_save_path = os.path.join(img_output_dir, new_name)
pdf_save_path = os.path.join(pdf_output_dir, new_name)
......
......@@ -409,7 +409,7 @@ class Command(BaseCommand, LoggerMixin):
@staticmethod
def get_path(name, img_output_dir, wb_output_dir, pdf_output_dir):
time_stamp = datetime.now().strftime('%Y-%m-%d_%H:%M:%S')
time_stamp = datetime.now().strftime('%Y-%m-%d_%H_%M_%S')
new_name = '{0}_{1}'.format(time_stamp, name)
img_save_path = os.path.join(img_output_dir, new_name)
pdf_save_path = os.path.join(pdf_output_dir, new_name)
......
......@@ -965,13 +965,21 @@ class Command(BaseCommand, LoggerMixin):
print_date = bs_info.get('end_date', '').strftime("%Y-%m-%d")
except Exception as e:
print_date = ''
is_eBank = bs_info.get('e_bank', False)
if is_eBank:
bs_verify = bs_info.get('verify_res_ebank', True)
else:
bs_verify = bs_info.get('verify_res_paper_bank', True)
res.append(
{
'bankStatement_type': str(bs_info.get('classify', '')),
'role': bs_info.get('role', ''),
'print_time': print_date,
'timedelta': bs_info.get('timedelta', ''),
'verify': bs_info.get('verify_res_ebank', True),
'e_bank': bs_info.get('e_bank', False),
# 'verify': bs_info.get('verify_res_ebank', True),
'verify': bs_verify,
# 'e_bank': bs_info.get('e_bank', False),
'e_bank': is_eBank,
'income_keywords': income_keywords_str
}
)
......@@ -1037,6 +1045,13 @@ class Command(BaseCommand, LoggerMixin):
tmp_res = page_info_dict.get(str(pno2), {}).get(key1, '')
img_pno = pno1
res[key] = tmp_res
# 添加处理,
# [售后回租合同] - 如果 key 是 "承租人签字", 且内容中包含 签署日期:XXXX, 则将签署日期去除
# [车辆租赁抵押合同] - 如果 key 是 ""
if key == '承租人签字' and tmp_res is not None and '签署日期' in tmp_res:
res[key] = tmp_res.split('签署日期')[0]
if key == "抵押人签字" and tmp_res is not None and "签署日期" in tmp_res:
res[key] = tmp_res.split("签署日期")[0]
res.setdefault(consts.IMG_PATH_KEY, dict())[key] = page_info_dict.get(str(img_pno), {}).get(
consts.IMG_PATH_KEY, '')
else:
......@@ -1639,7 +1654,7 @@ class Command(BaseCommand, LoggerMixin):
try:
channel, img_path, text_list = img_queue.get(block=False)
except Exception as e:
# self.online_log.info('{0} [img_2_ocr_1] [queue empty]'.format(self.log_base))
# # self.online_log.info('{0} [img_2_ocr_1] [queue empty]'.format(self.log_base))
time.sleep(self.sleep_time_img_get)
continue
else:
......@@ -1668,6 +1683,7 @@ class Command(BaseCommand, LoggerMixin):
'[error={4}]'.format(self.log_base, times, url, img_path,
traceback.format_exc()))
else:
self.online_log.info('{0} [ocr_1 start] [img={1}] [url={2}]'.format(self.log_base, img_path, url))
ocr_1_res = ocr_1_response.json()
end_time = time.time()
speed_time = int(end_time - start_time)
......@@ -1684,32 +1700,41 @@ class Command(BaseCommand, LoggerMixin):
self.log_base, img_path, traceback.format_exc()))
else:
try:
self.online_log.info('{0} [del json_data_1] [img={1}] '.format(self.log_base, img_path))
del json_data_1
# /data/bmw-ocr-data/AFC/tmp/6/img/page_0_img_0.jpeg
# AFC_2
path_split = img_path.split('/')
task_str = consts.SPLIT_STR.join((path_split[-5], path_split[-3]))
self.online_log.info('{0} [before lock] [img={1}] '.format(self.log_base, img_path))
with lock:
self.online_log.info('{0} [get lock] [img={1}] '.format(self.log_base, img_path))
doc_res_dict = res_dict.setdefault(task_str, {})
doc_res_dict[img_path] = ocr_1_res
res_dict[task_str] = doc_res_dict
todo_count = todo_count_dict.get(task_str)
if todo_count == 1:
finish_queue.put(task_str)
self.online_log.info('{0} [ocr_1 to finish_queue] [img={1}] '.format(self.log_base, img_path))
del todo_count_dict[task_str]
self.online_log.info('{0} [del todo_count_dict] [img={1}] '.format(self.log_base, img_path))
else:
todo_count_dict[task_str] = todo_count - 1
self.online_log.info('{0} [after lock] [img={1}] '.format(self.log_base, img_path))
except Exception as e:
self.online_log.error('{0} [process error (store ocr res)] [img_path={1}] [error={2}]'.format(
self.log_base, img_path, traceback.format_exc()))
def res_2_wb(self, res_dict, img_queue, finish_queue, error_list):
self.online_log.info('{0} [res_2_wb] [get task] [queue running] [finish_queue_size={1}]'.format(self.log_base, finish_queue.qsize()))
while len(error_list) == 0 or not img_queue.empty() or not finish_queue.empty():
try:
self.online_log.info('{0} [res_2_wb] [finish_queue.get1] [finish_queue_size={1}] [img_queue_size={2}]'.format(self.log_base, finish_queue.qsize(), img_queue.qsize()))
task_str = finish_queue.get(block=False)
self.online_log.info('{0} [res_2_wb] [finish_queue.get2]'.format(self.log_base))
except Exception as e:
# self.online_log.info('{0} [res_2_wb] [queue empty]'.format(self.log_base))
self.online_log.info('{0} [res_2_wb] [queue empty]'.format(self.log_base))
time.sleep(self.sleep_time_task_get)
continue
else:
......@@ -1747,6 +1772,12 @@ class Command(BaseCommand, LoggerMixin):
contract_result = {}
contract_result_compare = {}
income_keywords_dictionary = {"income_keywords": []}
# 添加财报三个报表的处理
financial_statement_dict = {}
# 添加财报情况说明的处理
financial_explanation_dict = {}
# 添加首付款支付承诺书的处理
down_payment_dict = {}
res_list = []
interest_keyword = Keywords.objects.filter(
type=KeywordsType.INTEREST.value, on_off=True).values_list('keyword', flat=True)
......@@ -1771,11 +1802,75 @@ class Command(BaseCommand, LoggerMixin):
for part_idx, ocr_data in enumerate(ocr_data_list):
part_idx = part_idx + 1
classify = ocr_data.get('classify')
self.online_log.info('{0} [task={1}] [classify={2}]'.format(self.log_base, task_str, classify))
if classify is None:
res_list.append((pno, ino, part_idx, consts.RES_FAILED_3))
self.online_log.warn('{0} [ocr_1 res error] [img={1}]'.format(
self.log_base, img_path))
continue
elif classify in consts.FINANCIAL_STATEMENT_CLASSIFY_LIST:
# 添加到 res_list 中
res_list.append((pno, ino, part_idx, consts.RES_SUCCESS_FINANCIAL_STATEMENT))
# 只要分类为财报三个报表的,就在 financial_statement_dict 中添加对应的 code 和 stamp 两个dict
if "code" not in financial_statement_dict:
financial_statement_dict["code"] = {}
if "stamp" not in financial_statement_dict:
financial_statement_dict["stamp"] = {}
financial_statement_table_name = None
if classify == 97:
financial_statement_table_name = "balance_sheet"
elif classify == 98:
financial_statement_table_name = "income_statement"
elif classify == 99:
financial_statement_table_name = "cash_flow_statement"
if financial_statement_table_name is not None:
if "id_code" in ocr_data:
id_code = ocr_data.get("id_code", "")
financial_statement_dict["code"][financial_statement_table_name] = id_code
if "stamp" in ocr_data:
stamp = ocr_data.get("stamp", "")
financial_statement_dict["stamp"][financial_statement_table_name] = stamp
elif classify in consts.FINANCIAL_EXPLANATION_CLASSIFY_LIST:
# 添加到 res_list 中
res_list.append((pno, ino, part_idx, consts.RES_SUCCESS_FINANCIAL_STATEMENT))
# 只要分类为财报情况说明的,就在 financial_explanation_dict 中添加对应的 title 和 stamp 两个dict
if "title" not in financial_explanation_dict:
financial_explanation_dict["title"] = {}
if "stamp" not in financial_explanation_dict:
financial_explanation_dict["stamp"] = {}
if "title" in ocr_data:
title = ocr_data.get("title", "")
financial_explanation_dict["title"] = title
if "stamp" in ocr_data:
stamp = ocr_data.get("stamp", "")
financial_explanation_dict["stamp"] = stamp
elif classify in consts.DOWN_PAYMENT_CLASSIFY_LIST:
# 添加到 res_list 中
res_list.append((pno, ino, part_idx, consts.RES_SUCCESS_DOWN_PAYMENT))
# 1-金融机构名称
financial_org_name = ocr_data.get("financial_org_name", "")
down_payment_dict["financial_org_name"] = financial_org_name
# 2-主借人姓名
main_borrower_name = ocr_data.get("main_borrower_name", "")
down_payment_dict["main_borrower_name"] = main_borrower_name
# 3-主借人证件号码
main_borrower_id_no = ocr_data.get("main_borrower_id_no", "")
down_payment_dict["main_borrower_id_no"] = main_borrower_id_no
# 4-申请编号
apply_no = ocr_data.get("apply_no", "")
down_payment_dict["apply_no"] = apply_no
# 5-抵押/租赁合同名称
contract_name = ocr_data.get("contract_name", "")
down_payment_dict["contract_name"] = contract_name
# 6-承诺人签字
promisor_signature = ocr_data.get("promisor_signature", "")
down_payment_dict["promisor_signature"] = promisor_signature
# 7-承诺人签字日期
promisor_signature_date = ocr_data.get("promisor_signature_date", "")
down_payment_dict["promisor_signature_date"] = promisor_signature_date
elif classify in consts.OTHER_CLASSIFY_SET: # 其他类
res_list.append((pno, ino, part_idx, consts.RES_SUCCESS_OTHER))
continue
......@@ -1962,7 +2057,7 @@ class Command(BaseCommand, LoggerMixin):
# src_excel_path = os.path.join(doc_data_path, 'src.xlsx')
# wb.save(src_excel_path)
#need_follow表示在上传edms时文件名是否要添加"关注"两字
count_list, need_follow = wb.rebuild(merged_bs_summary, license_summary, res_list, doc.document_scheme, contract_result, doc.metadata)
count_list, need_follow = wb.rebuild(merged_bs_summary, license_summary, res_list, doc.document_scheme, contract_result, doc.metadata, financial_statement_dict, financial_explanation_dict, down_payment_dict)
wb.save(excel_path)
except Exception as e:
......@@ -2063,16 +2158,28 @@ class Command(BaseCommand, LoggerMixin):
license_summary[consts.BS_CLASSIFY] = bs_rebuild
# 比对
if len(license_summary) > 0 and doc.document_scheme != consts.DOC_SCHEME_LIST[2]:
if len(license_summary) > 0 or classify in consts.NEW_FILE_COMPARE_SET:
if doc.document_scheme != consts.DOC_SCHEME_LIST[2]:
# if len(license_summary) > 0 and doc.document_scheme != consts.DOC_SCHEME_LIST[2]:
try:
is_ca = True if doc.document_scheme == consts.DOC_SCHEME_LIST[0] else False
# 更新OCR累计识别结果表
if business_type == consts.HIL_PREFIX:
result_class = HILOCRResult if is_ca else HILSEOCRResult
res_obj = atomicSaveDBHIL(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str)
try:
res_obj = atomicSaveDBHIL(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict)
except Exception as e:
# 遇到报错重试一次,希望解决两个文件首次入库都插入的问题
self.online_log.error('{0} [process error (ocr result save) retry] [task={1}] [error={2}]'.format(self.log_base, task_str, traceback.format_exc()))
res_obj = atomicSaveDBHIL(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict)
else:
result_class = AFCOCRResult if is_ca else AFCSEOCRResult
res_obj = atomicSaveDBAFC(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str)
try:
res_obj = atomicSaveDBAFC(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict)
except Exception as e:
# 遇到报错重试一次,希望解决两个文件首次入库都插入的问题
self.online_log.error('{0} [process error (ocr result save) retry] [task={1}] [error={2}]'.format(self.log_base, task_str, traceback.format_exc()))
res_obj = atomicSaveDBAFC(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict)
except Exception as e:
self.online_log.error(
......@@ -2103,6 +2210,32 @@ class Command(BaseCommand, LoggerMixin):
else:
self.online_log.info('{0} [comparison info send success] [task={1}] '
'[res_id={2}]'.format(self.log_base, task_str, res_obj.id))
else:
# license_summary 为空
self.online_log.info('{0} [task={1}] [no license_summary]'.format(self.log_base, task_str))
try:
is_ca = True if doc.document_scheme == consts.DOC_SCHEME_LIST[0] else False
# 更新OCR累计识别结果表
if business_type == consts.HIL_PREFIX:
result_class = HILOCRResult if is_ca else HILSEOCRResult
try:
res_obj = atomicSaveDBHIL(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict)
except Exception as e:
# 遇到报错重试一次,希望解决两个文件首次入库都插入的问题
self.online_log.error('{0} [process error (ocr result save) retry] [task={1}] [error={2}]'.format(self.log_base, task_str, traceback.format_exc()))
res_obj = atomicSaveDBHIL(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict)
else:
result_class = AFCOCRResult if is_ca else AFCSEOCRResult
try:
res_obj = atomicSaveDBAFC(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict)
except Exception as e:
# 遇到报错重试一次,希望解决两个文件首次入库都插入的问题
self.online_log.error('{0} [process error (ocr result save) retry] [task={1}] [error={2}]'.format(self.log_base, task_str, traceback.format_exc()))
res_obj = atomicSaveDBAFC(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict)
except Exception as e:
self.online_log.error(
'{0} [process error (ocr result save)] [task={1}] [error={2}]'.format(
self.log_base, task_str, traceback.format_exc()))
# DDA处理
if do_dda:
......@@ -2411,6 +2544,7 @@ class Command(BaseCommand, LoggerMixin):
except Exception as e:
self.online_log.error('{0} [process error (pdf & img remove)] [task={1}] [error={2}]'.format(
self.log_base, task_str, traceback.format_exc()))
self.online_log.info('{0} [res_2_wb after while] [len(error_list)={1}] [img_queue={2}] [finish_queue={3}]'.format(self.log_base, len(error_list), img_queue.empty(), finish_queue.empty()))
def handle(self, *args, **kwargs):
db.close_old_connections()
......@@ -2449,7 +2583,7 @@ class Command(BaseCommand, LoggerMixin):
self.online_log.info('{0} [stop safely]'.format(self.log_base))
@transaction.atomic
def atomicSaveDBAFC(self,result_class,doc,license_summary,ic_merge,rp_merge,task_str):
def atomicSaveDBAFC(self,result_class,doc,license_summary,ic_merge,rp_merge,task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict):
with transaction.atomic('afc'):
res_obj = result_class.objects.using('afc').select_for_update().filter(application_id=doc.application_id).first()
self.online_log.info('{0} [sql lock AFC application_id={1} doc_id={2}]'.format(self.log_base, doc.application_id,doc.id))
......@@ -2457,6 +2591,18 @@ def atomicSaveDBAFC(self,result_class,doc,license_summary,ic_merge,rp_merge,task
res_obj = result_class()
res_obj.application_id = doc.application_id
self.online_log.info('{0} [res_obj is None application_id={1} doc_id={2}]'.format(self.log_base, doc.application_id,doc.id))
# 财务报表存入数据库
if res_obj is not None:
if financial_statement_dict:
res_obj.fs_ocr = json.dumps([financial_statement_dict])
# 财报情况说明存入数据库
if res_obj is not None:
if financial_explanation_dict:
res_obj.fss_ocr = json.dumps([financial_explanation_dict])
# 首付款支付承诺书存入数据库
if res_obj is not None:
if down_payment_dict:
res_obj.dp_ocr = json.dumps([down_payment_dict])
for classify, field in consts.RESULT_MAPPING.items():
if not hasattr(res_obj, field):
continue
......@@ -2482,7 +2628,7 @@ def atomicSaveDBAFC(self,result_class,doc,license_summary,ic_merge,rp_merge,task
return res_obj
@transaction.atomic
def atomicSaveDBHIL(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str):
def atomicSaveDBHIL(self,result_class,doc,license_summary,ic_merge,rp_merge, task_str, financial_statement_dict, financial_explanation_dict, down_payment_dict):
with transaction.atomic('default'):
res_obj = result_class.objects.using('default').select_for_update().filter(application_id=doc.application_id).first()
self.online_log.info('{0} [sql lock HIL application_id={1} doc_id={2}]'.format(self.log_base, doc.application_id,doc.id))
......@@ -2490,6 +2636,18 @@ def atomicSaveDBHIL(self,result_class,doc,license_summary,ic_merge,rp_merge, tas
res_obj = result_class()
res_obj.application_id = doc.application_id
self.online_log.info('{0} [res_obj is None application_id={1} doc_id={2}]'.format(self.log_base, doc.application_id,doc.id))
# 财务报表三个表存入数据库
if res_obj is not None:
if financial_statement_dict:
res_obj.fs_ocr = json.dumps([financial_statement_dict])
# 财报情况说明存入数据库
if res_obj is not None:
if financial_explanation_dict:
res_obj.fss_ocr = json.dumps([financial_explanation_dict])
# 首付款支付承诺书存入数据库
if res_obj is not None:
if down_payment_dict:
res_obj.dp_ocr = json.dumps([down_payment_dict])
for classify, field in consts.RESULT_MAPPING.items():
if not hasattr(res_obj, field):
continue
......
......@@ -336,6 +336,9 @@ class AFCOCRResult(models.Model):
fsm_sc_ocr = models.TextField(null=True, verbose_name="汽车销售合同")
fsm_sc2_ocr = models.TextField(null=True, verbose_name="汽车销售合同补充合同")
fsm_activited = models.IntegerField(null=False, default=0, verbose_name="fsm激活状态 1:激活")
fs_ocr = models.TextField(null=True, verbose_name="财务报表")
fss_ocr = models.TextField(null=True, verbose_name="财务情况说明书")
dp_ocr = models.TextField(null=True, verbose_name="首付款支付承诺书")
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
......@@ -379,6 +382,9 @@ class HILOCRResult(models.Model):
fsm_sc_ocr = models.TextField(null=True, verbose_name="汽车销售合同")
fsm_sc2_ocr = models.TextField(null=True, verbose_name="汽车销售合同补充合同")
fsm_activited = models.IntegerField(null=False, default=0, verbose_name="fsm激活状态 1:激活")
fs_ocr = models.TextField(null=True, verbose_name="财务报表")
fss_ocr = models.TextField(null=True, verbose_name="财务情况说明书")
dp_ocr = models.TextField(null=True, verbose_name="首付款支付承诺书")
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
......@@ -420,6 +426,9 @@ class AFCSEOCRResult(models.Model):
fsm_sc_ocr = models.TextField(null=True, verbose_name="汽车销售合同")
fsm_sc2_ocr = models.TextField(null=True, verbose_name="汽车销售合同补充合同")
fsm_activited = models.IntegerField(null=False, default=0, verbose_name="fsm激活状态 1:激活")
fs_ocr = models.TextField(null=True, verbose_name="财务报表")
fss_ocr = models.TextField(null=True, verbose_name="财务情况说明书")
dp_ocr = models.TextField(null=True, verbose_name="首付款支付承诺书")
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
......@@ -461,6 +470,9 @@ class HILSEOCRResult(models.Model):
fsm_sc_ocr = models.TextField(null=True, verbose_name="汽车销售合同")
fsm_sc2_ocr = models.TextField(null=True, verbose_name="汽车销售合同补充合同")
fsm_activited = models.IntegerField(null=False, default=0, verbose_name="fsm激活状态 1:激活")
fs_ocr = models.TextField(null=True, verbose_name="财务报表")
fss_ocr = models.TextField(null=True, verbose_name="财务情况说明书")
dp_ocr = models.TextField(null=True, verbose_name="首付款支付承诺书")
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
......@@ -1119,3 +1131,45 @@ class DealerMapping(models.Model):
class Meta:
managed = False
db_table = 'dealer_mapping'
class HILGreenBookHistoryFile(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
object_id = models.CharField(max_length=64, verbose_name="文件唯一ID")
object_name = models.CharField(max_length=255, verbose_name="文件名称")
application_no = models.CharField(max_length=64, verbose_name="申请号")
object_type = models.CharField(max_length=64, verbose_name="文件类型")
customer_name = models.CharField(max_length=64, verbose_name="customer_name")
content_size = models.CharField(max_length=64, verbose_name="文件大小")
owner_name = models.CharField(max_length=64, verbose_name="owner_name")
input_date = models.DateTimeField(verbose_name="上传时间")
modify_date = models.DateTimeField(verbose_name="修改时间")
location = models.CharField(max_length=255, verbose_name="文件位置")
download_finish = models.SmallIntegerField(null=False, default=0, verbose_name="是否下载完成")
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
managed = False
db_table = 'hil_gb_history_file'
class AFCGreenBookHistoryFile(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
object_id = models.CharField(max_length=64, verbose_name="文件唯一ID")
object_name = models.CharField(max_length=255, verbose_name="文件名称")
application_no = models.CharField(max_length=64, verbose_name="申请号")
object_type = models.CharField(max_length=64, verbose_name="文件类型")
customer_name = models.CharField(max_length=64, verbose_name="customer_name")
content_size = models.CharField(max_length=64, verbose_name="文件大小")
owner_name = models.CharField(max_length=64, verbose_name="owner_name")
input_date = models.DateTimeField(verbose_name="上传时间")
modify_date = models.DateTimeField(verbose_name="修改时间")
location = models.CharField(max_length=255, verbose_name="文件位置")
download_finish = models.BooleanField(default=True, verbose_name="是否下载完成")
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
managed = False
db_table = 'afc_gb_history_file'
situ_db_label = 'afc'
......
......@@ -102,9 +102,14 @@ class ECM(GenericView):
"docbase": self.doc_base_map.get(business_type),
"documentType": doc_type,
"objectId": object_id,
"b_input_date": time.strftime("%m/%d/%Y %X"),
"b_credit_signing_date": time.strftime("%m/%d/%Y %X"),
"b_credit_check": True,
"b_id_number": '',
}
header_info = self.get_headers()
self.running_log.info("{0} download header_info:{1}".format(self.log_base, header_info))
self.running_log.info("{0} download args_info:{1}".format(self.log_base, download_json))
response = requests.post(self.download_url, headers=header_info, json=download_json, verify=False)
if response.status_code != 200:
raise ECMException('ECM download failed with code: {0}'.format(response.status_code))
......@@ -142,6 +147,9 @@ class ECM(GenericView):
"b_region": "0",
"b_region_name": self.b_region_name_map.get(business_type),
"b_input_date": time.strftime("%m/%d/%Y %X"),
"b_credit_signing_date": time.strftime("%m/%d/%Y %X"),
"b_credit_check": True,
"b_id_number": '',
# "file_base64_content": "",
}
for key in self.upload_fields:
......@@ -153,9 +161,28 @@ class ECM(GenericView):
args['file_base64_content'] = file_data
header_info = self.get_headers()
self.running_log.info("{0} upload header_info:{1}".format(self.log_base, header_info))
self.running_log.info("{0} upload args_info:{1}".format(self.log_base, args))
response = requests.post(self.upload_url, headers=header_info, json=args, verify=False)
if response.status_code != 200:
raise ECMException('ECM upload failed with code: {0} , with headers: {1} , with content: {2}'.format(
response.status_code, response.headers, response.text))
if 'ns6:createResponse' not in response.json().get('S:Envelope', {}).get('S:Body', {}):
if 'ns12:createResponse' not in response.json().get('S:Envelope', {}).get('S:Body', {}):
raise ECMException('ECM upload failed: {0} , with headers: {1}'.format(response.json(), response.headers))
def search_doc_info_list(self, filePath, business_type):
args = {
#userName n大写,和其他接口不一样,是因为apigateway没有做统一
"userName": self.username,
"password": self.pwd,
"docbase": self.doc_base_map.get(business_type),
"documentType": "green_book",
"dql":"select r_object_id, object_name,b_application_no, r_object_type,b_customer_name,r_content_size, owner_name, b_input_date, r_modify_date, b_location from green_book where b_location = '{}'" .format(filePath),
}
header_info = self.get_headers()
self.running_log.info("{0} search header_info:{1}".format(self.log_base, header_info))
self.running_log.info("{0} search args_info:{1}".format(self.log_base, args))
response = requests.post(self.search_url, headers=header_info, json=args, verify=False)
if response.status_code != 200:
raise ECMException('ECM search failed with code: {0}'.format(response.status_code))
#self.running_log.info("{0} search response.json():{1}".format(self.log_base, response.json()))
return response.json()
\ No newline at end of file
......
......@@ -827,6 +827,80 @@ class BSWorkbook(Workbook):
ws.append(row)
ws.append((None, ))
def financial_rebuild(self, financial_statement_dict):
# 如果 financial_statement_dict 为空,则不创建表
if not financial_statement_dict:
return
# 如果 financial_statement_dict 不为空,则创建表
ws = self.create_sheet(consts.FINANCIAL_SHEET_NAME)
for fin_key, fin_value in financial_statement_dict.items():
table_str = "识别码"
if fin_key == "code":
table_str = "识别码"
elif fin_key == "stamp":
table_str = "印章"
for table_key, table_value in fin_value.items():
if table_key == "balance_sheet":
row = ["资产负债表" + table_str, str(table_value)]
ws.append(row)
elif table_key == "income_statement":
row = ["利润表" + table_str, str(table_value)]
ws.append(row)
elif table_key == "cash_flow_statement":
row = ["现金流量表" + table_str, str(table_value)]
ws.append(row)
def financial_explanation_rebuild(self, financial_explanation_dict):
"""
Desc:
重构财报情况说明sheet
"""
# 如果 financial_explanation_dict 为空,则不创建sheet
if not financial_explanation_dict:
return
# 如果 financial_explanation_dict 不为空, 则创建sheet
ws = self.create_sheet(consts.FINANCIAL_EXPLANATION_SHEET_NAME)
for fin_key, fin_value in financial_explanation_dict.items():
table_str = "公司名称"
if fin_key == "title":
table_str = "公司名称"
elif fin_key == "stamp":
table_str = "印章"
row = ["财报情况说明" + table_str, str(fin_value)]
ws.append(row)
def down_payment_rebuild(self, down_payment_dict):
"""
Desc:
重构首付款支付承诺书sheet
"""
# 如果 down_payment_dict 为空, 则不创建sheet
if not down_payment_dict:
return
# 如果 down_payment_dict 不为空, 则创建sheet
ws = self.create_sheet(consts.DOWN_PAYMENT_SHEET_NAME)
english_chinese_dict = {
"financial_org_name": "渠道",
"main_borrower_name": "姓名",
"main_borrower_id_no": "证件号码",
"apply_no": "合同编号",
"contract_name": "合同名称",
"promisor_signature": "承诺人签字-电子",
"promisor_signature_date": "承诺人签字日期-电子"
}
for dp_key, dp_value in down_payment_dict.items():
if dp_key in english_chinese_dict.keys():
row = [english_chinese_dict[dp_key], str(dp_value)]
ws.append(row)
else:
row = [english_chinese_dict[dp_key], ""]
ws.append(row)
@staticmethod
def remove_yuan(amount_key_set, key, src_str):
if key in amount_key_set and isinstance(src_str, str):
......@@ -926,7 +1000,7 @@ class BSWorkbook(Workbook):
if len(self.sheetnames) > 1:
self.remove(self.get_sheet_by_name('Sheet'))
def rebuild(self, bs_summary, license_summary, res_list, document_scheme, contract_result, metadata):
def rebuild(self, bs_summary, license_summary, res_list, document_scheme, contract_result, metadata, financial_statement_dict, financial_explanation_dict, down_payment_dict):
res_count_tuple = self.res_sheet(res_list)
count_list = [(consts.MODEL_FIELD_BS, len(bs_summary))]
......@@ -934,10 +1008,16 @@ class BSWorkbook(Workbook):
self.license_rebuild(license_summary, document_scheme, count_list)
self.contract_rebuild(contract_result)
self.bs_rebuild(bs_summary, res_count_tuple, metadata)
self.financial_rebuild(financial_statement_dict)
self.financial_explanation_rebuild(financial_explanation_dict)
self.down_payment_rebuild(down_payment_dict)
else:
self.bs_rebuild(bs_summary, res_count_tuple, metadata)
self.license_rebuild(license_summary, document_scheme, count_list)
self.contract_rebuild(contract_result, True)
self.financial_rebuild(financial_statement_dict)
self.financial_explanation_rebuild(financial_explanation_dict)
self.down_payment_rebuild(down_payment_dict)
self.move_res_sheet()
self.remove_base_sheet()
return count_list, self.need_follow
......
......@@ -20,6 +20,7 @@ from common import response
from common.mixins import GenericView,DocGenericView
from common.tools.file_tools import file_write
from common.redis_cache import redis_handler as rh
from apps.doc.ocr.cms import cms
from .models import (
# UploadDocRecords,
DocStatus,
......@@ -53,16 +54,22 @@ from .models import (
AFCOCRResult,
AFCSEOCRResult,
HILCmsStatusInfo,
AFCCmsStatusInfo
AFCCmsStatusInfo,
HILGreenBookHistoryFile,
AFCGreenBookHistoryFile,
Configs
)
from common.exceptions import (NoPermissionException)
from .named_enum import ErrorType, AutoResult, WholeResult, RPAResult, SystemName, RequestTeam
from .mixins import DocHandler, MPOSHandler, PreSEHandler
from . import consts
from apps.account.authentication import OAuth2AuthenticationWithUser
from celery_compare.tasks import compare, fsm_compare
from prese.compare import get_empty_result
from apps.doc.ocr.ecm import ECM
import time
from django.http import HttpResponse
from django.utils.encoding import escape_uri_path
class CustomDate(fields.Date):
......@@ -90,6 +97,22 @@ class CustomDecimal(fields.Decimal):
def load_data(request, schema):
return request.data
employee_args = {
'application_id': fields.Str(required=True, validate=validate.Length(max=64)),
'business_type': fields.Str(required=True, validate=validate.Length(max=64)),
}
q_gb_file_args = {
'file_path': fields.Str(required=True, validate=validate.Length(max=255)),
'business_type': fields.Str(required=True, validate=validate.Length(max=64)),
}
d_gb_file_args = {
'object_id': fields.Str(required=True, validate=validate.Length(max=64)),
'save_path': fields.Str(required=True, validate=validate.Length(max=255)),
'business_type': fields.Str(required=True, validate=validate.Length(max=64)),
}
go_args = {
'image': fields.Raw(required=True),
......@@ -561,6 +584,10 @@ mpos_args = {
'file_base64_content': fields.List(fields.Str(), required=True, validate=validate.Length(min=1)),
}
invoice_download_args = {
'application_entity': fields.Int(required=True),
'application_ids': fields.Str(required=True),
}
class UploadDocView(GenericView, DocHandler):
# permission_classes = []
......@@ -620,7 +647,7 @@ class UploadDocView(GenericView, DocHandler):
self.running_log.info('[doc upload applicationId-{0}] [ocr result saved]'.format(application_id))
if data_source == consts.DATA_SOURCE_LIST[1]:
if document_name.endswith('-证书.pdf') or document_name.endswith('-证书'):
if document_name.endswith('-证书.pdf') or document_name.endswith('-证书') or '-证书-bk-' in document_name:
self.running_log.info('[doc upload success] [eapp license skip] [args={0}]'.format(args))
return response.ok()
......@@ -1059,6 +1086,27 @@ class DocView(DocGenericView, DocHandler):
create_time_start = args.get('create_time_start')
create_time_end = args.get('create_time_end')
# 角色权限不符,返回空列表
token = request.META.get("HTTP_AUTHORIZATION")
user_role = rh.get_token(token[-11:])
self.running_log.info('[api doc] [user_role={0} business_type={1}] '.format(user_role, business_type))
if user_role is None or user_role == '-1' or (user_role == '1' and business_type == 'HIL') or (user_role == '2' and business_type == 'AFC'):
# pagination = {'current': page, 'total': 0, 'page_size': page_size}
# res = {
# 'pagination': pagination,
# 'doc_list': []
# }
# return response.ok(data=res)
raise NoPermissionException('no permission')
if user_role is None or user_role == '-1' or (user_role == '1' and business_type == 'HIL') or (user_role == '2' and business_type == 'AFC'):
# pagination = {'current': page, 'total': 0, 'page_size': page_size}
# res = {
# 'pagination': pagination,
# 'doc_list': []
# }
# return response.ok(data=res)
raise NoPermissionException('no permission')
status_query = Q(status=status) if status is not None else Q()
application_id_query = Q(application_id__contains=application_id) if application_id is not None else Q()
data_source_query = Q(data_source=data_source) if data_source is not None else Q()
......@@ -1224,6 +1272,14 @@ class CompareResultView(GenericView):
scheme = args.get('scheme')
case_id = args.get('case_id')
is_auto = args.get('auto')
# 角色权限不符,返回异常
token = request.META.get("HTTP_AUTHORIZATION")
user_role = rh.get_token(token[-11:])
self.running_log.info('[CompareResultView] [user_role={0}] '.format(user_role))
if user_role is None or user_role == '-1' or (user_role == '1' and entity == 'HIL') or (user_role == '2' and entity == 'AFC'):
raise NoPermissionException('no permission')
if is_auto == 1:
result_table = HILAutoSettlement if entity == consts.HIL_PREFIX else AFCAutoSettlement
......@@ -1460,10 +1516,18 @@ class SECMSView(GenericView):
# CMS上传比对信息接口 SE
# @use_args(se_cms_args, location='data')
def post(self, request): # interface_report cms to ocr
# 如果是压测 直接返回通过结果
is_pressure = notifyCmsPass(self, request)
if is_pressure:
return response.ok()
# 以下时非压测时的正常逻辑
start_time = time.time()
args = request.data
cms_info = args.get('content', {})
# uat 强制"仅接受银行流水"
# cms_info['autoApprovedDetails']['PolicyComments'] = '仅接受银行流水'
business_type = consts.AFC_PREFIX if cms_info.get('financeCompany', '').startswith(
'宝马') else consts.HIL_PREFIX
src_application_id = cms_info.get('settlemnetVerification', {}).get('applicationNo', '')
......@@ -1477,6 +1541,11 @@ class SECMSView(GenericView):
fsm_contract = cms_info.get('FSMContract', False)
is_fsm=1 if fsm_contract else 0
# 测试是否单线程
#self.running_log.info('接到请求,准备sleep')
#time.sleep(10)
#self.running_log.info('sleep结束')
auto_class = HILAutoSettlement if business_type in consts.HIL_SET else AFCAutoSettlement
auto_obj = auto_class.objects.filter(application_id=application_id).first()
if is_auto:
......@@ -1616,6 +1685,19 @@ class AutoSettlementView(GenericView):
is_fsm = args.get('is_fsm')
# 角色权限不符,返回空列表
token = request.META.get("HTTP_AUTHORIZATION")
user_role = rh.get_token(token[-11:])
self.running_log.info('[AutoSettlementView] [user_role={0}] '.format(user_role))
if user_role is None or user_role == '-1' or (user_role == '1' and business_type == 'HIL') or (user_role == '2' and business_type == 'AFC'):
# pagination = {'current': page, 'total': 0, 'page_size': page_size}
# res = {
# 'pagination': pagination,
# 'doc_list': []
# }
# return response.ok(data=res)
raise NoPermissionException('no permission')
if isinstance(auto_result, int):
auto_result = consts.RESULT_MAP.get(auto_result)
if isinstance(whole_result, int):
......@@ -1700,6 +1782,13 @@ class AutoSettlementExcelView(GenericView):
is_fsm = args.get('is_fsm')
# 角色权限不符,返回异常
token = request.META.get("HTTP_AUTHORIZATION")
user_role = rh.get_token(token[-11:])
self.running_log.info('[AutoSettlementExcelView] [user_role={0}] '.format(user_role))
if user_role is None or user_role == '-1' or (user_role == '1' and business_type == 'HIL') or (user_role == '2' and business_type == 'AFC'):
raise NoPermissionException('no permission')
if isinstance(auto_result, int):
auto_result = consts.RESULT_MAP.get(auto_result)
if isinstance(whole_result, int):
......@@ -1847,3 +1936,206 @@ class GoView(GenericView):
return response.ok(data=result)
else:
return response.error_msg(msg='识别错误')
class InvoiceExcelView(GenericView):
#permission_classes = [IsAuthenticated]
#authentication_classes = [OAuth2AuthenticationWithUser]
# 下载发票excel
@use_args(invoice_download_args, location='querystring')
def get(self, request, args):
application_ids = args.get('application_ids')
application_entity = args.get('application_entity')
self.running_log.info('[InvoiceExcelView] [user_role={0}] '.format('111222333'))
# 角色权限不符,返回异常
token = request.META.get("HTTP_AUTHORIZATION")
user_role = rh.get_token(token[-11:])
self.running_log.info('[InvoiceExcelView] [user_role={0}] '.format(user_role))
if user_role is None or user_role == '-1' or (user_role == '1' and application_entity == '2') or (user_role == '2' and application_entity == '1'):
self.running_log.info('[InvoiceExcelView no permission] [user_role={0}] [application_entity={1}]'.format(user_role, application_entity))
raise NoPermissionException('no permission')
url = 'http://127.0.0.1:8088/napi/invoice/downloadExcelOri'
body = {
'applicationIds': application_ids,
'applicationEntity': application_entity
}
try:
self.running_log.info("request java invoice excel api, url:{0}, body:{1}".format(url, json.dumps(body)))
headers = {
'Content-Type': 'application/json'
}
resp = requests.post(url, headers=headers, json=body)
self.running_log.info("java invoice excel api finish, applicationIds:{0},{1}".format(application_ids, resp.text))
res_json = json.loads(resp.text)
file_path = res_json.get('result')
self.running_log.info("java invoice excel after process, filePath:{0}".format(file_path))
current_time = time.strftime('%Y-%m-%d_%H_%M_%S', time.localtime())
download_file_name = "发票信息提取-" + current_time + ".xlsx"
f = open(file_path,"rb")
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename="{0}"'.format(escape_uri_path(download_file_name))
response['Access-Control-Expose-Headers'] = 'content-disposition'
response.write(f.read())
f.close()
return response
except Exception as e:
self.running_log.error("invoice excel request to java error, url:{0}, param:{1}, errorMsg:{2}".format(
url, json.dumps(body), traceback.format_exc()))
class InvoiceQueryInfoView(GenericView):
#permission_classes = [IsAuthenticated]
#authentication_classes = [OAuth2AuthenticationWithUser]
@use_args(invoice_download_args, location='querystring')
def get(self, request, args):
application_ids = args.get('application_ids')
application_entity = args.get('application_entity')
self.running_log.info('[InvoiceExcelView] [user_role={0}] '.format('111222333'))
# 角色权限不符,返回异常
token = request.META.get("HTTP_AUTHORIZATION")
user_role = rh.get_token(token[-11:])
self.running_log.info('[InvoiceQueryInfoView] [user_role={0}] '.format(user_role))
if user_role is None or user_role == '-1' or (user_role == '1' and application_entity == '2') or (user_role == '2' and application_entity == '1'):
self.running_log.info('[InvoiceExcelView no permission] [user_role={0}] [application_entity={1}]'.format(user_role, application_entity))
raise NoPermissionException('no permission')
url = 'http://127.0.0.1:8088/napi/invoice/queryInfoOri'
body = {
'applicationIds': application_ids,
'applicationEntity': application_entity
}
try:
self.running_log.info("request java invoice info api, url:{0}, body:{1}".format(url, json.dumps(body)))
headers = {
'Content-Type': 'application/json'
}
resp = requests.post(url, headers=headers, json=body)
self.running_log.info("java invoice info api finish, applicationIds:{0},{1}".format(application_ids, resp.text))
res_json = json.loads(resp.text)
java_result = res_json.get('result')
return response.ok(data=java_result)
except Exception as e:
self.running_log.error("invoice info request to java error, url:{0}, param:{1}, errorMsg:{2}".format(
url, json.dumps(body), traceback.format_exc()))
def notifyCmsPass(self, request):
args = request.data
cms_info = args.get('content', {})
business_type = consts.AFC_PREFIX if cms_info.get('financeCompany', '').startswith('宝马') else consts.HIL_PREFIX
src_application_id = cms_info.get('settlemnetVerification', {}).get('applicationNo', '')
application_id = src_application_id[:src_application_id.rfind('-')]
pressure_switch = Configs.objects.filter(id=3).first()
if pressure_switch is None or (pressure_switch is not None and pressure_switch.value == 'N'):
self.running_log.info('[pressure_switch] [entity={0}]]'.format(pressure_switch))
return False
application_link = '{0}/showList/showList?entity={1}&scheme={2}&case_id={3}'.format(
conf.BASE_URL, business_type, consts.COMPARE_DOC_SCHEME_LIST[1], application_id)
data = {
"SubtenantId": consts.TENANT_MAP[business_type],
"Data": {
"Result_Message": "Pass",
"AutoCheckResult": "Pass",
"Failure_Reason": "",
"Application_Number": application_id,
"Bank_Statement": "",
"Link_URL": application_link,
"OCR_Version": 1,
"Origin": consts.INFO_SOURCE[1]
}
}
try:
response = cms.send(data) # interface_report ocr to cms
except Exception as e:
self.running_log.error('[pressure cms error] [error={0}]'.format(traceback.format_exc()))
else:
self.running_log.info('[pressure cms success] [response={0}]'.format(response))
return True
class EmployeeView(GenericView):
permission_classes = [IsAuthenticated]
authentication_classes = [OAuth2AuthenticationWithUser]
@use_args(employee_args, location='data')
def post(self, request, args):
application_id = args.get('application_id')
business_type = args.get('business_type')
ocr_result_class = HILOCRResult if business_type in consts.HIL_SET else AFCOCRResult
ocr_result_info = ocr_result_class.objects.filter(application_id=application_id).first()
self.running_log.info('[query Employee] [application_id={0}] [business_type={1}] [ocr_result_info exist={2}]'.format(application_id, business_type, ocr_result_info is not None))
if not ocr_result_info:
self.running_log.info('[query Employee] [application_id={0}] ocr_result none'.format(application_id))
return response.ok(data=False)
bss_ocr_str = ocr_result_info.bss_ocr
if bss_ocr_str is None:
return response.ok(data=False)
bss_ocr = json.loads(bss_ocr_str)
self.running_log.info('[query Employee] [application_id={0}] [bss_ocr={1}]'.format(application_id, bss_ocr))
for one_bss in bss_ocr:
income_keywords = one_bss.get('income_keywords')
self.running_log.info('[query Employee] [application_id={0}] [income_keywords={1}]'.format(application_id, income_keywords))
if income_keywords is not None and len(income_keywords) > 0:
return response.ok(data=True)
return response.ok(data=False)
class SearchGBHistoryFileView(GenericView):
permission_classes = [IsAuthenticated]
authentication_classes = [OAuth2AuthenticationWithUser]
@use_args(q_gb_file_args, location='data')
def post(self, request, args):
file_path = args.get('file_path')
business_type = args.get('business_type')
gb_history_file_class = HILGreenBookHistoryFile if business_type in consts.HIL_SET else AFCGreenBookHistoryFile
ecm = ECM()
response_json = ecm.search_doc_info_list(file_path, business_type)
data_objects = response_json['Envelope']['Body']['executeResponse']['return']['dataPackage']['DataObjects']
self.running_log.info('[SearchGBHistoryFileView] [data_objects size={0}] '.format(len(data_objects)))
for data_object in data_objects:
object_id = data_object['Identity']['ObjectId']['@id']
properties_dict = {}
properties = data_object['Properties']['Properties']
for prop in properties:
name = prop['@name']
value = prop.get('Value', 'null') # 如果Value为空,则输出null
properties_dict[name] = value
self.running_log.info('[SearchGBHistoryFileView] [properties_dict={0}] '.format(properties_dict))
try:
gb_history_file_class.objects.create(
object_id=object_id,
object_name=properties_dict.get('object_name', ''),
application_no=properties_dict.get('b_application_no', ''),
object_type='green_book',
customer_name=properties_dict.get('b_customer_name', ''),
content_size=properties_dict.get('r_content_size', ''),
owner_name=properties_dict.get('owner_name', ''),
#input_date=properties_dict.get('b_input_date', ''),
#modify_date=properties_dict.get('r_modify_date', ''),
location=properties_dict.get('b_location', ''),
download_finish=False
)
except Exception as e:
self.exception_log.exception('[SearchGBHistoryFileView] [db save failed] [error={0}]'.format(traceback.format_exc()))
return response.ok(data=True)
class DownloadGBHistoryFileView(GenericView):
permission_classes = [IsAuthenticated]
authentication_classes = [OAuth2AuthenticationWithUser]
@use_args(d_gb_file_args, location='data')
def post(self, request, args):
business_type = args.get('business_type')
object_id = args.get('object_id')
save_path = args.get('save_path')
ecm = ECM()
ecm.download(save_path, object_id, 'green_book', business_type)
self.running_log.info('[DownloadGBHistoryFileView] [args={0}] '.format(args))
return response.ok(data=False)
\ No newline at end of file
......
......@@ -8,4 +8,6 @@ broker = conf.CELERY_BROKER_URL
app = Celery('celery_compare', broker=broker, include=['celery_compare.tasks'])
app.conf.update(worker_max_tasks_per_child=5, timezone='Asia/Shanghai')
# worker_max_tasks_per_child ,worker执行了几次任务就会死
#app.conf.update(worker_max_tasks_per_child=10, timezone='Asia/Shanghai')
app.conf.update(timezone='Asia/Shanghai')
......
import json
from multiprocessing.sharedctypes import Value
import os
import cv2
import time
......@@ -38,6 +39,7 @@ from apps.doc.models import (
HILCompareReportNew,
AFCCompareReportNew,
AFCDoc,
HILDoc,
DealerMapping,
)
from apps.doc import consts
......@@ -46,7 +48,14 @@ from apps.doc.ocr.cms import cms
from apps.doc.exceptions import GCAPException
from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType, SystemName
from common.tools.comparison import cp
from common.tools.des import decode_des
# from common.tools.des import decode_des
from common.tools.aes_util import aes_decrypt_cbc
import threading
import concurrent.futures
from concurrent.futures import ThreadPoolExecutor
pool = ThreadPoolExecutor(max_workers=50, thread_name_prefix="compare_thread_")
compare_log = logging.getLogger('compare')
log_base = '[Compare]'
......@@ -54,6 +63,7 @@ log_base = '[Compare]'
empty_str = ''
empty_error_type = 1000
des_key = conf.CMS_DES_KEY
des_iv = conf.CMS_DES_IV
def rotate_bound(image, angle):
......@@ -933,7 +943,11 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
# is_cdfl = True # 车贷分离
is_cdfl_bo = False # 车贷分离,主借
is_cdfl_co = False # 车贷分离,共借
is_bo_corporate = False
role_count = 0
borrower_name = ''
borrower_idnum = ''
legal_name = ''
# province = cms_info.get('province', '')
for individual_info in cms_info.get('applicantInformation', []):
role_count += 1
......@@ -942,6 +956,7 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
license_dict = {}
customer_name = individual_info.get('name', '').strip()
if legal_name == '':
legal_name = individual_info.get('legalRepName', '')
establishment_date = individual_info.get('establishmentDate', '')
# date_of_birth = individual_info.get('dateOfBirth', '')
......@@ -953,11 +968,26 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
if individual_info['applicantType'] == consts.APPLICANT_TYPE_ORDER[0] and not is_corporate:
is_cdfl_bo = True
# CHINARPA-4660 是否公户判断
customersubType = individual_info.get('customersubType', '')
if individual_info['applicantType'] == consts.APPLICANT_TYPE_ORDER[0] and is_corporate:
is_bo_corporate = True
# CHINARPA-4660 财报主借人姓名赋值
# CHINARPA-5075 首付款承诺书主借人证件号赋值
if individual_info['applicantType'] == consts.APPLICANT_TYPE_ORDER[0]:
borrower_name = customer_name
for id_info in individual_info.get('IDInformation', []):
if id_info.get('idType') in consts.SE_CMS_FIRST_ID_FIELD_MAPPING:
borrower_idnum = aes_decrypt_cbc(id_info.get('idNum', ''), des_key, des_iv)
elif is_corporate and id_info.get('idType') in ['Unified Social Credit Code', 'Tax Number', 'Business License Number']:
borrower_idnum = aes_decrypt_cbc(id_info.get('idNum', ''), des_key, des_iv)
for id_info in individual_info.get('IDInformation', []):
if id_info.get('idType') in consts.SE_CMS_FIRST_ID_FIELD_MAPPING:
license_en, is_prc = consts.SE_CMS_FIRST_ID_FIELD_MAPPING[id_info['idType']]
# ['customerName', 'idNum', 'dateOfBirth', 'idExpiryDate', 'hukouProvince']
id_num = decode_des(id_info.get('idNum', ''), des_key)
id_num = aes_decrypt_cbc(id_info.get('idNum', ''), des_key, des_iv)
field_input = [('customerName', customer_name), ('idNum', id_num),
('idExpiryDate', id_info.get('idExpiryDate', ''))]
# if is_prc:
......@@ -969,22 +999,23 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
elif id_info.get('idType') in ['Unified Social Credit Code', 'Tax Number', 'Business License Number']:
# ['companyName', 'legalRepName', 'businessLicenseNo', 'organizationCreditCode',
# 'taxRegistrationCertificateNo', 'establishmentDate', 'businessLicenseDueDate']
id_num = decode_des(id_info.get('idNum', ''), des_key)
# bl_field_input = [
# ('companyName', customer_name),
# ('legalRepName', legal_name),
# ('businessLicenseNo', id_num),
# ('organizationCreditCode', id_num),
# ('taxRegistrationCertificateNo', id_num),
id_num = aes_decrypt_cbc(id_info.get('idNum', ''), des_key, des_iv)
bl_field_input = [
('companyName', customer_name),
('legalRepName', legal_name),
('businessLicenseNo', id_num),
('organizationCreditCode', id_num),
('taxRegistrationCertificateNo', id_num),
# ('businessLicenseDueDate', id_info.get('idExpiryDate', '')),
# ]
]
if is_corporate:
company_info_list.append((customer_name, id_num, legal_name))
# else:
# bl_field_input.append(('establishmentDate', establishment_date))
else:
bl_field_input.append(('establishmentDate', establishment_date))
# license_dict[consts.BL_EN] = bl_field_input
compare_log.info('{0} [bl_field_input] [{1}]'.format(log_base, bl_field_input))
license_dict[consts.BL_EN] = bl_field_input
all_id_num.append(id_num)
# SME营业执照---------------------------------------------------------------------------------------------------
......@@ -1000,6 +1031,7 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
(customer_name, '、'.join(all_id_num), all_id_num[0])
)
compare_log.info('{0} [license_dict] [{1}]'.format(log_base, license_dict))
if len(license_dict) > 0:
individual_info_dict.setdefault(individual_info['applicantType'], []).append(license_dict)
......@@ -1067,7 +1099,7 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[1], co_id if is_cdfl else main_id)) # 车贷分离
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[2], first_submission_date))
# vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[3], consts.SE_STAMP_VALUE))
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[4], consts.SE_FPL_VALUE))
# vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[4], consts.SE_FPL_VALUE))
bhsj = float(amount) / 1.13
# vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[5], consts.SPLIT_STR.join([
# format(bhsj, '.2f'),
......@@ -1120,16 +1152,51 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
# vehicle_info[consts.UCI_EN] = vehicle_field_input
compare_info['vehicleInfo'] = vehicle_info
# 公户财务报表-------------------------------------------------------------------------------------------------
financial_statement_info = {}
financial_statement_input = []
corporateFinancialInformation = cms_info.get('corporateFinancialInformation', {})
hashCode = corporateFinancialInformation.get('hashCode', '')
fiscalYear = corporateFinancialInformation.get('fiscalYear', '')
totalAssets = corporateFinancialInformation.get('totaAssets', 0)
totalLiabilitiesAndOwnersEquity = corporateFinancialInformation.get('totalLiabilitiesAndOwnersEquity', 0)
netProfit = corporateFinancialInformation.get('netProfit', 0)
if is_bo_corporate:
financial_statement_input.append((consts.SE_FS_FIELD[0], hashCode))
financial_statement_input.append((consts.SE_FS_FIELD[1], consts.SE_STAMP_VALUE))
financial_statement_input.append((consts.SE_FS_FIELD[2], fiscalYear))
financial_statement_input.append((consts.SE_FS_FIELD[3], [totalAssets, totalLiabilitiesAndOwnersEquity]))
financial_statement_input.append((consts.SE_FS_FIELD[4], [netProfit]))
financial_statement_info[consts.FS_EN] = financial_statement_input
compare_info['financialStatementInfo'] = financial_statement_info
# 财报情况说明
financial_statement_supplementary_info = {}
financial_statement_supplementary_input = []
cashAndCashEquivalentAtEndOfPeriod = corporateFinancialInformation.get('cashAndCashEquivalentAtEndOfPeriod', '')
if cashAndCashEquivalentAtEndOfPeriod == '':
need_fss = False
else:
need_fss = float(cashAndCashEquivalentAtEndOfPeriod) == 0
if is_bo_corporate and need_fss:
financial_statement_supplementary_input.append((consts.SE_FSS_FIELD[0], borrower_name))
financial_statement_supplementary_input.append((consts.SE_FSS_FIELD[1], consts.SE_STAMP_VALUE))
financial_statement_supplementary_info[consts.FSS_EN] = financial_statement_supplementary_input
compare_info['financialStatementSupplementaryInfo'] = financial_statement_supplementary_info
# 银行卡-------------------------------------------------------------------------------------------------------
bank_info = {}
bank_name = cms_info.get('bankAccountDetails', {}).get('bankName', '')
account_no = decode_des(cms_info.get('bankAccountDetails', {}).get('accountNo', ''), des_key)
account_no = aes_decrypt_cbc(cms_info.get('bankAccountDetails', {}).get('accountNo', ''), des_key, des_iv)
account_holder_name = cms_info.get('bankAccountDetails', {}).get('accountHolderName', '')
is_gsyh = True if '工商' in bank_name else False
if isinstance(company_info, tuple) and company_info[0] == account_holder_name:
pass
elif not ignore_bank:
# CHINARPA-4942 去掉注释逻辑,改为只要not ignore_bank 银行卡都要校验,不论是否公户
# if isinstance(company_info, tuple) and company_info[0] == account_holder_name:
# pass
# el
if not ignore_bank:
bank_field_input = [
('accountNo', account_no),
('bankName', bank_name),
......@@ -1154,9 +1221,11 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
compare_info['bankInfo'] = bank_info
# 银行流水 --------------------------------------------------------------------
#增加 allow_bs_type 默认值,防止不需要比对流水的申请报错
allow_bs_type = '全部'
if cms_info.get('autoApprovedDetails', {}).get('aaType', '') in ['CAA1', 'CAA2'] and \
'无需提供银行流水' not in cms_info.get('autoApprovedDetails', {}).get('PolicyComments', ''):
date_timedelta = 60 if auto else 90
date_timedelta = 83 if auto else 83
bs_role_list = []
for applicant_type in consts.APPLICANT_TYPE_ORDER[:2]:
if applicant_type in main_role_info:
......@@ -1170,6 +1239,14 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
(consts.SE_BS_FIELD[2], date_timedelta),
]
#在比对逻辑中添加字段
if '仅接受银行流水' in cms_info.get('autoApprovedDetails', {}).get('PolicyComments', ''):
#bs_field_input.append((consts.SE_BS_FIELD[9], '仅接受银行流水'))
allow_bs_type = '仅接受银行流水'
else:
#bs_field_input.append((consts.SE_BS_FIELD[9], '全部'))
allow_bs_type = '全部'
dbr_bs_role_list = []
for dbr_bs_role, _, _ in main_role_info.get(consts.APPLICANT_TYPE_ORDER[2], []):
dbr_bs_role_list.append(dbr_bs_role)
......@@ -1251,9 +1328,9 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
tmp_gzs_list = [amount, ]
# 保单 -----------------------------------------------------------------------------------------------------------
# 以前被注释的 start
# is_insurance = 0
# fp_campaign = cms_info.get('fpCampaign', '')
fp_group = cms_info.get('fpGroup', '')
# insurance_type = cms_info.get('insuranceDetails', {}).get('insuranceType', '')
# if insurance_type == 'Waive Insurance' and isinstance(insurance_price, str):
# is_insurance = 1
......@@ -1283,6 +1360,40 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
# if is_insurance == 1:
# bd_field_input.append((consts.SE_BD_FIELD[10], insurance_price))
# other_info[consts.BD_EN] = bd_field_input
# 以前被注释的 end
is_insurance = 0
fp_campaign = cms_info.get('fpCampaign', '')
fp_group = cms_info.get('fpGroup', '')
insurance_type = cms_info.get('insuranceDetails', {}).get('insuranceType', '')
if isinstance(insurance_price, str):
is_insurance = 1
elif insurance_type == 'Comprehensive Insurance':
is_insurance = 2
if is_insurance != 0:
if fp_campaign.find('OCU') == -1:
ssx_amount = amount
else:
ssx_amount = format(float(amount) * 0.8, '.2f')
if fp_campaign.find('Joy_Plus') == -1 or fp_campaign.find('JoyPlus') == -1:
dszx_amount = '200000'
else:
dszx_amount = '500000'
bd_field_input = [
(consts.SE_BD_FIELD[0], [co_name, bo_name] if is_cdfl else [main_name, ]), # 车贷分离
(consts.SE_BD_FIELD[1], [co_id, bo_id] if is_cdfl else [main_id, ]), # 车贷分离
(consts.SE_BD_FIELD[2], vin_no),
# (consts.SE_BD_FIELD[3], ssx_amount),
# (consts.SE_BD_FIELD[4], dszx_amount),
# (consts.SE_BD_FIELD[5], consts.JDMPV_VALUE),
(consts.SE_BD_FIELD[6], cms_info.get('insuranceDetails', {}).get('startDate', '')),
(consts.SE_BD_FIELD[7], cms_info.get('insuranceDetails', {}).get('endDate', '')),
(consts.SE_BD_FIELD[8], consts.SE_STAMP_VALUE),
# (consts.SE_BD_FIELD[9], consts.SE_DYSYR_VALUE),
]
if is_insurance == 1:
bd_field_input.append((consts.SE_BD_FIELD[10], insurance_price))
other_info[consts.BD_EN] = bd_field_input
if len(other_info) > 0:
compare_info['other'] = other_info
......@@ -1341,6 +1452,9 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
if len(main_role_info[app_type]) >= id_idx+1:
is_find = True
if isinstance(field_idx, int):
if key == '承租人签字' and is_bo_corporate:
hil_contract_1_input.append((key, legal_name))
else:
hil_contract_1_input.append((key, main_role_info[app_type][id_idx][field_idx]))
else:
hil_contract_1_input.append((key, field_idx))
......@@ -1383,6 +1497,9 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
if len(main_role_info[app_type]) >= id_idx+1:
is_find = True
if isinstance(field_idx, int):
if key == '抵押人签字' and is_bo_corporate:
hil_contract_2_input.append((key, legal_name))
else:
hil_contract_2_input.append((key, main_role_info[app_type][id_idx][field_idx]))
else:
hil_contract_2_input.append((key, field_idx))
......@@ -1390,7 +1507,7 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
hil_contract_2_input.append((key, empty_str))
contract_info[consts.HIL_CONTRACT_2_EN] = hil_contract_2_input
compare_info['contract'] = contract_info
return compare_info, cms_info.get('autoApprovedDetails', {}).get('aaType', ''), is_gsyh
return compare_info, cms_info.get('autoApprovedDetails', {}).get('aaType', ''), is_gsyh, allow_bs_type
else:
# AFC合同------------------------------------------------------------------------------------------------------
vehicle_principal_str = str(cms_info.get('financialInformation', {}).get('vehiclePrincipal', '0.0'))
......@@ -1450,6 +1567,9 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
if len(main_role_info[app_type]) >= id_idx+1:
is_find = True
if isinstance(field_idx, int):
if (key == '借款人签字及时间' or key == '主借人签字') and is_bo_corporate:
afc_contract_input.append((key, legal_name))
else:
afc_contract_input.append((key, main_role_info[app_type][id_idx][field_idx]))
else:
afc_contract_input.append((key, field_idx))
......@@ -1466,7 +1586,21 @@ def get_se_cms_compare_info_auto(application_id, last_obj, application_entity, d
contract_info[consts.AFC_CONTRACT_QRS_EN] = afc_contract_qrs_input
compare_info['contract'] = contract_info
return compare_info, cms_info.get('autoApprovedDetails', {}).get('aaType', ''), is_gsyh
# 首付款承诺书
down_payment_info = {}
down_payment_input = []
totalDownPayment = str(cms_info.get('financialInformation', {}).get('totalDownPayment'))
if totalDownPayment and totalDownPayment != '0.00':
down_payment_input.append((consts.SE_DP_FIELD[0], cms_info.get('financeCompany', '')))
down_payment_input.append((consts.SE_DP_FIELD[1], borrower_name))
down_payment_input.append((consts.SE_DP_FIELD[2], borrower_idnum))
down_payment_input.append((consts.SE_DP_FIELD[3], cms_info.get('settlemnetVerification', {}).get('applicationNo', '')))
down_payment_input.append((consts.SE_DP_FIELD[4], legal_name if is_bo_corporate else borrower_name ))
down_payment_input.append((consts.SE_DP_FIELD[5], '有/无'))
down_payment_info[consts.DP_EN] = down_payment_input
compare_info['downPayment'] = down_payment_info
return compare_info, cms_info.get('autoApprovedDetails', {}).get('aaType', ''), is_gsyh, allow_bs_type
def get_se_cms_compare_info(application_id, last_obj, application_entity, detect_list, data_source, auto=False, ignore_bank=False):
......@@ -1500,7 +1634,11 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
# 个人信息证件------------------------------------------------------------------------------------------------------
is_cdfl_bo = False # 车贷分离,主借
is_cdfl_co = False # 车贷分离,共借
is_bo_corporate = False
role_count = 0
borrower_name = ''
borrower_idnum = ''
legal_name = ''
# province = cms_info.get('province', '')
for individual_info in cms_info.get('applicantInformation', []):
role_count += 1
......@@ -1509,6 +1647,7 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
license_dict = {}
customer_name = individual_info.get('name', '').strip()
if legal_name == '':
legal_name = individual_info.get('legalRepName', '')
establishment_date = individual_info.get('establishmentDate', '')
# date_of_birth = individual_info.get('dateOfBirth', '')
......@@ -1520,11 +1659,26 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
if individual_info['applicantType'] == consts.APPLICANT_TYPE_ORDER[0] and not is_corporate:
is_cdfl_bo = True
# CHINARPA-4660 是否公户判断
customersubType = individual_info.get('customersubType', '')
if individual_info['applicantType'] == consts.APPLICANT_TYPE_ORDER[0] and is_corporate:
is_bo_corporate = True
# CHINARPA-4660 财报主借人姓名赋值
# CHINARPA-5075 首付款承诺书主借人证件号赋值
if individual_info['applicantType'] == consts.APPLICANT_TYPE_ORDER[0]:
borrower_name = customer_name
for id_info in individual_info.get('IDInformation', []):
if id_info.get('idType') in consts.SE_CMS_FIRST_ID_FIELD_MAPPING:
borrower_idnum = aes_decrypt_cbc(id_info.get('idNum', ''), des_key, des_iv)
elif is_corporate and id_info.get('idType') in ['Unified Social Credit Code', 'Tax Number', 'Business License Number']:
borrower_idnum = aes_decrypt_cbc(id_info.get('idNum', ''), des_key, des_iv)
for id_info in individual_info.get('IDInformation', []):
if id_info.get('idType') in consts.SE_CMS_FIRST_ID_FIELD_MAPPING:
license_en, is_prc = consts.SE_CMS_FIRST_ID_FIELD_MAPPING[id_info['idType']]
# ['customerName', 'idNum', 'dateOfBirth', 'idExpiryDate', 'hukouProvince']
id_num = decode_des(id_info.get('idNum', ''), des_key)
id_num = aes_decrypt_cbc(id_info.get('idNum', ''), des_key, des_iv)
field_input = [('customerName', customer_name), ('idNum', id_num),
('idExpiryDate', id_info.get('idExpiryDate', ''))]
# if is_prc:
......@@ -1536,7 +1690,7 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
elif id_info.get('idType') in ['Unified Social Credit Code', 'Tax Number', 'Business License Number']:
# ['companyName', 'legalRepName', 'businessLicenseNo', 'organizationCreditCode',
# 'taxRegistrationCertificateNo', 'establishmentDate', 'businessLicenseDueDate']
id_num = decode_des(id_info.get('idNum', ''), des_key)
id_num = aes_decrypt_cbc(id_info.get('idNum', ''), des_key, des_iv)
bl_field_input = [
('companyName', customer_name),
('legalRepName', legal_name),
......@@ -1551,6 +1705,7 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
else:
bl_field_input.append(('establishmentDate', establishment_date))
compare_log.info('{0} [bl_field_input] [{1}]'.format(log_base, bl_field_input))
license_dict[consts.BL_EN] = bl_field_input
all_id_num.append(id_num)
......@@ -1567,6 +1722,7 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
(customer_name, '、'.join(all_id_num), all_id_num[0])
)
compare_log.info('{0} [license_dict] [{1}]'.format(log_base, license_dict))
if len(license_dict) > 0:
individual_info_dict.setdefault(individual_info['applicantType'], []).append(license_dict)
......@@ -1630,7 +1786,7 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[1], co_id if is_cdfl else main_id)) # 车贷分离
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[2], first_submission_date))
# vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[3], consts.SE_STAMP_VALUE))
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[4], consts.SE_FPL_VALUE))
# vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[4], consts.SE_FPL_VALUE))
bhsj = float(amount) / 1.13
# vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[5], consts.SPLIT_STR.join([
# format(bhsj, '.2f'),
......@@ -1687,16 +1843,51 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
vehicle_info[consts.UCI_EN] = vehicle_field_input
compare_info['vehicleInfo'] = vehicle_info
# 公户财务报表-------------------------------------------------------------------------------------------------
financial_statement_info = {}
financial_statement_input = []
corporateFinancialInformation = cms_info.get('corporateFinancialInformation', {})
hashCode = corporateFinancialInformation.get('hashCode', '')
fiscalYear = corporateFinancialInformation.get('fiscalYear', '')
totalAssets = corporateFinancialInformation.get('totaAssets', 0)
totalLiabilitiesAndOwnersEquity = corporateFinancialInformation.get('totalLiabilitiesAndOwnersEquity', 0)
netProfit = corporateFinancialInformation.get('netProfit', 0)
if is_bo_corporate:
financial_statement_input.append((consts.SE_FS_FIELD[0], hashCode))
financial_statement_input.append((consts.SE_FS_FIELD[1], consts.SE_STAMP_VALUE))
financial_statement_input.append((consts.SE_FS_FIELD[2], fiscalYear))
financial_statement_input.append((consts.SE_FS_FIELD[3], [totalAssets, totalLiabilitiesAndOwnersEquity]))
financial_statement_input.append((consts.SE_FS_FIELD[4], [netProfit]))
financial_statement_info[consts.FS_EN] = financial_statement_input
compare_info['financialStatementInfo'] = financial_statement_info
# 财报情况说明
financial_statement_supplementary_info = {}
financial_statement_supplementary_input = []
cashAndCashEquivalentAtEndOfPeriod = corporateFinancialInformation.get('cashAndCashEquivalentAtEndOfPeriod', '')
if cashAndCashEquivalentAtEndOfPeriod == '':
need_fss = False
else:
need_fss = float(cashAndCashEquivalentAtEndOfPeriod) == 0
if is_bo_corporate and need_fss:
financial_statement_supplementary_input.append((consts.SE_FSS_FIELD[0], borrower_name))
financial_statement_supplementary_input.append((consts.SE_FSS_FIELD[1], consts.SE_STAMP_VALUE))
financial_statement_supplementary_info[consts.FSS_EN] = financial_statement_supplementary_input
compare_info['financialStatementSupplementaryInfo'] = financial_statement_supplementary_info
# 银行卡-------------------------------------------------------------------------------------------------------
bank_info = {}
bank_name = cms_info.get('bankAccountDetails', {}).get('bankName', '')
account_no = decode_des(cms_info.get('bankAccountDetails', {}).get('accountNo', ''), des_key)
account_no = aes_decrypt_cbc(cms_info.get('bankAccountDetails', {}).get('accountNo', ''), des_key, des_iv)
account_holder_name = cms_info.get('bankAccountDetails', {}).get('accountHolderName', '')
is_gsyh = True if '工商' in bank_name else False
if isinstance(company_info, tuple) and company_info[0] == account_holder_name:
pass
elif not ignore_bank:
# CHINARPA-4942 去掉注释逻辑,改为只要not ignore_bank 银行卡都要校验,不论是否公户
# if isinstance(company_info, tuple) and company_info[0] == account_holder_name:
# pass
# el
if not ignore_bank:
bank_field_input = [
('accountNo', account_no),
('bankName', bank_name),
......@@ -1721,9 +1912,11 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
compare_info['bankInfo'] = bank_info
# 银行流水 --------------------------------------------------------------------
#增加 allow_bs_type 默认值,防止不需要比对流水的申请报错
allow_bs_type = '全部'
if cms_info.get('autoApprovedDetails', {}).get('aaType', '') in ['CAA1', 'CAA2'] and \
'无需提供银行流水' not in cms_info.get('autoApprovedDetails', {}).get('PolicyComments', ''):
date_timedelta = 60 if auto else 90
date_timedelta = 83 if auto else 83
bs_role_list = []
for applicant_type in consts.APPLICANT_TYPE_ORDER[:2]:
if applicant_type in main_role_info:
......@@ -1737,6 +1930,14 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
(consts.SE_BS_FIELD[2], date_timedelta),
]
#在比对逻辑中添加字段
if '仅接受银行流水' in cms_info.get('autoApprovedDetails', {}).get('PolicyComments', ''):
#bs_field_input.append((consts.SE_BS_FIELD[9], '仅接受银行流水'))
allow_bs_type = '仅接受银行流水'
else:
#bs_field_input.append((consts.SE_BS_FIELD[9], '全部'))
allow_bs_type = '全部'
dbr_bs_role_list = []
for dbr_bs_role, _, _ in main_role_info.get(consts.APPLICANT_TYPE_ORDER[2], []):
dbr_bs_role_list.append(dbr_bs_role)
......@@ -1837,13 +2038,13 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
(consts.SE_BD_FIELD[0], [co_name, bo_name] if is_cdfl else [main_name, ]), # 车贷分离
(consts.SE_BD_FIELD[1], [co_id, bo_id] if is_cdfl else [main_id, ]), # 车贷分离
(consts.SE_BD_FIELD[2], vin_no),
(consts.SE_BD_FIELD[3], ssx_amount),
(consts.SE_BD_FIELD[4], dszx_amount),
(consts.SE_BD_FIELD[5], consts.JDMPV_VALUE),
# (consts.SE_BD_FIELD[3], ssx_amount),
# (consts.SE_BD_FIELD[4], dszx_amount),
# (consts.SE_BD_FIELD[5], consts.JDMPV_VALUE),
(consts.SE_BD_FIELD[6], cms_info.get('insuranceDetails', {}).get('startDate', '')),
(consts.SE_BD_FIELD[7], cms_info.get('insuranceDetails', {}).get('endDate', '')),
(consts.SE_BD_FIELD[8], consts.SE_STAMP_VALUE),
(consts.SE_BD_FIELD[9], consts.SE_DYSYR_VALUE),
# (consts.SE_BD_FIELD[9], consts.SE_DYSYR_VALUE),
]
if is_insurance == 1:
bd_field_input.append((consts.SE_BD_FIELD[10], insurance_price))
......@@ -1905,6 +2106,9 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
if len(main_role_info[app_type]) >= id_idx+1:
is_find = True
if isinstance(field_idx, int):
if key == '承租人签字' and is_bo_corporate:
hil_contract_1_input.append((key, legal_name))
else:
hil_contract_1_input.append((key, main_role_info[app_type][id_idx][field_idx]))
else:
hil_contract_1_input.append((key, field_idx))
......@@ -1924,6 +2128,9 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
(consts.SE_HIL_CON_3_FIELD[6], main_id),
]
if online_sign:
if is_bo_corporate:
hil_contract_3_input.append((consts.SE_HIL_CON_3_FIELD[7], legal_name))
else:
hil_contract_3_input.append((consts.SE_HIL_CON_3_FIELD[7], main_name))
contract_info[consts.HIL_CONTRACT_3_EN] = hil_contract_3_input
......@@ -1947,6 +2154,9 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
if len(main_role_info[app_type]) >= id_idx+1:
is_find = True
if isinstance(field_idx, int):
if key == '抵押人签字' and is_bo_corporate:
hil_contract_2_input.append((key, legal_name))
else:
hil_contract_2_input.append((key, main_role_info[app_type][id_idx][field_idx]))
else:
hil_contract_2_input.append((key, field_idx))
......@@ -1954,7 +2164,7 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
hil_contract_2_input.append((key, empty_str))
contract_info[consts.HIL_CONTRACT_2_EN] = hil_contract_2_input
compare_info['contract'] = contract_info
return compare_info, cms_info.get('applicationVersion', 1), cms_info.get('autoApprovedDetails', {}).get('aaType', ''), is_gsyh
return compare_info, cms_info.get('applicationVersion', 1), cms_info.get('autoApprovedDetails', {}).get('aaType', ''), is_gsyh, allow_bs_type
else:
# AFC合同------------------------------------------------------------------------------------------------------
vehicle_principal_str = str(cms_info.get('financialInformation', {}).get('vehiclePrincipal', '0.0'))
......@@ -2014,6 +2224,9 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
if len(main_role_info[app_type]) >= id_idx+1:
is_find = True
if isinstance(field_idx, int):
if (key == '借款人签字及时间' or key == '主借人签字') and is_bo_corporate:
afc_contract_input.append((key, legal_name))
else:
afc_contract_input.append((key, main_role_info[app_type][id_idx][field_idx]))
else:
afc_contract_input.append((key, field_idx))
......@@ -2029,10 +2242,24 @@ def get_se_cms_compare_info(application_id, last_obj, application_entity, detect
afc_contract_qrs_input = [(consts.SE_AFC_CON_QRS_FIELD[0], '{0}{1}{2}'.format(role_count, consts.SPLIT_STR, full_no))]
contract_info[consts.AFC_CONTRACT_QRS_EN] = afc_contract_qrs_input
compare_info['contract'] = contract_info
return compare_info, cms_info.get('applicationVersion', 1), cms_info.get('autoApprovedDetails', {}).get('aaType', ''), is_gsyh
def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type):
# 首付款承诺书
down_payment_info = {}
down_payment_input = []
totalDownPayment = str(cms_info.get('financialInformation', {}).get('totalDownPayment'))
if totalDownPayment and totalDownPayment != '0.00':
down_payment_input.append((consts.SE_DP_FIELD[0], cms_info.get('financeCompany', '')))
down_payment_input.append((consts.SE_DP_FIELD[1], borrower_name))
down_payment_input.append((consts.SE_DP_FIELD[2], borrower_idnum))
down_payment_input.append((consts.SE_DP_FIELD[3], cms_info.get('settlemnetVerification', {}).get('applicationNo', '')))
down_payment_input.append((consts.SE_DP_FIELD[4], legal_name if is_bo_corporate else borrower_name ))
down_payment_input.append((consts.SE_DP_FIELD[5], '有/无'))
down_payment_info[consts.DP_EN] = down_payment_input
compare_info['downPayment'] = down_payment_info
return compare_info, cms_info.get('applicationVersion', 1), cms_info.get('autoApprovedDetails', {}).get('aaType', ''), is_gsyh, allow_bs_type
def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type, allow_bs_type):
# 主共借至少提供一个
# 有担保人,担保人必须提供。主共借没有时,修改comment:人工查看担保人亲属关系
......@@ -2046,6 +2273,7 @@ def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type):
field_img_path_dict = dict()
if ocr_res_str is not None:
# 字段在比对逻辑中添加的,这个地方不用改,如果要是在get_info时添加,要改这个
pre_field_list = strip_list[:3]
dbr1_field_list = strip_list[3:6]
dbr2_field_list = strip_list[6:]
......@@ -2062,13 +2290,21 @@ def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type):
auto_paper_verify_list = []
auto_elec_verify_list = []
auto_paper_verify_false_idx_list = []
auto_paper_verify_true_idx_list = []
auto_elec_verify_false_idx_list = []
all_zhifubao_weixin = True
for tmp_idx, ocr_res in enumerate(ocr_res_list):
correct_count = 0
pre_tmp_res_part = {}
verify_bool = ocr_res.get('verify', False)
e_bank = ocr_res.get('e_bank', False)
bankStatement_type = ocr_res.get('bankStatement_type', '')
# 如果是高风险经销商,cms信息中包含‘仅接受银行流水’,但是识别出的流水是支付宝/微信,直接跳过这个文件,就当不存在
if allow_bs_type == '仅接受银行流水' and bankStatement_type in ['12', '13', '48']:
continue
all_zhifubao_weixin = False
#verify_list.append(verify_bool)
if not verify_bool:
verify_false_idx_list.append(str(tmp_idx+1))
......@@ -2079,8 +2315,11 @@ def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type):
auto_elec_verify_false_idx_list.append(str(tmp_idx+1))
else:
auto_paper_verify_list.append(verify_bool)
verify_list.append(False)
verify_list.append(verify_bool)
if not verify_bool:
auto_paper_verify_false_idx_list.append(str(tmp_idx+1))
else:
auto_paper_verify_true_idx_list.append(str(tmp_idx+1))
for idx, (name, value) in enumerate(pre_field_list):
ocr_str_or_list = ocr_res.get(compare_logic[name][0])
......@@ -2117,47 +2356,100 @@ def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type):
# 非FSM Full CAA1
# 2023.12 auto CAA1 也使用此逻辑(之前非FSM auto CAA1不判断真伪)
if aa_type == 'CAA1':
name = '真伪'
# 若仅提供纸质流水,则默认真伪为N2
if not auto_elec_verify_list:
result = consts.RESULT_N2
reason = '第{0}份银行流水为纸质版,请核查流水真伪。'.format('、'.join(auto_paper_verify_false_idx_list))
# 若仅提供电子流水,逐一比对,有false为N1,全部true为Y
if not auto_paper_verify_list:
result = consts.RESULT_Y if all(auto_elec_verify_list) else consts.RESULT_N1
reason = '第{0}份银行流水疑似造假,需人工核查。'.format('、'.join(auto_elec_verify_false_idx_list))
#同时包含,同时返回N1,N2
if auto_elec_verify_list and auto_paper_verify_list:
result = consts.RESULT_Y if all(auto_elec_verify_list) else consts.RESULT_N1
reason1 = '第{0}份银行流水疑似造假,需人工核查。'.format('、'.join(auto_elec_verify_false_idx_list))
reason2 = '第{0}份银行流水为纸质版,请核查流水真伪。'.format('、'.join(auto_paper_verify_false_idx_list))
reason = reason1 + reason2
result_field_list.append((name, empty_str, result, json.dumps(verify_list, ensure_ascii=False), empty_str, empty_error_type, reason))
# 非FSM Full & Auto CAA2 目前逻辑和上面的完全一样
elif aa_type == 'CAA2' :
# ---------- 以下 CHINARPA-5153 作废
# if aa_type == 'CAA1':
# name = '真伪'
# # 若仅提供纸质流水,则默认真伪为N2
# if not auto_elec_verify_list:
# result = consts.RESULT_N2
# reason = '<关注>第{0}份流水为纸质版,请核查流水真伪。'.format('、'.join(auto_paper_verify_false_idx_list))
# # 若仅提供电子流水,逐一比对,有false为N1,全部true为Y
# if not auto_paper_verify_list:
# result = consts.RESULT_Y if all(auto_elec_verify_list) else consts.RESULT_N1
# reason = '<关注>第{0}份电子流水疑似造假,请核查excel。'.format('、'.join(auto_elec_verify_false_idx_list))
# #同时包含,同时返回N1,N2
# if auto_elec_verify_list and auto_paper_verify_list:
# result = consts.RESULT_Y if all(auto_elec_verify_list) else consts.RESULT_N1
# reason1 = '<关注>第{0}份电子流水疑似造假,请核查excel。'.format('、'.join(auto_elec_verify_false_idx_list))
# reason2 = '<关注>第{0}份流水为纸质版,请核查流水真伪。'.format('、'.join(auto_paper_verify_false_idx_list))
# reason = reason1 + '\n' + reason2
# result_field_list.append((name, empty_str, result, json.dumps(verify_list, ensure_ascii=False), empty_str, empty_error_type, reason))
# # 非FSM Full & Auto CAA2 目前逻辑和上面的完全一样
# elif aa_type == 'CAA2' :
# name = '真伪'
# # 若仅提供纸质流水,则默认真伪为N2
# if not auto_elec_verify_list:
# result = consts.RESULT_N2
# reason = '<关注>第{0}份流水为纸质版,请核查流水真伪。'.format('、'.join(auto_paper_verify_false_idx_list))
# # 若仅提供电子流水,逐一比对,有false为N1,全部true为Y
# if not auto_paper_verify_list:
# result = consts.RESULT_Y if all(auto_elec_verify_list) else consts.RESULT_N1
# reason = '<关注>第{0}份电子流水疑似造假,请核查excel。'.format('、'.join(auto_elec_verify_false_idx_list))
# #同时包含,同时返回N1,N2
# if auto_elec_verify_list and auto_paper_verify_list:
# result = consts.RESULT_Y if all(auto_elec_verify_list) else consts.RESULT_N1
# reason1 = '<关注>第{0}份电子流水疑似造假,请核查excel。'.format('、'.join(auto_elec_verify_false_idx_list))
# reason2 = '<关注>第{0}份流水为纸质版,请核查流水真伪。'.format('、'.join(auto_paper_verify_false_idx_list))
# reason = reason1 + '\n' + reason2
# result_field_list.append((name, empty_str, result, json.dumps(verify_list, ensure_ascii=False), empty_str, empty_error_type, reason))
# ---------- 以上 CHINARPA-5153 作废
# 【具体分支描述可以看java代码】
if aa_type == 'CAA1' or aa_type == 'CAA2':
name = '真伪'
# 若仅提供纸质流水,则默认真伪为N2
if not auto_elec_verify_list:
result = consts.RESULT_N2
reason = '第{0}份银行流水为纸质版,请核查流水真伪。'.format('、'.join(auto_paper_verify_false_idx_list))
# 若仅提供电子流水,逐一比对,有false为N1,全部true为Y
if not auto_paper_verify_list:
result = consts.RESULT_Y if all(auto_elec_verify_list) else consts.RESULT_N1
reason = '第{0}份银行流水疑似造假,需人工核查。'.format('、'.join(auto_elec_verify_false_idx_list))
#同时包含,同时返回N1,N2
reason_n1 = '<关注>第{0}份电子流水疑似造假,请核查excel。'.format('、'.join(auto_elec_verify_false_idx_list))
reason_n2 = '<关注>第{0}份流水为纸质版,请核查流水真伪。'.format('、'.join(auto_paper_verify_true_idx_list))
reason_n3 = '<关注>第{0}份纸质流水疑似造假,请核查excel。'.format('、'.join(auto_paper_verify_false_idx_list))
if auto_elec_verify_list and auto_paper_verify_list:
result = consts.RESULT_Y if all(auto_elec_verify_list) else consts.RESULT_N1
reason1 = '第{0}份银行流水疑似造假,需人工核查。'.format('、'.join(auto_elec_verify_false_idx_list))
reason2 = '第{0}份银行流水为纸质版,请核查流水真伪。'.format('、'.join(auto_paper_verify_false_idx_list))
reason = reason1 + reason2
# 有电子流水,有纸质流水,则需逐一判断电子流水属性或纸质流水检测结果
elecTrue = len(auto_elec_verify_false_idx_list) <= 0
paperTrue = len(auto_paper_verify_false_idx_list) <= 0
paperNotClear = len(auto_paper_verify_true_idx_list) > 0
if not elecTrue and not paperTrue and paperNotClear:
reason = reason_n1 + '\n' + reason_n2 + '\n' + reason_n3
elif not elecTrue and not paperTrue:
reason = reason_n1 + '\n' + reason_n3
elif not elecTrue and paperNotClear:
reason = reason_n1 + '\n' + reason_n2
elif elecTrue and not paperTrue and paperNotClear:
reason = reason_n2 + '\n' + reason_n3
elif elecTrue and paperNotClear:
reason = reason_n2
elif elecTrue and not paperTrue:
reason = reason_n3
result = consts.RESULT_Y if elecTrue and paperTrue and not paperNotClear else consts.RESULT_N
elif auto_elec_verify_list and not auto_paper_verify_list:
# 只有电子流水,以电子为准
reason = reason_n1
result = consts.RESULT_Y if all(auto_elec_verify_list) else consts.RESULT_N
elif not auto_elec_verify_list:
paperTrue = len(auto_paper_verify_false_idx_list) <= 0
paperNotClear = len(auto_paper_verify_true_idx_list) > 0
if not paperTrue and paperNotClear:
reason = reason_n2 + '\n' + reason_n3
elif paperNotClear:
reason = reason_n2
elif not paperTrue:
reason = reason_n3
result = consts.RESULT_N
result_field_list.append((name, empty_str, result, json.dumps(verify_list, ensure_ascii=False), empty_str, empty_error_type, reason))
if all_zhifubao_weixin:
# 核查点名称,cms传值,比对结果,ocr结果,图片路径,错误类型,错误描述
result_field_list.append(('类型', allow_bs_type, consts.RESULT_N, '全部为支付宝/微信', empty_str, ErrorType.NF.value, '高风险经销商流水类型异常'))
else:
result_field_list.append(('类型', allow_bs_type, consts.RESULT_Y, '包含支持的流水类型', empty_str, empty_error_type, ''))
# 担保人1
dbr1_best_res = {}
if len(dbr1_field_list) > 0:
max_correct_count = 0
for ocr_res in ocr_res_list:
bankStatement_type = ocr_res.get('bankStatement_type', '')
# 如果是高风险经销商,cms信息中包含‘仅接受银行流水’,但是识别出的流水是支付宝/微信,直接跳过这个文件,就当不存在
if allow_bs_type == '仅接受银行流水' and bankStatement_type in ['12', '13', '48']:
continue
correct_count = 0
dbr1_tmp_res_part = {}
for idx, (name, value) in enumerate(dbr1_field_list):
......@@ -2190,6 +2482,10 @@ def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type):
if len(dbr1_field_list) > 0:
max_correct_count = 0
for ocr_res in ocr_res_list:
bankStatement_type = ocr_res.get('bankStatement_type', '')
# 如果是高风险经销商,cms信息中包含‘仅接受银行流水’,但是识别出的流水是支付宝/微信,直接跳过这个文件,就当不存在
if allow_bs_type == '仅接受银行流水' and bankStatement_type in ['12', '13', '48']:
continue
correct_count = 0
dbr2_tmp_res_part = {}
for idx, (name, value) in enumerate(dbr2_field_list):
......@@ -2302,7 +2598,7 @@ def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type):
return result_field_list, field_img_path_dict
def se_compare_license(license_en, ocr_res_dict, field_list):
def se_compare_license(license_en, ocr_res_dict, field_list, is_auto):
ocr_field, compare_logic, special_expiry_date = consts.SE_COMPARE_FIELD[license_en]
is_find = False
......@@ -2312,6 +2608,7 @@ def se_compare_license(license_en, ocr_res_dict, field_list):
section_img_info = dict()
field_img_path_dict = dict()
ocr_res_str = ocr_res_dict.get(ocr_field)
compare_log.info('{0} [{1}_compare] ocr_res:{2}'.format(log_base, license_en, ocr_res_str))
if ocr_res_str is not None:
ocr_res_list = json.loads(ocr_res_str)
......@@ -2356,16 +2653,30 @@ def se_compare_license(license_en, ocr_res_dict, field_list):
ocr_res_list[res_idx].get(consts.LOWER_AMOUNT_FIELD, ''),
ocr_res_list[res_idx].get(consts.UPPER_AMOUNT_FIELD, ''),
)
# auto 保单 保险费合计 ocr结果需要加上一个基数,再与cms结果做比对
elif is_auto and ocr_field == consts.BD_FIELD and name == consts.SE_BD_FIELD[10]:
ocr_str = ocr_res_list[res_idx].get(compare_logic[name][0])
compare_log.info('{0} [bd_4962_price] [ori ocr_str:{1}] '.format(log_base, ocr_str))
add_price = conf.BD_PRICE
compare_log.info('{0} [bd_4962_price] [add_price:{1}] '.format(log_base, add_price))
ocr_str = str(float(ocr_str) + float(add_price))
compare_log.info('{0} [bd_4962_price] [final ocr_str:{1}] '.format(log_base, ocr_str))
else:
ocr_str = ocr_res_list[res_idx].get(compare_logic[name][0])
if isinstance(ocr_str, str):
result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2])
compare_log.info('{0} [{1}_license] [field:{2}] [input_str:{3}] [ocr_str:{4}] [result:{5}]'.format(log_base, license_en, name, value, ocr_str, result))
no_key = False
# 二手车交易凭证 日期
elif ocr_field == consts.JYPZ_OCR_FIELD and name == consts.SE_GB_USED_FIELD[2]:
result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2])
no_key = False
elif isinstance(ocr_str, int):
# 目前应该只有财报的公章
result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2])
compare_log.info('{0} [{1}_license] [field:{2}] [input_str:{3}] [ocr_str:{4}] [result:{5}]'.format(log_base, license_en, name, value, ocr_str, result))
no_key = False
else:
result = consts.RESULT_N
ocr_str = empty_str
......@@ -2489,6 +2800,113 @@ def se_compare_license(license_en, ocr_res_dict, field_list):
return result_field_list, no_ocr_result, field_img_path_dict
def se_fs_compare(license_en, ocr_res_dict, field_list):
compare_log.info('{0} [se_fs_compare] start'.format(log_base))
ocr_field, compare_logic, special_expiry_date = consts.SE_COMPARE_FIELD[license_en]
is_find = False
no_ocr_result = False
special_expiry_date_slice = False
result_field_list = []
section_img_info = dict()
field_img_path_dict = dict()
ocr_res_str = ocr_res_dict.get(ocr_field)
compare_log.info('{0} [se_fs_compare] ocr_res:{1}'.format(log_base, ocr_res_str))
if ocr_res_str is not None:
ocr_res_list = json.loads(ocr_res_str)
length = len(ocr_res_list)
last_ocr_str = ocr_res_list[length-1]
compare_log.info('{0} [se_fs_compare] [code len {1}] [stamp len {2}] ]'.format(log_base, len(last_ocr_str.get('code',{})), len(last_ocr_str.get('stamp',{}))))
if len(last_ocr_str.get('code',{})) != 3 or len(last_ocr_str.get('stamp',{})) != 3:
# 先判断最后一次上传的文件是不是包括3个,如果不是直接返回"未提供财报或财报不完整"
compare_log.info('{0} [se_fs_compare error] last ocr result len < 3'.format(log_base))
else:
for res_idx in range(length-1, -1, -1):
if is_find:
break
for idx, (name, value) in enumerate(field_list):
compare_log.info('{0} [se_fs_compare for ... in] [idx:{1}] [name:{2}] [value:{3}]'.format(log_base, idx, name, value))
ocr_str = ocr_res_list[res_idx].get(compare_logic[name][0])
compare_log.info('{0} [se_fs_compare ocr_str] [ocr_str:{1}]'.format(log_base, ocr_str))
#财年/资产负债表内容/利润表内容 不需要ocr结果,所以即使为空也可以进入比对
if isinstance(ocr_str, str) or isinstance(ocr_str, dict) or compare_logic[name][0] == '财年' or compare_logic[name][0] == '资产负债表内容' or compare_logic[name][0] == '利润表内容':
result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2])
compare_log.info('{0} [se_fs_compare result:{1}]'.format(log_base, result))
no_key = False
else:
result = consts.RESULT_N
ocr_str = empty_str
no_key = True
if idx == 0 and result == consts.RESULT_N and length > 1:
break
is_find = True
section_img_info[consts.SECTION_IMG_PATH_KEY] = ocr_res_list[res_idx].get(consts.SECTION_IMG_PATH_KEY, '')
section_img_info[consts.ALL_POSITION_KEY] = ocr_res_list[res_idx].get(consts.ALL_POSITION_KEY, {})
if special_expiry_date:
section_img_info[consts.SECTION_IMG_PATH_KEY_2] = ocr_res_list[res_idx].get(
consts.SECTION_IMG_PATH_KEY_2, '')
section_img_info[consts.ALL_POSITION_KEY_2] = ocr_res_list[res_idx].get(consts.ALL_POSITION_KEY_2, {})
img_path = ocr_res_list[res_idx].get(consts.IMG_PATH_KEY, '') if result == consts.RESULT_N else empty_str
if isinstance(value, list):
value = json.dumps(value, ensure_ascii=False)
error_type = empty_error_type if result == consts.RESULT_Y else ErrorType.OCR.value
result_field_list.append((name, value, result, ocr_str, img_path, error_type, compare_logic[name][3]))
else:
no_ocr_result = True
if not is_find:
for name, value in field_list:
if isinstance(value, list):
value = json.dumps(value, ensure_ascii=False)
no_find_str = consts.FS_NO_FIND
result_field_list.append((name, value, consts.RESULT_N, empty_str, empty_str, ErrorType.NF.value, no_find_str))
if is_find:
section_img_path = section_img_info.get(consts.SECTION_IMG_PATH_KEY, '')
if os.path.exists(section_img_path):
failed_field = []
base_img_path = empty_str
for name, _, result, _, img_path, _, _ in result_field_list:
if result == consts.RESULT_N:
if special_expiry_date_slice and name == 'idExpiryDate':
continue
failed_field.append(name)
if base_img_path == empty_str:
base_img_path = img_path
if len(failed_field) > 0:
info = section_img_info.get(consts.ALL_POSITION_KEY, {})
section_position = info.get(consts.POSITION_KEY, {})
section_angle = info.get(consts.ANGLE_KEY, 0)
try:
last_img = img_process(section_img_path, section_position, section_angle)
except Exception as e:
for field in failed_field:
field_img_path_dict[field] = base_img_path
else:
pre, suf = os.path.splitext(section_img_path)
for field in failed_field:
try:
res_field = compare_logic[field][0]
is_valid, coord_tuple = field_build_coordinates(info.get(res_field, {}))
if is_valid:
save_path = '{0}_{1}{2}'.format(pre, field, suf)
field_img = last_img[coord_tuple[0]:coord_tuple[1], coord_tuple[2]:coord_tuple[3], :]
cv2.imwrite(save_path, field_img)
field_img_path_dict[field] = save_path
else:
field_img_path_dict[field] = base_img_path
except Exception as e:
field_img_path_dict[field] = base_img_path
return result_field_list, field_img_path_dict
def se_compare_license_id(license_en, id_res_list, field_list, is_auto):
if is_auto:
......@@ -2975,7 +3393,7 @@ def se_mvc34_compare(license_en, ocr_res_dict, field_list):
return result_field_list, field_img_path_dict
def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto, id_res_list, aa_type):
def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto, id_res_list, aa_type, allow_bs_type):
# individualCusInfo
# corporateCusInfo
# vehicleInfo
......@@ -2989,9 +3407,11 @@ def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto, id_res_list
rpa_failure_reason = {}
field_result_dict = {}
# compare_info 格式: {'financialStatementInfo': {'Financial Statement': [('11', '22'), ('111', '222'), ('1111', '2222')]}}
for info_key, info_value in compare_info.items():
if info_key in ['individualCusInfo', 'applicantInformation']:
for idx, license_list in info_value.items():
compare_log.info('{0} [compare license_list] [entity={1}]'.format(log_base, license_list))
for license_dict in license_list:
for license_en, field_list in license_dict.items():
strip_list = []
......@@ -3015,7 +3435,7 @@ def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto, id_res_list
license_en, id_res_list, strip_list, is_auto)
else:
result_field_list, no_ocr_result, field_img_path_dict = se_compare_license(
license_en, ocr_res_dict, strip_list)
license_en, ocr_res_dict, strip_list, is_auto)
each_license_failed_count = 0
for name, value, result, ocr_str, img_path, error_type, cn_reason in result_field_list:
if license_en not in consts.SKIP_CARD or not no_ocr_result:
......@@ -3047,6 +3467,7 @@ def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto, id_res_list
each_license_failed_count, len(result_field_list)))
else:
for license_en, field_list in info_value.items():
compare_log.info('{0} [compare license_en] [entity={1}]'.format(log_base, license_en))
strip_list = []
for a, b in field_list:
if isinstance(b, str):
......@@ -3069,9 +3490,12 @@ def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto, id_res_list
elif license_en == consts.AFC_CONTRACT_QRS_EN:
result_field_list, field_img_path_dict = se_contract_qrs_compare(license_en, ocr_res_dict, strip_list)
elif license_en == consts.BS_EN:
result_field_list, field_img_path_dict = se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type)
# 银行流水的比对,是只要有正确的就可以,所以没有按照时间顺序,先比最新的,在比最早的,如果以后要改逻辑,切记这个
result_field_list, field_img_path_dict = se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto, aa_type, allow_bs_type)
elif license_en == consts.FS_EN:
result_field_list, field_img_path_dict = se_fs_compare(license_en, ocr_res_dict, strip_list)
else:
result_field_list, _, field_img_path_dict = se_compare_license(license_en, ocr_res_dict, strip_list)
result_field_list, _, field_img_path_dict = se_compare_license(license_en, ocr_res_dict, strip_list, is_auto)
each_license_failed_count = 0
for name, value, result, ocr_str, img_path, error_type, cn_reason in result_field_list:
......@@ -3126,6 +3550,8 @@ def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto, id_res_list
tmp_set = set()
last_cn_reason_list = []
last_cn_reason_list_attention = []
last_cn_reason_list_not_attention = []
bs_cn_reason_list = []
for i in cn_reason_list:
if i in tmp_set:
......@@ -3135,7 +3561,13 @@ def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto, id_res_list
# bs_cn_reason_list.append(i)
else:
tmp_set.add(i)
last_cn_reason_list.append(i)
if '关注' in i:
last_cn_reason_list_attention.append(i)
else:
last_cn_reason_list_not_attention.append(i)
# 要把2个list中的元素加进去,不是加整个list所以要用extend,不能用append
last_cn_reason_list.extend(last_cn_reason_list_attention)
last_cn_reason_list.extend(last_cn_reason_list_not_attention)
cn_failure_reason_str = '\n'.join(last_cn_reason_list)
bs_failure_reason_str = '\n'.join(bs_cn_reason_list)
return compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str, \
......@@ -3156,11 +3588,11 @@ def se_compare_auto(application_id, application_entity, ocr_res_id, last_obj, oc
try:
# 比对逻辑
# detect_list = se_result_detect(ocr_res_dict)
compare_info, aa_type, is_gsyh = get_se_cms_compare_info_auto(
compare_info, aa_type, is_gsyh, allow_bs_type = get_se_cms_compare_info_auto(
application_id, last_obj, application_entity, data_source, ignore_bank=ignore_bank)
compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str, \
cn_failure_reason_str, bs_failure_reason_str, _, field_result_dict = se_compare_process(
compare_info, ocr_res_dict, is_gsyh, True, id_res_list, aa_type)
compare_info, ocr_res_dict, is_gsyh, True, id_res_list, aa_type, allow_bs_type)
compare_log.info('{0} [Auto SE] [compare success] [entity={1}] [id={2}] [ocr_res_id={3}] [result={4}]'.format(
log_base, application_entity, application_id, ocr_res_id, compare_result))
except Exception as e:
......@@ -3223,11 +3655,11 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res
# 比对逻辑
start_time = datetime.now()
detect_list = se_result_detect(ocr_res_dict)
compare_info, application_version, aa_type, is_gsyh = get_se_cms_compare_info(
compare_info, application_version, aa_type, is_gsyh, allow_bs_type = get_se_cms_compare_info(
application_id, last_obj, application_entity, detect_list, data_source, ignore_bank=ignore_bank)
compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str, \
cn_failure_reason_str, bs_failure_reason_str, rpa_failure_reason, field_result_dict = se_compare_process(
compare_info, ocr_res_dict, is_gsyh, False, id_res_list, aa_type)
compare_info, ocr_res_dict, is_gsyh, False, id_res_list, aa_type, allow_bs_type)
compare_log.info('{0} [SE] [compare success] [entity={1}] [id={2}] [ocr_res_id={3}] [result={4}]'.format(
log_base, application_entity, application_id, ocr_res_id, compare_result))
except Exception as e:
......@@ -3327,6 +3759,24 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res
}
}
try:
compare_log.info('{0} [SE] [cms sleep start] [entity={1}] [id={2}] '.format(log_base, application_entity, application_id))
# 实时查询延迟时间
try:
cms_delay_time_config = Configs.objects.filter(id=5).first()
if cms_delay_time_config is not None and cms_delay_time_config.value is not None and cms_delay_time_config.value.isdigit():
cms_delay_time = cms_delay_time_config.value
else:
cms_delay_time = 0
except Exception as e:
cms_delay_time = 0
compare_log.info('[get cms_delay_time_config fail] [error={0}]'.format(traceback.format_exc()))
compare_log.info('cms_delay_time:{0}'.format(cms_delay_time))
try:
time.sleep(int(cms_delay_time))
except Exception as e:
compare_log.info('[sleep error] [error={0}]'.format(traceback.format_exc()))
compare_log.info('{0} [SE] [cms sleep end] [entity={1}] [id={2}] '.format(log_base, application_entity, application_id))
response = cms.send(data) # interface_report ocr to cms
except Exception as e:
is_success = False
......@@ -3358,9 +3808,60 @@ def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res
@app.task
def fsm_compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True, is_cms=False):
# try:
# producer_thread_fsm = threading.Thread(target=fsm_compare_thread, args=(application_id, application_entity, uniq_seq, ocr_res_id, is_ca, is_cms))
# producer_thread_fsm.start()
# except Exception as e:
# compare_log.info('[fsm thread error] [error={0}]'.format(traceback.format_exc()))
# with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
# # 使用map函数提交多个任务
# results = list(executor.map(fsm_compare_thread, application_id, application_entity, uniq_seq, ocr_res_id, is_ca, is_cms))
compare_log.info('[fsm thread]')
#pool = ThreadPoolExecutor(max_workers=6, thread_name_prefix="fsm_thread_")
try:
# 这个try不生效
pool.submit(fsm_compare_thread, application_id, application_entity, uniq_seq, ocr_res_id, is_ca, is_cms)
except Exception as e:
compare_log.info('[fsm thread fail] [error={0}]'.format(traceback.format_exc()))
#pool.shutdown(wait=True)
def fsm_compare_thread(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True, is_cms=False):
try:
compare_log.info('{0} [receive fsm task] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] [is_ca={5}] '
'[is_cms={6}]'.format(log_base, application_entity, application_id, uniq_seq, ocr_res_id,
is_ca, is_cms))
# 查看此订单号下是否有未完成的文件,如果有,等1分钟
try:
doc_wait_file_class = HILDoc if application_entity == consts.HIL_PREFIX else AFCDoc
doc_wait_file_result = doc_wait_file_class.objects.filter(application_id=application_id, status=1).first()
compare_log.info('doc_wait_file_result:{0}'.format(doc_wait_file_result))
compare_log.info('{0} [comparison unfinished file check] [entity={1}] [id={2}] [doc_wait_file_result={3}]'.format(log_base, application_entity, application_id, doc_wait_file_result))
except Exception as e:
doc_wait_file_result = None
compare_log.info('[get doc_wait_file_result fail] [error={0}]'.format(traceback.format_exc()))
if doc_wait_file_result is not None:
# 实时查询延迟时间
try:
delay_time_config = Configs.objects.filter(id=4).first()
if delay_time_config is not None and delay_time_config.value is not None and delay_time_config.value.isdigit():
delay_time = delay_time_config.value
else:
delay_time = 0
except Exception as e:
delay_time = 0
compare_log.info('[get delay_time_config fail] [error={0}]'.format(traceback.format_exc()))
compare_log.info('delay_time:{0}'.format(delay_time))
compare_log.info('{0} [comparison unfinished file wait delay_time start] [entity={1}] [id={2}] [doc_id={3}]'.format(log_base, application_entity, application_id, doc_wait_file_result.id))
try:
time.sleep(int(delay_time))
except Exception as e:
compare_log.info('[sleep error] [error={0}]'.format(traceback.format_exc()))
compare_log.info('{0} [comparison unfinished file wait delay_time end] [entity={1}] [id={2}] [doc_id={3}]'.format(log_base, application_entity, application_id, doc_wait_file_result.id))
# 调用java fsm 比对流程接口(http)
# 调用Java fsm 比对流程接口, fsm 是se流程, ca可以暂时忽略
auto_class = HILAutoSettlement if application_entity == consts.HIL_PREFIX else AFCAutoSettlement
......@@ -3389,13 +3890,35 @@ def fsm_compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=
except Exception as e:
compare_log.error("fsm full request to java error, url:{0}, param:{1}, errorMsg:{2}".format(
url, json.dumps(body), traceback.format_exc()))
except Exception as e:
compare_log.info('[fsm_compare_thread error] [error={0}]'.format(traceback.format_exc()))
@app.task
def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True, is_cms=False):
# try:
# producer_thread = threading.Thread(target=compare_thread, args=(application_id, application_entity, uniq_seq, ocr_res_id, is_ca, is_cms))
# producer_thread.start()
# except Exception as e:
# compare_log.info('[thread error] [error={0}]'.format(traceback.format_exc()))
# with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
# # 使用map函数提交多个任务
# results = list(executor.map(compare_thread, application_id, application_entity, uniq_seq, ocr_res_id, is_ca, is_cms))
compare_log.info('[non fsm thread]')
#pool = ThreadPoolExecutor(max_workers=6, thread_name_prefix="non_fsm_thread_")
try:
# 这个try不生效
pool.submit(compare_thread, application_id, application_entity, uniq_seq, ocr_res_id, is_ca, is_cms)
except Exception as e:
compare_log.info('[non fsm thread fail] [error={0}]'.format(traceback.format_exc()))
#pool.shutdown(wait=True)
def compare_thread(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True, is_cms=False):
# POS: application_id, application_entity, uniq_seq, None
# OCR: application_id, business_type(application_entity), None, ocr_res_id
try:
compare_log.info('{0} [receive task] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] [is_ca={5}] '
'[is_cms={6}]'.format(log_base, application_entity, application_id, uniq_seq, ocr_res_id,
is_ca, is_cms))
......@@ -3438,6 +3961,35 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True
uniq_seq, ocr_res_id, is_ca, is_cms))
return
# 查看此订单号下是否有未完成的文件,如果有,等?分钟
try:
doc_wait_file_class = HILDoc if application_entity == consts.HIL_PREFIX else AFCDoc
doc_wait_file_result = doc_wait_file_class.objects.filter(application_id=application_id, status=1).first()
compare_log.info('doc_wait_file_result:{0}'.format(doc_wait_file_result))
compare_log.info('{0} [comparison unfinished file check] [entity={1}] [id={2}] [doc_wait_file_result={3}]'.format(log_base, application_entity, application_id, doc_wait_file_result))
except Exception as e:
doc_wait_file_result = None
compare_log.info('[get doc_wait_file_result fail] [error={0}]'.format(traceback.format_exc()))
if doc_wait_file_result is not None:
# 实时查询延迟时间
try:
delay_time_config = Configs.objects.filter(id=4).first()
if delay_time_config is not None and delay_time_config.value is not None and delay_time_config.value.isdigit():
delay_time = delay_time_config.value
else:
delay_time = 0
except Exception as e:
delay_time = 0
compare_log.info('[get delay_time_config fail] [error={0}]'.format(traceback.format_exc()))
compare_log.info('delay_time:{0}'.format(delay_time))
compare_log.info('{0} [comparison unfinished file wait delay_time start] [entity={1}] [id={2}] [doc_id={3}]'.format(log_base, application_entity, application_id, doc_wait_file_result.id))
try:
time.sleep(int(delay_time))
except Exception as e:
compare_log.info('[sleep error] [error={0}]'.format(traceback.format_exc()))
compare_log.info('{0} [comparison unfinished file wait delay_time end] [entity={1}] [id={2}] [doc_id={3}]'.format(log_base, application_entity, application_id, doc_wait_file_result.id))
if is_ca:
ca_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res_dict)
else:
......@@ -3482,4 +4034,5 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True
compare_log.error('{0} [Auto SE] [result save error] [entity={1}] [id={2}] [ocr_res_id={3}] '
'[error={4}]'.format(log_base, application_entity, application_id, ocr_res_id,
traceback.format_exc()))
except Exception as e:
compare_log.info('[compare_thread error] [error={0}]'.format(traceback.format_exc()))
......
......@@ -19,10 +19,18 @@ class HMHRetriever:
def get_target_fields(self, pdf_text_list):
result = dict()
is_find_name_id_company, is_find_application_no, is_find_name_date = False, False, False
for bbox, text in pdf_text_list.pop(str(0), []):
# print(text)
# for bbox, text in pdf_text_list.pop(str(0), []):
pdf_text_items = pdf_text_list.pop(str(0), [])
for i in range(len(pdf_text_items)):
bbox, text = pdf_text_items[i]
combined_text = text
if i < len(pdf_text_items) - 1:
combined_text += pdf_text_items[i + 1][1]
if not is_find_name_id_company:
name_id_company_list = re.findall(r'姓名(.*)证件号码(.*)与(.*公司)', text)
# name_id_company_list = re.findall(r'姓名(.*?)证件号码(.*?)与(.*?公司|.*)', combined_text)
name_id_company_list = re.findall(r'姓名(.*)证件号码(.*)与(.*公司)', combined_text)
for name_id_company_tuple in name_id_company_list:
if len(name_id_company_tuple) == 3:
result[self.search_fields_list[0][0]] = {
......@@ -40,7 +48,7 @@ class HMHRetriever:
is_find_name_id_company = True
break
if not is_find_application_no:
application_no_list = re.findall(r'合同编号.*(CH-B\d*-\d*).*', text)
application_no_list = re.findall(r'合同编号.*(CH-B\d*-\d*).*', combined_text)
if len(application_no_list) == 1:
result[self.search_fields_list[3][0]] = {
self.words_str: application_no_list[0],
......@@ -48,7 +56,7 @@ class HMHRetriever:
}
is_find_application_no = True
if not is_find_name_date:
name_date_list = re.findall(r'(.*).*签署日期.*(\d{4}-\d{2}-\d{2})', text)
name_date_list = re.findall(r'(.*).*签署日期.*(\d{4}-\d{2}-\d{2})', combined_text)
for name_date_tuple in name_date_list:
if len(name_date_tuple) == 2:
result[self.search_fields_list[4][0]] = {
......
#这个有问题
from Crypto.Cipher import AES
from base64 import b64encode, b64decode
def encrypt_ecb(data, key):
data = data.encode()
key = key.encode()
aes = AES.new(key, AES.MODE_CBC, bytes(16))
res = aes.encrypt(pad(data, 32))
return b64encode(res).decode()
def decrypt(data, key, iv):
key = key.encode()
iv = iv.encode()
# aes = AES.new(key, AES.MODE_CBC, bytes(16))
aes = AES.new(key, AES.MODE_CBC, iv)
res = aes.decrypt(b64decode(data))
return unpad(res, 32).decode()
def unpad(padded_data, block_size, style='pkcs7'):
pdata_len = len(padded_data)
if pdata_len == 0:
raise ValueError("Zero-length input cannot be unpadded")
if pdata_len % block_size:
raise ValueError("Input data is not padded")
if style in ('pkcs7', 'x923'):
padding_len = bord(padded_data[-1])
if padding_len<1 or padding_len>min(block_size, pdata_len):
raise ValueError("Padding is incorrect.")
if style == 'pkcs7':
if padded_data[-padding_len:]!=bchr(padding_len)*padding_len:
raise ValueError("PKCS#7 padding is incorrect.")
else:
if padded_data[-padding_len:-1]!=bchr(0)*(padding_len-1):
raise ValueError("ANSI X.923 padding is incorrect.")
elif style == 'iso7816':
padding_len = pdata_len - padded_data.rfind(bchr(128))
if padding_len<1 or padding_len>min(block_size, pdata_len):
raise ValueError("Padding is incorrect.")
if padding_len>1 and padded_data[1-padding_len:]!=bchr(0)*(padding_len-1):
raise ValueError("ISO 7816-4 padding is incorrect.")
else:
raise ValueError("Unknown padding style")
return padded_data[:-padding_len]
def pad(data_to_pad, block_size, style='pkcs7'):
padding_len = block_size-len(data_to_pad)%block_size
if style == 'pkcs7':
padding = bchr(padding_len)*padding_len
elif style == 'x923':
padding = bchr(0)*(padding_len-1) + bchr(padding_len)
elif style == 'iso7816':
padding = bchr(128) + bchr(0)*(padding_len-1)
else:
raise ValueError("Unknown padding style")
return data_to_pad + padding
def bord(s):
return s
def bchr(s):
return bytes([s])
if __name__ == '__main__':
decrypt_data = decrypt('QkjNiuixpmtcxxqxaIZ30A==', 'm0XsOHC52YZ5KtakhpuMSZtF7DhwudmG', 'OCRocr2024UATocr')
print('解密:', decrypt_data)
\ No newline at end of file
from Crypto.Cipher import AES
from base64 import b64encode, b64decode
def aes_encrypt_cbc(data, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
return cipher.encrypt(data)
def aes_decrypt_cbc(data, key, iv):
res = ''
try:
cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
res = cipher.decrypt(b64decode(data))
res = res.decode('utf-8').replace('\x0e', '')
except Exception as e:
res = ''
return res
# 示例使用
key = 'm0XsOHC52YZ5KtakhpuMSZtF7DhwudmG' # 密钥长度必须是16、24或32字节
iv = 'OCRocr2024UATocr'
decrypted_data = aes_decrypt_cbc('QkjNiuixpmtcxxqxaIZ30A==', key, iv)
print("解密:", decrypted_data)
\ No newline at end of file
......@@ -12,6 +12,7 @@ import logging
compare_log = logging.getLogger('compare')
class Comparison:
def __init__(self):
......@@ -221,7 +222,7 @@ class Comparison:
for idx in range(len(src_str)):
if src_str[idx].isdigit():
replace_char_list.append(src_str[idx])
elif idx == len(src_str)-3:
elif idx == len(src_str) - 3:
replace_char_list.append('.')
return ''.join(replace_char_list)
......@@ -323,6 +324,9 @@ class Comparison:
return self.RESULT_Y
if kwargs.get('remove_space', False):
input_str = input_str.replace(' ', '')
if kwargs.get('remove_all_space', False):
input_str = input_str.replace(' ', '')
ocr_str = ocr_str.replace(' ', '')
if kwargs.get('brackets_replace', False):
input_str = input_str.translate(self.KH_TRANS)
ocr_str = ocr_str.translate(self.KH_TRANS)
......@@ -603,6 +607,33 @@ class Comparison:
except Exception as e:
return self.RESULT_N
def se_bd_date_2_compare(self, input_str, ocr_str, **kwargs):
try:
# Convert strings to date objects
ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d").date()
# Get today's date
today_date = datetime.today().date()
'''
开始时间<后天(不包含), 结束时间>昨天(不包含)
'''
if kwargs.get('start', False):
# 开始时间 < 后天(不包含)
day_after_tomorrow_date = today_date + relativedelta(days=2)
if ocr_date < day_after_tomorrow_date:
return self.RESULT_Y
else:
# 结束时间>昨天(不包含)
yesterday_date = today_date + relativedelta(days=-1)
if ocr_date > yesterday_date:
return self.RESULT_Y
# Default return value if conditions are not met
return self.RESULT_N
except Exception as e:
# Return RESULT_N in case of any exception
return self.RESULT_N
def se_bs_print_date_compare(self, input_str, ocr_str, **kwargs):
try:
input_date = datetime.strptime(input_str, "%Y-%m-%d")
......@@ -676,7 +707,58 @@ class Comparison:
except Exception as e:
return self.RESULT_N
def hash_code_compare(self, input_str, ocr_dict, **kwargs):
try:
balance_sheet_hash = ocr_dict.get('balance_sheet','')
income_statement_hash = ocr_dict.get('income_statement','')
cash_flow_statement_hash = ocr_dict.get('cash_flow_statement','')
if balance_sheet_hash != input_str or income_statement_hash != input_str or cash_flow_statement_hash != input_str:
return self.RESULT_N
else:
return self.RESULT_Y
except Exception as e:
return self.RESULT_N
cp = Comparison()
def stamp_dict_compare(self, input_str, ocr_dict, **kwargs):
try:
balance_sheet_stamp = ocr_dict.get('balance_sheet','')
income_statement_stamp = ocr_dict.get('income_statement','')
cash_flow_statement_stamp = ocr_dict.get('cash_flow_statement','')
if balance_sheet_stamp != 1 or income_statement_stamp != 1 or cash_flow_statement_stamp != 1:
return self.RESULT_N
else:
return self.RESULT_Y
except Exception as e:
return self.RESULT_N
def stamp_str_compare(self, input_str, ocr_str, **kwargs):
try:
if ocr_str != 1:
return self.RESULT_N
else:
return self.RESULT_Y
except Exception as e:
return self.RESULT_N
def fiscal_year_compare(self, input_str, ocr_list, **kwargs):
try:
this_year_str = datetime.now().strftime('%Y')
this_year = int(this_year_str)
last_year = this_year - 1
if str(input_str) != str(this_year) and str(input_str) != str(last_year):
return self.RESULT_N
return self.RESULT_Y
except Exception as e:
return self.RESULT_N
def input_list_not_zero_compare(self, input_list, ocr_list, **kwargs):
try:
for item in input_list:
if float(item) == 0:
return self.RESULT_N
return self.RESULT_Y
except Exception as e:
return self.RESULT_N
cp = Comparison()
......
import pyodbc
hil_sql = """
ALTER TABLE hil_ocr_result ADD fs_ocr nvarchar(max);
ALTER TABLE hil_se_ocr_result ADD fs_ocr nvarchar(max);
ALTER TABLE hil_ocr_result ADD fss_ocr nvarchar(max);
ALTER TABLE hil_se_ocr_result ADD fss_ocr nvarchar(max);
"""
afc_sql = """
ALTER TABLE afc_ocr_result ADD fs_ocr nvarchar(max);
ALTER TABLE afc_se_ocr_result ADD fs_ocr nvarchar(max);
ALTER TABLE afc_ocr_result ADD fss_ocr nvarchar(max);
ALTER TABLE afc_se_ocr_result ADD fss_ocr nvarchar(max);
"""
hil_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True)
hil_cursor = hil_cnxn.cursor()
hil_cursor.execute(hil_sql)
hil_cursor.close()
hil_cnxn.close()
afc_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True)
afc_cursor = afc_cnxn.cursor()
afc_cursor.execute(afc_sql)
afc_cursor.close()
afc_cnxn.close()
import pyodbc
hil_sql = """
ALTER TABLE hil_ocr_result ADD dp_ocr nvarchar(max);
ALTER TABLE hil_se_ocr_result ADD dp_ocr nvarchar(max);
"""
afc_sql = """
ALTER TABLE afc_ocr_result ADD dp_ocr nvarchar(max);
ALTER TABLE afc_se_ocr_result ADD dp_ocr nvarchar(max);
"""
hil_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True)
hil_cursor = hil_cnxn.cursor()
hil_cursor.execute(hil_sql)
hil_cursor.close()
hil_cnxn.close()
afc_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True)
afc_cursor = afc_cnxn.cursor()
afc_cursor.execute(afc_sql)
afc_cursor.close()
afc_cnxn.close()
import pyodbc
hil_sql = """
CREATE TABLE [dbo].[hil_gb_history_file] (
[id] int IDENTITY(1,1) NOT NULL,
[object_id] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[object_name] varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[application_no] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[object_type] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[customer_name] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[content_size] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[owner_name] varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[input_date] datetime NULL,
[modify_date] datetime NULL,
[location] varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[download_finish] int NOT NULL,
[update_time] datetime NULL,
[create_time] datetime NULL
)
GO;
alter table hil_gb_history_file ADD CONSTRAINT unique_object_id unique(object_id)
"""
afc_sql = """
CREATE TABLE [dbo].[afc_gb_history_file] (
[id] int IDENTITY(1,1) NOT NULL,
[object_id] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[object_name] varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[application_no] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[object_type] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[customer_name] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[content_size] varchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[owner_name] varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[input_date] datetime NULL,
[modify_date] datetime NULL,
[location] varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[download_finish] int NOT NULL,
[update_time] datetime NULL,
[create_time] datetime NULL
)
GO;
alter table afc_gb_history_file ADD CONSTRAINT unique_object_id unique(object_id)
"""
hil_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True)
hil_cursor = hil_cnxn.cursor()
hil_cursor.execute(hil_sql)
hil_cursor.close()
hil_cnxn.close()
afc_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True)
afc_cursor = afc_cnxn.cursor()
afc_cursor.execute(afc_sql)
afc_cursor.close()
afc_cnxn.close()
......@@ -100,9 +100,9 @@ DATABASES = {
for db_setting in DATABASES.values():
db_setting['OPTIONS'] = {
'driver': 'ODBC Driver 17 for SQL Server',
'extra_params': "odbc_cursortype=2"
'extra_params': "odbc_cursortype=2;TrustServerCertificate=yes;Encrypt=yes"
}
db_setting['CONN_MAX_AGE'] = 0
# set this to False if you want to turn off pyodbc's connection pooling
DATABASE_CONNECTION_POOLING = True
......
......@@ -16,3 +16,4 @@ BASE_URL = https://sfocr-prod.bmwgroup.net
DELAY_SECONDS = 60
BD_PRICE = 950
\ No newline at end of file
......
......@@ -15,3 +15,5 @@ DEALER_CODE = ocr_situ_group
BASE_URL = https://staging-bmw-ocr.situdata.com
DELAY_SECONDS = 60
BD_PRICE = 950
\ No newline at end of file
......
......@@ -15,3 +15,5 @@ DEALER_CODE = ocr_situ_group
BASE_URL = https://sfocr-uat.bmwgroup.net
DELAY_SECONDS = 60
BD_PRICE = 950
\ No newline at end of file
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!