802a919c by 周伟奇

fix merge

2 parents c61cf5a2 12a2684f
......@@ -6,4 +6,5 @@ urlpatterns = [
path(r'v1', views.CompareView.as_view()),
path(r'settlement/v1', views.SECompareView.as_view()),
path(r'offline/v1', views.CompareOfflineView.as_view()),
path(r'result', views.CompareResultView.as_view()),
]
......
......@@ -12,6 +12,7 @@ FIXED_APPLICATION_ID_PREFIX = 'CH-S'
DOC_SCHEME_LIST = ['ACCEPTANCE', 'SETTLEMENT', 'CONTRACTMANAGEMENT']
DATA_SOURCE_LIST = ['POS', 'EAPP', 'ECONTRACT']
COMPARE_DOC_SCHEME_LIST = ['CA', 'SE']
HIL_PREFIX = 'HIL'
AFC_PREFIX = 'AFC'
......@@ -1055,13 +1056,13 @@ IC_RES_MAPPING = {
1: '真实证件',
}
# ----------------- compare ---------------------
# ----------------- CA compare ---------------------
ENTITY = ['HIL', 'AFC']
CUSTOMER_TYPE = ['TCCOR', 'TCDAS', 'TCFRE', 'TCIAS', 'TCIND', 'TCSEP', 'TCURE']
NO_COMPARE_CUSTOMER_TYPE = ['TCFRE', 'TCIND']
VEHICLE_STATUS = ['PCUSD', 'PCNEW']
APPLICANT_TYPE = ['COAPP', 'CUSTR', 'GAUTR1', 'GAUTR2']
APPLICANT_TYPE = ['CUSTR', 'COAPP', 'GAUTR1', 'GAUTR2']
ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID', 'ITUSC', 'ITCCU']
SECOND_ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID']
SUB_TYPE = ['CSIBM', 'CSOTH', 'CSSME']
......@@ -1087,22 +1088,38 @@ EEP_OCR_FIELD = 'eep_ocr'
DL_OCR_FIELD = 'dl_ocr'
PP_OCR_FIELD = 'pp_ocr'
MVC_OCR_FIELD = 'mvc_ocr'
MVI_OCR_FIELD = 'mvi_ocr'
BC_OCR_FIELD = 'bc_ocr'
UCI_OCR_FIELD = 'uci_ocr'
DDA_OCR_FIELD = 'bs_ocr'
RESULT_MAPPING = {
# MVI_CLASSIFY: 'mvi_ocr',
MVI_CLASSIFY: MVI_OCR_FIELD,
IC_CLASSIFY: IC_OCR_FIELD,
RP_CLASSIFY: RP_OCR_FIELD,
# BC_CLASSIFY: 'bc_ocr',
BC_CLASSIFY: BC_OCR_FIELD,
BL_CLASSIFY: BL_OCR_FIELD,
# UCI_CLASSIFY: 'uci_ocr',
UCI_CLASSIFY: UCI_OCR_FIELD,
EEP_CLASSIFY: EEP_OCR_FIELD,
DL_CLASSIFY: DL_OCR_FIELD,
PP_CLASSIFY: PP_OCR_FIELD,
MVC_CLASSIFY: MVC_OCR_FIELD,
DDA_CLASSIFY: DDA_OCR_FIELD,
# VAT_CLASSIFY: 'vat_ocr',
}
COMPARE_FIELDS = (IC_OCR_FIELD, RP_OCR_FIELD, BL_OCR_FIELD, EEP_OCR_FIELD, DL_OCR_FIELD, PP_OCR_FIELD, MVC_OCR_FIELD)
COMPARE_FIELDS = (MVI_OCR_FIELD,
IC_OCR_FIELD,
RP_OCR_FIELD,
BC_OCR_FIELD,
BL_OCR_FIELD,
UCI_OCR_FIELD,
EEP_OCR_FIELD,
DL_OCR_FIELD,
PP_OCR_FIELD,
MVC_OCR_FIELD,
DDA_OCR_FIELD,
)
# 身份证
ITPRC = [
......@@ -1253,5 +1270,167 @@ DDA_MAPPING = [
DDA_PRO_MIN = 0.6
# ----------------------- SE compare -----------------------
SE_FIRST_ID_FIELD = ['customerName', 'idNum', 'dateOfBirth', 'idExpiryDate']
SE_ID_CARD_FIELD = ['customerName', 'idNum', 'dateOfBirth', 'idExpiryDate', 'hukouProvince', 'hukouCity']
SE_SECOND_ID_FIELD = [
('customerName', 'customerName'),
('secondIdNum', 'idNum'),
]
SE_CORPORATE_ID_FIELD = [
('legalRepName', 'customerName'),
('firstIdNo', 'idNum')
]
SE_SEP_FIELD = [
('companyName', 'companyName'),
('customerName', 'legalRepName'),
('registeredCapital', 'registeredCapital'),
('selfEmployedSubType', 'organizationType')
]
SE_CORPORATE_FIELD = ['companyName', 'legalRepName', 'businessLicenseNo', 'organizationCreditCode',
'taxRegistrationCertificateNo', 'establishmentDate', 'businessLicenseDueDate']
SE_CORPORATE_ALL_FIELD = ['companyName', 'legalRepName', 'firstIdNo', 'businessLicenseNo', 'organizationCreditCode',
'taxRegistrationCertificateNo', 'establishmentDate', 'businessLicenseDueDate']
SE_NEW_FIELD = ['vinNo', 'dealer', 'vehicleTransactionAmount']
SE_USED_FIELD = ['vinNo', 'vehicleTransactionAmount']
SE_NEW_ADD_FIELD = ['customerName', 'idNum', 'dateOfInvoice']
SE_GB_NEW_FIELD = ['vinNo']
SE_GB_USED_FIELD = ['customerName', 'idNum', 'date']
SE_BANK_FIELD = ['accountNo', 'bankName']
SE_DDA_FIELD = ['applicationId(1)', 'applicationId(2)', 'bankName', 'companyName', 'customerName', 'idNum', 'accountHolderName', 'accountNo']
HIL_COMPANY_NAME = '先锋国际融资租赁有限公司'
AFC_COMPANY_NAME = '宝马汽车金融(中国)有限公司'
ID_EN = 'PRC ID'
PP_EN = 'Passport'
EEP_EN = 'Resident Permit to Mainland'
RP_EN = 'Resident ID'
BL_EN = 'Business permit'
MVI_EN = 'newCar Invoice'
UCI_EN = 'usedCar Invoice'
MVC_EN = 'Green Book'
BC_EN = 'Bank Card'
DDA_EN = 'DDA'
ID_COMPARE_LOGIC = {
'customerName': ('姓名', 'se_name_compare', {}),
'idNum': ('公民身份号码', 'se_common_compare', {}),
'dateOfBirth': ('出生年月', 'se_date_compare', {'input_replace': ''}),
'idExpiryDate': ('有效期限', 'se_date_compare', {'long': True, 'ocr_split': True, 'input_replace': ''}),
'hukouProvince': ('住址', 'se_contain_compare', {}),
'hukouCity': ('住址', 'se_contain_compare', {}),
}
PP_COMPARE_LOGIC = {
'customerName': ('英文姓名', 'se_name_compare', {'is_passport': True}),
'idNum': ('护照号码', 'se_common_compare', {}),
'dateOfBirth': ('出生日期', 'se_date_compare', {'input_replace': ''}),
'idExpiryDate': ('有效期至', 'se_date_compare', {'input_replace': ''}),
}
EEP_COMPARE_LOGIC = {
'customerName': ('中文名', 'se_common_compare', {}),
'idNum': ('证件号码', 'se_common_compare', {}),
'dateOfBirth': ('出生日期', 'se_date_compare', {'input_replace': '.'}),
'idExpiryDate': ('有效期限', 'se_date_compare', {'ocr_split': True, 'input_replace': '.'}),
}
RP_COMPARE_LOGIC = {
'customerName': ('姓名', 'se_name_compare', {}),
'idNum': ('公民身份号码', 'se_common_compare', {}),
'dateOfBirth': ('出生年月', 'se_date_compare', {'input_replace': ''}),
'idExpiryDate': ('有效期限', 'se_date_compare', {'ocr_split': True, 'input_replace': ''}),
'hukouProvince': ('住址', 'se_contain_compare', {}),
'hukouCity': ('住址', 'se_contain_compare', {}),
}
BL_COMPARE_LOGIC = {
'companyName': ('企业名称', 'se_company_compare', {}),
'legalRepName': ('经营者姓名', 'se_name_compare', {}),
'firstIdNo': ('注册号', 'se_common_compare', {}),
'businessLicenseNo': ('注册号', 'se_common_compare', {}),
'organizationCreditCode': ('注册号', 'se_common_compare', {}),
'taxRegistrationCertificateNo': ('注册号', 'se_common_compare', {}),
'establishmentDate': ('成立日期', 'se_date_compare', {'ocr_replace': True}),
'businessLicenseDueDate': ('营业期限', 'se_date_compare', {'ocr_split': True, 'long': True, 'ocr_replace': True}),
'organizationType': ('企业类型', 'se_type_compare', {}),
'registeredCapital': ('注册资本', 'se_rmb_compare', {}),
}
MVI_COMPARE_LOGIC = {
'vinNo': ('车辆识别代码', 'se_common_compare', {}),
'dealer': ('销方名称', 'se_common_compare', {}),
'vehicleTransactionAmount': ('价税合计小写', 'se_amount_compare', {}),
'customerName': ('购方名称', 'se_name_compare', {}),
'idNum': ('购买方身份证号或组织机构代码', 'se_common_compare', {}),
'dateOfInvoice': ('开票日期', 'se_date_compare', {}),
}
UCI_COMPARE_LOGIC = {
'vinNo': ('车架号', 'se_common_compare', {}),
'vehicleTransactionAmount': ('价税合计小写', 'se_amount_compare', {}),
'customerName': ('购方名称', 'se_name_compare', {}),
'idNum': ('购方纳税人识别号', 'se_common_compare', {}),
}
MVC_COMPARE_LOGIC = {
'vinNo': ('9.车辆识别代号/车架号', 'se_common_compare', {}),
# 'customerName': ('姓名/名称', ),
# 'idNum': ('身份证明名称/号码', ),
# 'date': ('转移登记日期', ),
}
BC_COMPARE_LOGIC = {
'accountNo': ('CardNum', 'se_common_compare', {}),
'bankName': ('BankName', 'se_common_compare', {}),
}
DDA_COMPARE_LOGIC = {
'applicationId(1)': ('check_Num', ),
'applicationId(2)': ('check_Num', ),
'bankName': ('to_bank', ),
'companyName': ('to_company', ),
'customerName': (DDA_IC_NAME, ),
'idNum': (DDA_IC_ID, ),
'accountHolderName': (DDA_BC_NAME, ),
'accountNo': (DDA_BC_ID, ),
}
# MVC_OCR_FIELD = 'mvc_ocr'
SE_COMPARE_FIELD = {
ID_EN: (IC_OCR_FIELD, ID_COMPARE_LOGIC, True),
PP_EN: (PP_OCR_FIELD, PP_COMPARE_LOGIC, False),
EEP_EN: (EEP_OCR_FIELD, EEP_COMPARE_LOGIC, False),
RP_EN: (RP_OCR_FIELD, RP_COMPARE_LOGIC, True),
BL_EN: (BL_OCR_FIELD, BL_COMPARE_LOGIC, False),
MVI_EN: (MVI_OCR_FIELD, MVI_COMPARE_LOGIC, False),
UCI_EN: (UCI_OCR_FIELD, UCI_COMPARE_LOGIC, False),
MVC_EN: (MVC_OCR_FIELD, MVC_COMPARE_LOGIC, False),
BC_EN: (BC_OCR_FIELD, BC_COMPARE_LOGIC, False),
DDA_EN: (DDA_OCR_FIELD, DDA_COMPARE_LOGIC, False),
}
SE_FIRST_ID_FIELD_MAPPING = {
'ITPRC': (ID_EN, SE_ID_CARD_FIELD),
'ITPSP': (PP_EN, SE_FIRST_ID_FIELD),
'ITHKM': (EEP_EN, SE_FIRST_ID_FIELD),
'ITTID': (EEP_EN, SE_FIRST_ID_FIELD),
'ITRES': (RP_EN, SE_FIRST_ID_FIELD),
}
SE_SECOND_ID_FIELD_MAPPING = {
'ITPRC': (ID_EN, SE_SECOND_ID_FIELD),
'ITPSP': (PP_EN, SE_SECOND_ID_FIELD),
'ITHKM': (EEP_EN, SE_SECOND_ID_FIELD),
'ITTID': (EEP_EN, SE_SECOND_ID_FIELD),
'ITRES': (RP_EN, SE_SECOND_ID_FIELD),
}
HEAD_LIST = ['Info', 'Index', 'License', 'Field', 'Input', 'OCR', 'Result', 'Position', 'Image', 'errorType']
......
......@@ -23,7 +23,21 @@ from apps.doc.ocr.edms import EDMS, rh
from apps.doc.named_enum import KeywordsType, FailureReason, WorkflowName, ProcessName, RequestTeam, RequestTrigger
from apps.doc.exceptions import EDMSException, OCR1Exception, OCR2Exception, OCR4Exception
from apps.doc.ocr.wb import BSWorkbook
from apps.doc.models import DocStatus, HILDoc, AFCDoc, Keywords, HILOCRResult, AFCOCRResult, HILOCRReport, AFCOCRReport, DDARecords, IDBCRecords, Configs
from apps.doc.models import (
DocStatus,
HILDoc,
AFCDoc,
Keywords,
HILOCRResult,
AFCOCRResult,
AFCSEOCRResult,
HILOCRReport,
HILSEOCRResult,
AFCOCRReport,
DDARecords,
IDBCRecords,
Configs,
)
from celery_compare.tasks import compare
......@@ -990,16 +1004,22 @@ class Command(BaseCommand, LoggerMixin):
finally:
# TODO 识别结果存一张表,方便跑报表
# CA比对
if doc.document_scheme == consts.DOC_SCHEME_LIST[0] and len(license_summary) > 0:
# 比对
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累计识别结果表
result_class = HILOCRResult if business_type == consts.HIL_PREFIX else AFCOCRResult
if business_type == consts.HIL_PREFIX:
result_class = HILOCRResult if is_ca else HILSEOCRResult
else:
result_class = AFCOCRResult if is_ca else AFCSEOCRResult
res_obj = result_class.objects.filter(application_id=doc.application_id).first()
if res_obj is None:
res_obj = result_class()
res_obj.application_id = doc.application_id
for classify, field in consts.RESULT_MAPPING.items():
if not hasattr(res_obj, field):
continue
license_list = license_summary.get(classify)
if not license_list:
continue
......@@ -1009,8 +1029,6 @@ class Command(BaseCommand, LoggerMixin):
elif classify == consts.RP_CLASSIFY and rp_merge:
license_list[0].update(license_list[1])
license_list.pop(1)
if not hasattr(res_obj, field):
continue
old_res_str = getattr(res_obj, field)
if old_res_str is None:
last_res_str = json.dumps(license_list)
......@@ -1030,8 +1048,8 @@ class Command(BaseCommand, LoggerMixin):
# 触发比对
try:
# pass
compare.apply_async((doc.application_id, business_type, None, res_obj.id),
queue='queue_compare')
compare.apply_async((doc.application_id, business_type, None, res_obj.id,
is_ca), queue='queue_compare')
except Exception as e:
self.online_log.error(
'{0} [process error (comparison info send)] [task={1}] [error={2}]'.format(
......
......@@ -190,6 +190,58 @@ class AFCComparisonInfo(models.Model):
db_table = 'afc_comparison_info'
situ_db_label = 'afc'
# 比对信息表
class AFCSEComparisonInfo(models.Model):
id = models.BigAutoField(primary_key=True, verbose_name="id") # 主键
uniq_seq = models.CharField(max_length=128, verbose_name="唯一序列号") # 索引
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
application_version = models.SmallIntegerField(default=0, verbose_name="应用版本")
# CUSTOMER_TYPE = ['TCCOR', 'TCDAS', 'TCFRE', 'TCIAS', 'TCIND', 'TCSEP', 'TCURE']
customer_type = models.CharField(max_length=16, verbose_name="顾客类型")
first_submmison_date = models.CharField(max_length=16, verbose_name="首次提交时间")
property_doc_policy = models.CharField(null=True, max_length=16, verbose_name="申请及文件政策")
individual_cus_info = models.TextField(verbose_name="个人信息")
corporate_cus_info = models.TextField(null=True, verbose_name="公司信息")
vehicle_info = models.TextField(verbose_name="车辆信息")
insurance_info = models.TextField(verbose_name="保险信息")
bank_info = models.TextField(verbose_name="银行信息")
quotationt_info = models.TextField(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_se_comparison_info'
situ_db_label = 'afc'
# 比对信息表
class HILSEComparisonInfo(models.Model):
id = models.BigAutoField(primary_key=True, verbose_name="id") # 主键
uniq_seq = models.CharField(max_length=128, verbose_name="唯一序列号") # 索引
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
application_version = models.SmallIntegerField(default=0, verbose_name="应用版本")
# CUSTOMER_TYPE = ['TCCOR', 'TCDAS', 'TCFRE', 'TCIAS', 'TCIND', 'TCSEP', 'TCURE']
customer_type = models.CharField(max_length=16, verbose_name="顾客类型")
first_submmison_date = models.CharField(max_length=16, verbose_name="首次提交时间")
property_doc_policy = models.CharField(null=True, max_length=16, verbose_name="申请及文件政策")
individual_cus_info = models.TextField(verbose_name="个人信息")
corporate_cus_info = models.TextField(null=True, verbose_name="公司信息")
vehicle_info = models.TextField(verbose_name="车辆信息")
insurance_info = models.TextField(verbose_name="保险信息")
bank_info = models.TextField(verbose_name="银行信息")
quotationt_info = models.TextField(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_se_comparison_info'
# 比对信息表
class HILComparisonInfo(models.Model):
......@@ -220,7 +272,7 @@ class AFCOCRResult(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
bs_ocr = models.TextField(null=True, verbose_name="银行流水")
bs_ocr = models.TextField(null=True, verbose_name="DDA")
mvi_ocr = models.TextField(null=True, verbose_name="机动车销售统一发票")
ic_ocr = models.TextField(null=True, verbose_name="身份证")
rp_ocr = models.TextField(null=True, verbose_name="居住证")
......@@ -247,7 +299,7 @@ class HILOCRResult(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
bs_ocr = models.TextField(null=True, verbose_name="银行流水")
bs_ocr = models.TextField(null=True, verbose_name="DDA")
mvi_ocr = models.TextField(null=True, verbose_name="机动车销售统一发票")
ic_ocr = models.TextField(null=True, verbose_name="身份证")
rp_ocr = models.TextField(null=True, verbose_name="居住证")
......@@ -268,6 +320,59 @@ class HILOCRResult(models.Model):
db_table = 'hil_ocr_result'
# OCR结果累计表
class AFCSEOCRResult(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
bs_ocr = models.TextField(null=True, verbose_name="DDA")
mvi_ocr = models.TextField(null=True, verbose_name="机动车销售统一发票")
ic_ocr = models.TextField(null=True, verbose_name="身份证")
rp_ocr = models.TextField(null=True, verbose_name="居住证")
bc_ocr = models.TextField(null=True, verbose_name="银行卡")
bl_ocr = models.TextField(null=True, verbose_name="营业执照")
uci_ocr = models.TextField(null=True, verbose_name="二手车发票")
eep_ocr = models.TextField(null=True, verbose_name="港澳台通行证")
dl_ocr = models.TextField(null=True, verbose_name="行驶证")
pp_ocr = models.TextField(null=True, verbose_name="护照")
mvc_ocr = models.TextField(null=True, verbose_name="机动车登记证")
vat_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='创建时间')
class Meta:
managed = False
db_table = 'afc_se_ocr_result'
situ_db_label = 'afc'
# OCR结果累计表
class HILSEOCRResult(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
bs_ocr = models.TextField(null=True, verbose_name="DDA")
mvi_ocr = models.TextField(null=True, verbose_name="机动车销售统一发票")
ic_ocr = models.TextField(null=True, verbose_name="身份证")
rp_ocr = models.TextField(null=True, verbose_name="居住证")
bc_ocr = models.TextField(null=True, verbose_name="银行卡")
bl_ocr = models.TextField(null=True, verbose_name="营业执照")
uci_ocr = models.TextField(null=True, verbose_name="二手车发票")
eep_ocr = models.TextField(null=True, verbose_name="港澳台通行证")
dl_ocr = models.TextField(null=True, verbose_name="行驶证")
pp_ocr = models.TextField(null=True, verbose_name="护照")
mvc_ocr = models.TextField(null=True, verbose_name="机动车登记证")
vat_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='创建时间')
class Meta:
managed = False
db_table = 'hil_se_ocr_result'
# OCR Report
class HILOCRReport(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
......@@ -437,3 +542,105 @@ class IDBCRecords(models.Model):
db_table = 'idbc_records'
class AFCSECompareResult(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
is_finish = models.BooleanField(default=False, verbose_name="是否完成")
compare_count = models.SmallIntegerField(default=0, verbose_name="比对字段总数")
failed_count = models.SmallIntegerField(default=0, verbose_name="比对失败数目")
reason1_count = models.SmallIntegerField(default=0, verbose_name="原因1数目")
reason2_count = models.SmallIntegerField(default=0, verbose_name="原因2数目")
reason3_count = models.SmallIntegerField(default=0, verbose_name="原因3数目")
reason4_count = models.SmallIntegerField(default=0, verbose_name="原因4数目")
reason5_count = models.SmallIntegerField(default=0, verbose_name="原因5数目")
reason6_count = models.SmallIntegerField(default=0, verbose_name="原因6数目")
reason7_count = models.SmallIntegerField(default=0, verbose_name="原因7数目")
reason8_count = models.SmallIntegerField(default=0, verbose_name="原因8数目")
reason9_count = models.SmallIntegerField(default=0, verbose_name="原因9数目")
reason10_count = models.SmallIntegerField(default=0, verbose_name="原因10数目")
result = 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='创建时间')
class Meta:
managed = False
db_table = 'afc_se_compare_result'
situ_db_label = 'afc'
class AFCCACompareResult(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
is_finish = models.BooleanField(default=False, verbose_name="是否完成")
compare_count = models.SmallIntegerField(default=0, verbose_name="比对字段总数")
failed_count = models.SmallIntegerField(default=0, verbose_name="比对失败数目")
reason1_count = models.SmallIntegerField(default=0, verbose_name="原因1数目")
reason2_count = models.SmallIntegerField(default=0, verbose_name="原因2数目")
reason3_count = models.SmallIntegerField(default=0, verbose_name="原因3数目")
reason4_count = models.SmallIntegerField(default=0, verbose_name="原因4数目")
reason5_count = models.SmallIntegerField(default=0, verbose_name="原因5数目")
reason6_count = models.SmallIntegerField(default=0, verbose_name="原因6数目")
reason7_count = models.SmallIntegerField(default=0, verbose_name="原因7数目")
reason8_count = models.SmallIntegerField(default=0, verbose_name="原因8数目")
reason9_count = models.SmallIntegerField(default=0, verbose_name="原因9数目")
reason10_count = models.SmallIntegerField(default=0, verbose_name="原因10数目")
result = 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='创建时间')
class Meta:
managed = False
db_table = 'afc_ca_compare_result'
situ_db_label = 'afc'
class HILSECompareResult(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
is_finish = models.BooleanField(default=False, verbose_name="是否完成")
compare_count = models.SmallIntegerField(default=0, verbose_name="比对字段总数")
failed_count = models.SmallIntegerField(default=0, verbose_name="比对失败数目")
reason1_count = models.SmallIntegerField(default=0, verbose_name="原因1数目")
reason2_count = models.SmallIntegerField(default=0, verbose_name="原因2数目")
reason3_count = models.SmallIntegerField(default=0, verbose_name="原因3数目")
reason4_count = models.SmallIntegerField(default=0, verbose_name="原因4数目")
reason5_count = models.SmallIntegerField(default=0, verbose_name="原因5数目")
reason6_count = models.SmallIntegerField(default=0, verbose_name="原因6数目")
reason7_count = models.SmallIntegerField(default=0, verbose_name="原因7数目")
reason8_count = models.SmallIntegerField(default=0, verbose_name="原因8数目")
reason9_count = models.SmallIntegerField(default=0, verbose_name="原因9数目")
reason10_count = models.SmallIntegerField(default=0, verbose_name="原因10数目")
result = 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='创建时间')
class Meta:
managed = False
db_table = 'hil_se_compare_result'
class HILCACompareResult(models.Model):
id = models.AutoField(primary_key=True, verbose_name="id") # 主键
application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引
is_finish = models.BooleanField(default=False, verbose_name="是否完成")
compare_count = models.SmallIntegerField(default=0, verbose_name="比对字段总数")
failed_count = models.SmallIntegerField(default=0, verbose_name="比对失败数目")
reason1_count = models.SmallIntegerField(default=0, verbose_name="原因1数目")
reason2_count = models.SmallIntegerField(default=0, verbose_name="原因2数目")
reason3_count = models.SmallIntegerField(default=0, verbose_name="原因3数目")
reason4_count = models.SmallIntegerField(default=0, verbose_name="原因4数目")
reason5_count = models.SmallIntegerField(default=0, verbose_name="原因5数目")
reason6_count = models.SmallIntegerField(default=0, verbose_name="原因6数目")
reason7_count = models.SmallIntegerField(default=0, verbose_name="原因7数目")
reason8_count = models.SmallIntegerField(default=0, verbose_name="原因8数目")
reason9_count = models.SmallIntegerField(default=0, verbose_name="原因9数目")
reason10_count = models.SmallIntegerField(default=0, verbose_name="原因10数目")
result = 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='创建时间')
class Meta:
managed = False
db_table = 'hil_ca_compare_result'
......
......@@ -51,6 +51,7 @@ class ProcessName(NamedEnum):
IDCARD = (2, 'F2_IDReport')
DDA = (3, 'CL_S1_DDAConsolidation')
CACOMPARE = (4, 'S1_CA_DocumentVerify')
SE_CACOMPARE = (5, 'S1_SE_DocumentVerify')
class WorkflowName(NamedEnum):
......
......@@ -6,7 +6,7 @@ import datetime
import fitz
import shutil
from django.utils import timezone
from django.db.utils import IntegrityError
from django.http import HttpResponse
from django.db.models import Q
from rest_framework.permissions import IsAuthenticated
from webargs import fields, validate
......@@ -16,7 +16,21 @@ from common import response
from common.mixins import GenericView
from common.tools.file_tools import file_write
from common.redis_cache import redis_handler as rh
from .models import DocStatus, PriorityApplication, GCAPRecords, AFCComparisonInfo, HILComparisonInfo, AFCCompareOfflineReport, HILCompareOfflineReport
from .models import (
DocStatus,
PriorityApplication,
GCAPRecords,
AFCComparisonInfo,
AFCSEComparisonInfo,
HILComparisonInfo,
HILSEComparisonInfo,
AFCCompareOfflineReport,
HILCompareOfflineReport,
AFCCACompareResult,
AFCSECompareResult,
HILCACompareResult,
HILSECompareResult,
)
from .mixins import DocHandler
from . import consts
from apps.account.authentication import OAuth2AuthenticationWithUser
......@@ -257,6 +271,13 @@ doc_list_args = {
'create_time_end': fields.Date(required=False),
}
compare_result_args = {
'entity': fields.Str(required=True, validate=validate.OneOf(consts.BUSINESS_TYPE_LIST)),
'scheme': fields.Str(required=True, validate=validate.OneOf(consts.COMPARE_DOC_SCHEME_LIST)),
'id': fields.Int(required=False, validate=lambda val: val >= 1),
'case_id': fields.Str(required=True, validate=validate.Length(max=64)),
}
upload_pdf_args = {
'pdf_file': fields.Raw(required=True),
}
......@@ -474,7 +495,8 @@ class CompareView(GenericView):
corporate_cus_info=corporate_cus_info,
)
# 触发比对
compare.apply_async((application_id, business_type, uniq_seq, None), queue='queue_compare')
compare.apply_async((application_id, business_type, uniq_seq, None, True),
queue='queue_compare')
return response.ok()
post.openapi_doc = '''
......@@ -504,7 +526,38 @@ class SECompareView(GenericView):
# pos上传比对信息接口 SE
@use_args(se_compare_args, location='data')
def post(self, request, args):
self.running_log.info('se compare in')
# 存库
content = args.get('content', {})
uniq_seq = content.get('uniqSeq')
business_type = content.get('applicationEntity')
application_id = content.get('applicationId')
individual_cus_info = json.dumps(content.get('individualCusInfo'))
vehicle_info = json.dumps(content.get('vehicleInfo'))
insurance_info = json.dumps(content.get('insuranceInfo'))
bank_info = json.dumps(content.get('bankInfo'))
quotationt_info = json.dumps(content.get('quotationtInfo'))
corporate_cus_info = json.dumps(content.get('corporateCusInfo')) if isinstance(
content.get('corporateCusInfo'), dict) else None
comparison_class = HILSEComparisonInfo if business_type in consts.HIL_SET else AFCSEComparisonInfo
comparison_class.objects.create(
uniq_seq=uniq_seq,
application_id=application_id,
application_version=content.get('applicationVersion'),
customer_type=content.get('customerType'),
first_submmison_date=content.get('firstSubmmisonDate'),
property_doc_policy=content.get('propertyDocumentPolicy', None),
individual_cus_info=individual_cus_info,
corporate_cus_info=corporate_cus_info,
vehicle_info=vehicle_info,
insurance_info=insurance_info,
bank_info=bank_info,
quotationt_info=quotationt_info
)
# 触发比对
compare.apply_async((application_id, business_type, uniq_seq, None, False),
queue='queue_compare')
return response.ok()
post.openapi_doc = '''
......@@ -695,3 +748,59 @@ class DocView(GenericView, DocHandler):
is_priority, enqueue_res))
data = {'excel_path': os.path.join(save_dir_path, '{0}.xlsx'.format(doc.id))}
return response.ok(data=data)
class CompareResultView(GenericView):
# 获取比对结果
@use_args(compare_result_args, location='querystring')
def get(self, request, args):
result_id = args.get('id', None)
entity = args.get('entity')
scheme = args.get('scheme')
case_id = args.get('case_id')
if entity == consts.HIL_PREFIX:
result_table = HILCACompareResult if scheme == consts.COMPARE_DOC_SCHEME_LIST[0] else HILSECompareResult
else:
result_table = AFCCACompareResult if scheme == consts.COMPARE_DOC_SCHEME_LIST[0] else AFCSECompareResult
if result_id is None:
result_str_list = result_table.objects.filter(id=result_id).values_list('result', flat=True)
else:
result_str_list = result_table.objects.filter(application_id=case_id).values_list('result', flat=True)
if len(result_str_list) == 0:
compare_result_list = []
else:
compare_result_list = json.loads(result_str_list[0])
if len(compare_result_list) == 0:
body_html = "<h1>没有比对结果</h1>"
else:
head_content = ''.join(['<th>{0}</th>'.format(head_name) for head_name in consts.HEAD_LIST])
head_html = '<tr>{0}</tr>'.format(head_content)
row_html_list = []
for row_dict in compare_result_list:
row_list = [row_dict.get(head, '') for head in consts.HEAD_LIST]
row_content = ''.join(['<td>{0}</td>'.format(row_str) for row_str in row_list])
row_html = '<tr>{0}</tr>'.format(row_content)
row_html_list.append(row_html)
content_html = ''.join(row_html_list)
body_html = '<table border="1">{0}{1}</table>'.format(head_html, content_html)
html = """
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>比对结果</title>
</head>
<body>
{0}
</body>
</html>
""".format(body_html)
return HttpResponse(html)
# return response.ok(data=compare_result)
......
......@@ -5,7 +5,21 @@ import traceback
from datetime import datetime, timedelta
from collections import OrderedDict
from . import app
from apps.doc.models import AFCOCRResult, HILOCRResult, AFCComparisonInfo, HILComparisonInfo, Configs, HILCompareReport, AFCCompareReport
from apps.doc.models import (
AFCOCRResult,
AFCSEOCRResult,
HILOCRResult,
HILSEOCRResult,
AFCComparisonInfo,
AFCSEComparisonInfo,
HILComparisonInfo,
HILSEComparisonInfo,
Configs,
HILCompareReport,
AFCCompareReport,
AFCSECompareResult,
HILSECompareResult,
)
from apps.doc import consts
from apps.doc.ocr.gcap import gcap
from apps.doc.exceptions import GCAPException
......@@ -181,34 +195,7 @@ def usedcar_info_compare(info_dict, ocr_res_dict, ocr_field, compare_list, res_s
return is_find and key_right, no_match_vino
@app.task
def compare(application_id, application_entity, uniq_seq, ocr_res_id):
# POS: application_id, application_entity, uniq_seq, None
# OCR: application_id, business_type(application_entity), None, ocr_res_id
compare_log.info('{0} [receive task] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}]'.format(
log_base, application_entity, application_id, uniq_seq, ocr_res_id))
# 根据application_id查找最新的比对信息,如果没有,结束
comparison_class = HILComparisonInfo if application_entity == consts.HIL_PREFIX else AFCComparisonInfo
last_obj = comparison_class.objects.filter(application_id=application_id).last()
if last_obj is None:
compare_log.info('{0} [comparison info empty] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}]'.format(
log_base, application_entity, application_id, uniq_seq, ocr_res_id))
return
# 根据application_id查找OCR累计结果指定license字段,如果没有,结束
result_class = HILOCRResult if application_entity == consts.HIL_PREFIX else AFCOCRResult
if ocr_res_id is None:
ocr_res_dict = result_class.objects.filter(application_id=application_id).values(*consts.COMPARE_FIELDS).first()
else:
ocr_res_dict = result_class.objects.filter(id=ocr_res_id).values(*consts.COMPARE_FIELDS).first()
if ocr_res_dict is None:
compare_log.info('{0} [ocr info empty] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}]'.format(
log_base, application_entity, application_id, uniq_seq, ocr_res_id
))
return
def ca_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res_dict):
start_time = datetime.now()
compare_failed = False
......@@ -339,38 +326,36 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id):
comparison_res['OCR_Input']['corporateCusInfo'] = order_corporate_cus_info
comparison_res['OCR_Input']['wholeResult'] = consts.RESULT_N if consts.RESULT_N in res_set or consts.RESULT_NA in res_set else consts.RESULT_Y
comparison_res['OCR_Input'][
'wholeResult'] = consts.RESULT_N if consts.RESULT_N in res_set or consts.RESULT_NA in res_set else consts.RESULT_Y
except Exception as e:
compare_failed = True
compare_log.error('{0} [compare error] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] '
'[error={5}]'.format(log_base, application_entity, application_id, uniq_seq, ocr_res_id,
traceback.format_exc()))
compare_log.error('{0} [CA] [compare error] [entity={1}] [id={2}] [ocr_res_id={3}] [error={4}]'.format(
log_base, application_entity, application_id, ocr_res_id, traceback.format_exc()))
else:
compare_log.info('{0} [compare success] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] '
'[compare_res={5}]'.format(log_base, application_entity, application_id, uniq_seq,
ocr_res_id, comparison_res))
compare_log.info('{0} [CA] [compare success] [entity={1}] [id={2}] [ocr_res_id={3}] [compare_res={4}]'.format(
log_base, application_entity, application_id, ocr_res_id, comparison_res))
is_gcap_send = Configs.objects.filter(id=1).first()
if is_gcap_send is not None and is_gcap_send.value == 'N':
compare_log.info('{0} [gcap closed] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}]'.format(
log_base, application_entity, application_id, uniq_seq, ocr_res_id))
compare_log.info('{0} [CA] [gcap closed] [entity={1}] [id={2}] [ocr_res_id={3}]'.format(
log_base, application_entity, application_id, ocr_res_id))
return
# 时间延迟
send_time = last_obj.create_time + timedelta(seconds=15)
while datetime.now() < send_time:
compare_log.info('{0} [time wait 5s] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}]'.format(
log_base, application_entity, application_id, uniq_seq, ocr_res_id))
compare_log.info('{0} [CA] [time wait 5s] [entity={1}] [id={2}] [ocr_res_id={3}]'.format(
log_base, application_entity, application_id, ocr_res_id))
time.sleep(5)
# 将比对结果发送GCAP
try:
data = gcap.dict_to_xml(comparison_res)
except Exception as e:
compare_log.error('{0} [dict to xml failed] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] '
'[error={5}]'.format(log_base, application_entity, application_id, uniq_seq, ocr_res_id,
traceback.format_exc()))
compare_log.error('{0} [CA] [dict to xml failed] [entity={1}] [id={2}] [ocr_res_id={3}] [error={4}]'.format(
log_base, application_entity, application_id, ocr_res_id, traceback.format_exc()))
else:
try:
for times in range(consts.RETRY_TIMES):
......@@ -383,16 +368,15 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id):
else:
raise GCAPException(gcap_exc)
except Exception as e:
compare_log.error('{0} [gcap failed] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] '
'[error={5}]'.format(log_base, application_entity, application_id, uniq_seq,
ocr_res_id, traceback.format_exc()))
compare_log.error('{0} [CA] [gcap failed] [entity={1}] [id={2}] [ocr_res_id={3}] [error={4}]'.format(
log_base, application_entity, application_id, ocr_res_id, traceback.format_exc()))
else:
compare_log.info('{0} [gcap success] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] '
'[response={5}]'.format(log_base, application_entity, application_id, uniq_seq,
ocr_res_id, res_text))
compare_log.info('{0} [task success] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}]'.format(
log_base, application_entity, application_id, uniq_seq, ocr_res_id))
compare_log.info('{0} [CA] [gcap success] [entity={1}] [id={2}] [ocr_res_id={3}] [response={4}]'.format(
log_base, application_entity, application_id, ocr_res_id, res_text))
compare_log.info('{0} [CA] [task success] [entity={1}] [id={2}] [ocr_res_id={3}]'.format(
log_base, application_entity, application_id, ocr_res_id))
# report
try:
end_time = datetime.now()
if compare_failed:
......@@ -400,7 +384,8 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id):
failure_reason = 'Compare process error'
total_fields = 0
else:
successful_at_this_level = True if comparison_res['OCR_Input']['wholeResult'] == consts.RESULT_Y else False
successful_at_this_level = True if comparison_res['OCR_Input'][
'wholeResult'] == consts.RESULT_Y else False
field_failed = {
'individualCusInfo': [],
'corporateCusInfo': [],
......@@ -471,7 +456,6 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id):
else:
failure_reason = ''
request_trigger = RequestTrigger.SUBMITING.value if ocr_res_id is None else RequestTrigger.UPLOADING.value
report_class = HILCompareReport if application_entity == consts.HIL_PREFIX else AFCCompareReport
report_class.objects.create(
......@@ -486,10 +470,359 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id):
total_fields=total_fields,
workflow_name=last_obj.customer_type,
)
compare_log.info('{0} [report save success] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}]'.format(
log_base, application_entity, application_id, uniq_seq, ocr_res_id))
compare_log.info(
'{0} [CA] [report save success] [entity={1}] [id={2}] [ocr_res_id={3}]'.format(
log_base, application_entity, application_id, ocr_res_id))
except Exception as e:
compare_log.error('{0} [report save success] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] '
'[error={5}]'.format(log_base, application_entity, application_id, uniq_seq,
ocr_res_id, traceback.format_exc()))
compare_log.error('{0} [CA] [report 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()))
def get_se_compare_info(last_obj, application_entity):
compare_info = {}
individual_info_dict = {}
main_role_info = {}
for individual_info in json.loads(last_obj.individual_cus_info):
main_role_info.setdefault(individual_info['applicantType'], []).append(
(individual_info['customerName'], individual_info['idNum']))
license_dict = {}
if individual_info['idType'] in consts.SE_FIRST_ID_FIELD_MAPPING:
license_en, field_list = consts.SE_FIRST_ID_FIELD_MAPPING[individual_info['idType']]
field_input = []
for field in field_list:
if field in individual_info:
field_input.append((field, individual_info[field]))
license_dict[license_en] = field_input
if individual_info['secondIdType'] in consts.SE_SECOND_ID_FIELD_MAPPING:
second_license_en, second_field_list = consts.SE_SECOND_ID_FIELD_MAPPING[individual_info['secondIdType']]
if second_license_en not in license_dict:
second_field_input = []
for second_field, write_field in second_field_list:
if second_field in individual_info:
second_field_input.append((write_field, individual_info[second_field]))
license_dict[second_license_en] = second_field_input
if individual_info['customerType'] == consts.CUSTOMER_TYPE[5]:
sep_field_input = []
for sep_field, sep_write_field in consts.SE_SEP_FIELD:
if sep_field in individual_info:
sep_field_input.append((sep_write_field, individual_info[sep_field]))
license_dict[consts.BL_EN] = sep_field_input
if len(license_dict) > 0:
individual_info_dict.setdefault(individual_info['applicantType'], []).append(license_dict)
compare_info['individualCusInfo'] = individual_info_dict
for applicant_type in consts.APPLICANT_TYPE:
if applicant_type in main_role_info:
main_name, main_num = main_role_info[applicant_type][0]
break
del main_role_info
company_info = None
if isinstance(last_obj.corporate_cus_info, str):
corporate_info_dict = json.loads(last_obj.corporate_cus_info)
corporate_info = {}
company_info = (corporate_info_dict['companyName'], corporate_info_dict['businessLicenseNo'])
if corporate_info_dict['firstIdType'] == consts.ID_TYPE[6]:
bl_field_input = []
for bl_field in consts.SE_CORPORATE_ALL_FIELD:
bl_field_input.append((bl_field, corporate_info_dict[bl_field]))
corporate_info[consts.BL_EN] = bl_field_input
else:
if corporate_info_dict['firstIdType'] in consts.SE_FIRST_ID_FIELD_MAPPING:
license_en, _ = consts.SE_FIRST_ID_FIELD_MAPPING[corporate_info_dict['firstIdType']]
first_id_field_input = []
for first_id_field, first_id_write_field in consts.SE_CORPORATE_ID_FIELD:
first_id_field_input.append((first_id_write_field, corporate_info_dict[first_id_field]))
corporate_info[license_en] = first_id_field_input
bl_field_input = []
for bl_field in consts.SE_CORPORATE_FIELD:
bl_field_input.append((bl_field, corporate_info_dict[bl_field]))
corporate_info[consts.BL_EN] = bl_field_input
compare_info['corporateCusInfo'] = corporate_info
vehicle_info_dict = json.loads(last_obj.vehicle_info) # TODO 车辆登记证
vehicle_info = {}
vehicle_field_input = []
gb_field_input = []
if vehicle_info_dict['vehicleStatus'] == 'New':
for vehicle_field in consts.SE_NEW_FIELD:
vehicle_field_input.append((vehicle_field, vehicle_info_dict[vehicle_field]))
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[0], main_name))
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[1], main_num))
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[2], last_obj.first_submmison_date))
for gb_field in consts.SE_GB_NEW_FIELD:
gb_field_input.append((gb_field, vehicle_info_dict[gb_field]))
vehicle_info[consts.MVI_EN] = vehicle_field_input
vehicle_info[consts.MVC_EN] = gb_field_input
else:
for vehicle_field in consts.SE_USED_FIELD:
vehicle_field_input.append((vehicle_field, vehicle_info_dict[vehicle_field]))
for gb_field in consts.SE_GB_NEW_FIELD:
gb_field_input.append((gb_field, vehicle_info_dict[gb_field]))
if isinstance(company_info, tuple):
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[0], company_info[0]))
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[1], company_info[1]))
# gb_field_input.append((consts.SE_GB_USED_FIELD[0], company_info[0]))
# gb_field_input.append((consts.SE_GB_USED_FIELD[1], company_info[1]))
else:
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[0], main_name))
vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[1], main_num))
# gb_field_input.append((consts.SE_GB_USED_FIELD[0], main_name))
# gb_field_input.append((consts.SE_GB_USED_FIELD[1], main_num))
# gb_field_input.append((consts.SE_GB_USED_FIELD[2], last_obj.first_submmison_date))
vehicle_info[consts.UCI_EN] = vehicle_field_input
vehicle_info[consts.MVC_EN] = gb_field_input
compare_info['vehicleInfo'] = vehicle_info
bank_info_dict = json.loads(last_obj.bank_info)
bank_info = {}
bank_field_input = []
for bank_field in consts.SE_BANK_FIELD:
bank_field_input.append((bank_field, bank_info_dict[bank_field]))
bank_info[consts.BC_EN] = bank_field_input
dda_field_input = []
for dda_field in consts.SE_DDA_FIELD:
if dda_field.startswith('applicationId'):
dda_field_input.append((dda_field, last_obj.application_id))
elif dda_field == 'companyName':
company_name = consts.HIL_COMPANY_NAME if application_entity in consts.HIL_SET else consts.AFC_COMPANY_NAME
dda_field_input.append((dda_field, company_name))
elif dda_field == 'customerName':
dda_field_input.append((dda_field, main_name))
elif dda_field == 'idNum':
dda_field_input.append((dda_field, main_num))
else:
dda_field_input.append((dda_field, bank_info_dict[dda_field]))
bank_info[consts.DDA_EN] = dda_field_input
compare_info['bankInfo'] = bank_info
return compare_info
def se_compare_license(license_en, ocr_res_dict, field_list):
ocr_field, compare_logic, special_expiry_date = consts.SE_COMPARE_FIELD[license_en]
is_find = False
result_field_list = []
ocr_res_str = ocr_res_dict.get(ocr_field)
if ocr_res_str is not None:
ocr_res_list = json.loads(ocr_res_str)
length = len(ocr_res_list)
# 身份证、居住证 过期期限特殊处理
if special_expiry_date:
expiry_dates = set()
key = compare_logic.get('idExpiryDate')[0]
for ocr_res in ocr_res_list:
if key in ocr_res:
expiry_dates.add(ocr_res[key])
else:
expiry_dates = set()
for ocr_res in ocr_res_list:
if is_find:
break
for idx, (name, value) in enumerate(field_list):
ocr_str = ocr_res.get(compare_logic[name][0])
if not isinstance(ocr_str, str):
result = consts.RESULT_N
else:
result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2])
if idx == 0 and result == consts.RESULT_N and length > 1:
break
is_find = True
# 过期期限特殊处理
if special_expiry_date and name == 'idExpiryDate' and result == consts.RESULT_N:
for expiry_date in expiry_dates:
expiry_date_res = getattr(cp, compare_logic[name][1])(value, expiry_date, **compare_logic[name][2])
if expiry_date_res == consts.RESULT_Y:
ocr_str = expiry_date
result = expiry_date_res
break
result_field_list.append((name, value, result, ocr_str))
if not is_find:
for name, value in field_list:
result_field_list.append((name, value, consts.RESULT_N, ''))
return result_field_list
def se_compare_process(compare_info, ocr_res_dict):
# individualCusInfo
# corporateCusInfo
# vehicleInfo
# bankInfo
compare_result = []
total_fields = 0
failed_count = 0
successful_at_this_level = True
failure_reason = {}
for info_key, info_value in compare_info.items():
if info_key == 'individualCusInfo':
for idx, license_dict in info_value.items():
for license_en, field_list in license_dict.items():
failure_field = []
result_field_list = se_compare_license(license_en, ocr_res_dict, field_list)
for name, value, result, ocr_str in result_field_list:
total_fields += 1
if result == consts.RESULT_N:
failed_count += 1
successful_at_this_level = False
failure_field.append(name)
compare_result.append(
{
'Info': info_key,
'Index': idx,
'License': license_en,
'Field': name,
'Input': value,
'OCR': ocr_str,
'Result': result,
'Position': '',
'Image': '',
'errorType': '',
}
)
failure_reason.setdefault(license_en, []).append('/'.join(failure_field))
else:
for license_en, field_list in info_value.items():
failure_field = []
result_field_list = se_compare_license(license_en, ocr_res_dict, field_list)
for name, value, result, ocr_str in result_field_list:
total_fields += 1
if result == consts.RESULT_N:
failed_count += 1
successful_at_this_level = False
failure_field.append(name)
compare_result.append(
{
'Info': info_key,
'Index': 0,
'License': license_en,
'Field': name,
'Input': value,
'OCR': ocr_str,
'Result': result,
'Position': '',
'Image': '',
'errorType': '',
}
)
failure_reason.setdefault(license_en, []).append('/'.join(failure_field))
failure_reason_list = []
for license_en, failed_field_list in failure_reason.items():
failure_reason_list.append('{0}:{1}'.format(license_en, ';'.join(failed_field_list)))
failure_reason_str = '、'.join(failure_reason_list)
return compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str
def se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res_dict):
try:
# 比对逻辑
start_time = datetime.now()
compare_info = get_se_compare_info(last_obj, application_entity)
compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str = se_compare_process(
compare_info, ocr_res_dict)
except Exception as e:
pass
else:
# 将比对结果写入数据库
try:
result_table = HILSECompareResult if application_entity == consts.HIL_PREFIX else AFCSECompareResult
res_obj = result_table.objects.filter(application_id=application_id).first()
if res_obj is None:
res_obj = result_table()
res_obj.application_id = application_id
res_obj.compare_count = total_fields
res_obj.failed_count = failed_count
# res_obj.reason1_count = reason1_count
res_obj.result = json.dumps(compare_result)
res_obj.save()
compare_log.info('{0} [SE] [result save success] [entity={1}] [id={2}] [ocr_res_id={3}]'.format(
log_base, application_entity, application_id, ocr_res_id))
except Exception as e:
compare_log.error('{0} [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()))
# report
end_time = datetime.now()
try:
request_trigger = RequestTrigger.SUBMITING.value if ocr_res_id is None else RequestTrigger.UPLOADING.value
report_class = HILCompareReport if application_entity == consts.HIL_PREFIX else AFCCompareReport
report_class.objects.create(
case_number=application_id,
request_team=RequestTeam.SETTLEMENT.value,
request_trigger=request_trigger,
transaction_start=start_time,
transaction_end=end_time,
successful_at_this_level=successful_at_this_level,
failure_reason=failure_reason_str,
process_name=ProcessName.SE_CACOMPARE.value,
total_fields=total_fields,
workflow_name=last_obj.customer_type,
)
compare_log.info('{0} [SE] [report save success] [entity={1}] [id={2}] [ocr_res_id={3}]'.format(
log_base, application_entity, application_id, ocr_res_id))
except Exception as e:
compare_log.error('{0} [SE] [report 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()))
@app.task
def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True):
# POS: application_id, application_entity, uniq_seq, None
# OCR: application_id, business_type(application_entity), None, ocr_res_id
compare_log.info('{0} [receive task] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] [is_ca={5}]'.format(
log_base, application_entity, application_id, uniq_seq, ocr_res_id, is_ca))
# 根据application_id查找最新的比对信息,如果没有,结束
if is_ca:
comparison_class = HILComparisonInfo if application_entity == consts.HIL_PREFIX else AFCComparisonInfo
else:
comparison_class = HILSEComparisonInfo if application_entity == consts.HIL_PREFIX else AFCSEComparisonInfo
last_obj = comparison_class.objects.filter(application_id=application_id).last()
if last_obj is None:
compare_log.info('{0} [comparison info empty] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] '
'[is_ca={5}]'.format(log_base, application_entity, application_id, uniq_seq, ocr_res_id, is_ca))
return
# 根据application_id查找OCR累计结果指定license字段,如果没有,结束
if is_ca:
result_class = HILOCRResult if application_entity == consts.HIL_PREFIX else AFCOCRResult
else:
result_class = HILSEOCRResult if application_entity == consts.HIL_PREFIX else AFCSEOCRResult
if ocr_res_id is None:
ocr_res_dict = result_class.objects.filter(application_id=application_id).values(*consts.COMPARE_FIELDS).first()
else:
ocr_res_dict = result_class.objects.filter(id=ocr_res_id).values(*consts.COMPARE_FIELDS).first()
if ocr_res_dict is None:
compare_log.info('{0} [ocr info empty] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] '
'[is_ca={5}]'.format(log_base, application_entity, application_id, uniq_seq, ocr_res_id, is_ca))
return
if is_ca:
ca_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res_dict)
else:
se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res_dict)
......
......@@ -136,6 +136,85 @@ class Comparison:
return self.build_res(input_str == compare_str), compare_str
def se_name_compare(self, input_str, ocr_str, **kwargs):
if kwargs.get('is_passport'):
input_tmp = input_str.upper().replace(' ', '')
ocr_tmp = ocr_str.upper().replace(' ', '')
if input_tmp.find(ocr_tmp) == -1:
return self.RESULT_N
else:
return self.RESULT_Y
else:
# if re.search(r'[a-zA-Z]]', input_str):
# return self.RESULT_NA, ocr_str
input_s = input_str.translate(self.TRANS)
ocr_s = ocr_str.translate(self.TRANS)
return self.build_res(input_s == ocr_s)
def se_common_compare(self, input_str, ocr_str, **kwargs):
return self.build_res(input_str == ocr_str)
def se_date_compare(self, input_str, ocr_str, **kwargs):
if kwargs.get('long', False):
if '长期' in ocr_str or '永久' in ocr_str:
if input_str in ['2099-12-31', '2099-01-01', '2999-12-31', '2999-01-01']:
return self.RESULT_Y
else:
return self.RESULT_N
if kwargs.get('ocr_split', False):
if '至' in ocr_str:
ocr_str = ocr_str.split('至')[-1]
elif '-' in ocr_str:
ocr_str = ocr_str.split('-')[-1]
if kwargs.get('ocr_replace', False):
ocr_str = ocr_str.replace('年', '-').replace('月', '-').replace('日', '')
if kwargs.get('input_replace') is not None:
input_str = input_str.replace('-', kwargs.get('input_replace'))
return self.build_res(input_str == ocr_str)
def se_contain_compare(self, input_str, ocr_str, **kwargs):
if ocr_str.find(input_str) == -1:
return self.RESULT_N
else:
return self.RESULT_Y
def se_amount_compare(self, input_str, ocr_str, **kwargs):
if input_str == ocr_str:
return self.RESULT_Y
else:
try:
float_input = float(input_str)
float_ocr = float(ocr_str)
except Exception as e:
return self.RESULT_N
else:
return self.build_res(float_ocr == float_input)
def se_company_compare(self, input_str, ocr_str, **kwargs):
input_tmp = re.sub(self.re_obj, '', input_str).strip()
ocr_tmp = re.sub(self.re_obj, '', ocr_str).strip()
return self.build_res(input_tmp == ocr_tmp)
def se_rmb_compare(self, input_str, ocr_str, **kwargs):
try:
ocr_lower = rmb_handler.to_rmb_lower(ocr_str)
res = self.build_res(float(input_str) == ocr_lower)
# input_rmb_upper = to_rmb_upper(float(input_str))
# res = self.build_res(input_rmb_upper == ocr_str)
except Exception as e:
return self.RESULT_N
else:
return res
def se_type_compare(self, input_str, ocr_str, **kwargs):
for map_tuple in self.TYPE_MAPPING:
if re.search(map_tuple[0], ocr_str) is not None:
compare_str = map_tuple[1]
break
else:
compare_str = self.CSOTH
return self.build_res(input_str == compare_str)
cp = Comparison()
......
import pyodbc
hil_sql = """
create table hil_se_comparison_info
(
id bigint identity primary key,
uniq_seq nvarchar(128) not null,
application_id nvarchar(64) not null,
application_version tinyint default 0 not null,
customer_type nvarchar(16) not null,
first_submmison_date nvarchar(16) not null,
property_doc_policy nvarchar(16),
individual_cus_info nvarchar(max) not null,
corporate_cus_info nvarchar(max),
vehicle_info nvarchar(max) not null,
insurance_info nvarchar(max) not null,
bank_info nvarchar(max) not null,
quotationt_info nvarchar(max) not null,
update_time datetime not null,
create_time datetime not null
);
create index hil_se_comparison_info_application_id_index
on hil_se_comparison_info (application_id);
create index hil_se_comparison_info_create_time_index
on hil_se_comparison_info (create_time);
create index hil_se_comparison_info_uniq_seq_index
on hil_se_comparison_info (uniq_seq);
create table hil_se_ocr_result
(
id int identity primary key,
application_id nvarchar(64) not null,
bs_ocr nvarchar(max),
mvi_ocr nvarchar(max),
ic_ocr nvarchar(max),
rp_ocr nvarchar(max),
bc_ocr nvarchar(max),
bl_ocr nvarchar(max),
uci_ocr nvarchar(max),
eep_ocr nvarchar(max),
dl_ocr nvarchar(max),
pp_ocr nvarchar(max),
mvc_ocr nvarchar(max),
vat_ocr nvarchar(max),
update_time datetime not null,
create_time datetime not null
);
create unique index hil_se_ocr_result_application_id_uindex
on hil_se_ocr_result (application_id);
create table hil_ca_compare_result
(
id int identity primary key,
application_id nvarchar(64) not null,
is_finish bit default 0 not null,
compare_count smallint default 0 not null,
failed_count smallint default 0 not null,
reason1_count smallint default 0 not null,
reason2_count smallint default 0 not null,
reason3_count smallint default 0 not null,
reason4_count smallint default 0 not null,
reason5_count smallint default 0 not null,
reason6_count smallint default 0 not null,
reason7_count smallint default 0 not null,
reason8_count smallint default 0 not null,
reason9_count smallint default 0 not null,
reason10_count smallint default 0 not null,
result nvarchar(max),
update_time datetime not null,
create_time datetime not null
);
create unique index hil_ca_compare_result_application_id_uindex
on hil_ca_compare_result (application_id);
create index hil_ca_compare_result_update_time_index
on hil_ca_compare_result (update_time);
create table hil_se_compare_result
(
id int identity primary key,
application_id nvarchar(64) not null,
is_finish bit default 0 not null,
compare_count smallint default 0 not null,
failed_count smallint default 0 not null,
reason1_count smallint default 0 not null,
reason2_count smallint default 0 not null,
reason3_count smallint default 0 not null,
reason4_count smallint default 0 not null,
reason5_count smallint default 0 not null,
reason6_count smallint default 0 not null,
reason7_count smallint default 0 not null,
reason8_count smallint default 0 not null,
reason9_count smallint default 0 not null,
reason10_count smallint default 0 not null,
result nvarchar(max),
update_time datetime not null,
create_time datetime not null
);
create unique index hil_se_compare_result_application_id_uindex
on hil_se_compare_result (application_id);
create index hil_se_compare_result_update_time_index
on hil_se_compare_result (update_time);
"""
afc_sql = """
create table afc_se_comparison_info
(
id bigint identity primary key,
uniq_seq nvarchar(128) not null,
application_id nvarchar(64) not null,
application_version tinyint default 0 not null,
customer_type nvarchar(16) not null,
first_submmison_date nvarchar(16) not null,
property_doc_policy nvarchar(16),
individual_cus_info nvarchar(max) not null,
corporate_cus_info nvarchar(max),
vehicle_info nvarchar(max) not null,
insurance_info nvarchar(max) not null,
bank_info nvarchar(max) not null,
quotationt_info nvarchar(max) not null,
update_time datetime not null,
create_time datetime not null
);
create index afc_se_comparison_info_application_id_index
on afc_se_comparison_info (application_id);
create index afc_se_comparison_info_create_time_index
on afc_se_comparison_info (create_time);
create index afc_se_comparison_info_uniq_seq_index
on afc_se_comparison_info (uniq_seq);
create table afc_se_ocr_result
(
id int identity primary key,
application_id nvarchar(64) not null,
bs_ocr nvarchar(max),
mvi_ocr nvarchar(max),
ic_ocr nvarchar(max),
rp_ocr nvarchar(max),
bc_ocr nvarchar(max),
bl_ocr nvarchar(max),
uci_ocr nvarchar(max),
eep_ocr nvarchar(max),
dl_ocr nvarchar(max),
pp_ocr nvarchar(max),
mvc_ocr nvarchar(max),
vat_ocr nvarchar(max),
update_time datetime not null,
create_time datetime not null
);
create unique index afc_se_ocr_result_application_id_uindex
on afc_se_ocr_result (application_id);
create table afc_ca_compare_result
(
id int identity primary key,
application_id nvarchar(64) not null,
is_finish bit default 0 not null,
compare_count smallint default 0 not null,
failed_count smallint default 0 not null,
reason1_count smallint default 0 not null,
reason2_count smallint default 0 not null,
reason3_count smallint default 0 not null,
reason4_count smallint default 0 not null,
reason5_count smallint default 0 not null,
reason6_count smallint default 0 not null,
reason7_count smallint default 0 not null,
reason8_count smallint default 0 not null,
reason9_count smallint default 0 not null,
reason10_count smallint default 0 not null,
result nvarchar(max),
update_time datetime not null,
create_time datetime not null
);
create unique index afc_ca_compare_result_application_id_uindex
on afc_ca_compare_result (application_id);
create index afc_ca_compare_result_update_time_index
on afc_ca_compare_result (update_time);
create table afc_se_compare_result
(
id int identity primary key,
application_id nvarchar(64) not null,
is_finish bit default 0 not null,
compare_count smallint default 0 not null,
failed_count smallint default 0 not null,
reason1_count smallint default 0 not null,
reason2_count smallint default 0 not null,
reason3_count smallint default 0 not null,
reason4_count smallint default 0 not null,
reason5_count smallint default 0 not null,
reason6_count smallint default 0 not null,
reason7_count smallint default 0 not null,
reason8_count smallint default 0 not null,
reason9_count smallint default 0 not null,
reason10_count smallint default 0 not null,
result nvarchar(max),
update_time datetime not null,
create_time datetime not null
);
create unique index afc_se_compare_result_application_id_uindex
on afc_se_compare_result (application_id);
create index afc_se_compare_result_update_time_index
on afc_se_compare_result (update_time);
"""
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()
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!