1e50135a by 周伟奇

prese part 1

1 parent f6840d5c
......@@ -1234,26 +1234,39 @@ RESULT_MAPPING = {
}
CA_ADD_COMPARE_FIELDS = (IC_OCR_FIELD, BL_OCR_FIELD, BS_FIELD)
CA_ADD_COMPARE_FIELDS_PRE = (IC_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,
HMH_OCR_FIELD,
JYPZ_OCR_FIELD,
HT_FIELD,
BD_FIELD,
BS_FIELD,
HIL_CONTRACT_1_FIELD,
HIL_CONTRACT_2_FIELD,
HIL_CONTRACT_3_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,
HMH_OCR_FIELD,
JYPZ_OCR_FIELD,
HT_FIELD,
BD_FIELD,
BS_FIELD,
HIL_CONTRACT_1_FIELD,
HIL_CONTRACT_2_FIELD,
HIL_CONTRACT_3_FIELD,
PRE_COMPARE_FIELDS = (
MVI_OCR_FIELD,
IC_OCR_FIELD,
BC_OCR_FIELD,
HMH_OCR_FIELD,
HT_FIELD,
BD_FIELD,
HIL_CONTRACT_1_FIELD,
HIL_CONTRACT_2_FIELD,
)
# 身份证
......
......@@ -2,8 +2,9 @@ import re
import json
import requests
from .named_enum import DocStatus
from .models import HILDoc, AFCDoc
from .models import HILDoc, AFCDoc, AFCSEOCRResult, AFCOCRResult, HILSEOCRResult, HILOCRResult
from . import consts
from prese.compare import pre_compare
class MPOSHandler:
......@@ -141,3 +142,31 @@ class DocHandler:
else:
return consts.DATA_SOURCE_LIST[0]
class PreSEHandler:
# preSettlement
@staticmethod
def pre_compare_entrance(pos_content):
application_entity = pos_content.get('applicationEntity')
application_id = pos_content.get('applicationId')
# 根据application_id查找OCR累计结果指定license字段,如果没有,结束
result_class = HILSEOCRResult if application_entity in consts.HIL_SET else AFCSEOCRResult
ca_result_class = HILOCRResult if application_entity in consts.HIL_SET else AFCOCRResult
ca_ocr_res_dict = ca_result_class.objects.filter(application_id=application_id).values(
*consts.CA_ADD_COMPARE_FIELDS_PRE).first()
ocr_res_dict = result_class.objects.filter(application_id=application_id).values(
*consts.PRE_COMPARE_FIELDS).first()
if ocr_res_dict is None:
return
id_res_list = []
for field_name in consts.CA_ADD_COMPARE_FIELDS_PRE:
if field_name == consts.IC_OCR_FIELD:
id_res_list.append(ca_ocr_res_dict.get(field_name) if isinstance(ca_ocr_res_dict, dict) else None)
id_res_list.append(ocr_res_dict.get(field_name))
rebuild_compare_result = pre_compare(pos_content, ocr_res_dict, id_res_list)
return rebuild_compare_result
......
......@@ -48,10 +48,10 @@ from .models import (
MposReport,
)
from .named_enum import ErrorType, AutoResult, WholeResult, RPAResult
from .mixins import DocHandler, MPOSHandler
from .mixins import DocHandler, MPOSHandler, PreSEHandler
from . import consts
from apps.account.authentication import OAuth2AuthenticationWithUser
from celery_compare.tasks import compare, pos_compare
from celery_compare.tasks import compare
class CustomDate(fields.Date):
......@@ -87,6 +87,8 @@ se_vehicle_args = {
'vehicleTransactionAmount': CustomDecimal(required=True),
'vinNo': fields.Str(required=True, validate=validate.Length(max=256)),
'dealer': fields.Str(required=True, validate=validate.Length(max=256)),
'showRoom': fields.Str(required=False),
'agencyDealer': fields.Str(required=False),
'option': CustomDecimal(required=False),
'msrp': CustomDecimal(required=False),
'totalAmount': CustomDecimal(required=False),
......@@ -125,6 +127,7 @@ se_quotationt_args = {
'loanTerm': fields.Int(required=True),
'vehiclePrincipal': CustomDecimal(required=True),
'associatedServicePrincipal': CustomDecimal(required=False),
'mortgageType': fields.Str(required=True, validate=validate.Length(max=16)),
'associatedServiceInfo': fields.List(fields.Nested(se_associated_args), required=False),
'monthlyPaymentInfo': fields.List(fields.Nested(se_payment_args), required=True, validate=validate.Length(min=1)),
}
......@@ -224,6 +227,10 @@ se_compare_content = {
'applicationId': fields.Str(required=True, validate=validate.Length(max=64)),
"applicationVersion": fields.Int(required=True),
'applicationEntity': fields.Str(required=True, validate=validate.OneOf(consts.ENTITY)),
'productGroup': fields.Str(required=False),
'productGroupID': fields.Str(required=False),
'customerType': fields.Str(required=True, validate=validate.OneOf(consts.CUSTOMER_TYPE)),
"firstSubmmisonDate": CustomDate(required=True),
'propertyDocumentPolicy': fields.Str(required=False, validate=validate.Length(max=16)),
......@@ -754,34 +761,45 @@ class CompareView(GenericView):
'''
class SECompareView(GenericView):
class SECompareView(GenericView, PreSEHandler):
permission_classes = [IsAuthenticated]
authentication_classes = [OAuth2AuthenticationWithUser]
# pos上传比对信息接口 SE
# SE preSettlement
@use_args(se_compare_args, location='data')
def post(self, request, args):
# 存库
log_base = '[prese]'
content = args.get('content', {})
business_type = content.get('applicationEntity')
application_id = content.get('applicationId')
uniq_seq = content.get('uniqSeq')
bank_verify = content.get('bankInfo', {}).get('bankVerificationStatus', '')
bank_class = HILbankVerification if business_type in consts.HIL_SET else AFCbankVerification
bank_obj = bank_class.objects.filter(application_id=application_id).first()
# 存库, 用于银行卡比对
try:
bank_class = HILbankVerification if business_type in consts.HIL_SET else AFCbankVerification
bank_obj = bank_class.objects.filter(application_id=application_id).first()
if bank_obj is None and bank_verify == 'PASS':
bank_class.objects.create(
application_id=application_id,
)
elif bank_obj is not None and bank_verify == 'PASS' and bank_obj.on_off is False:
bank_obj.on_off = True
bank_obj.save()
elif bank_obj is not None and bank_verify != 'PASS' and bank_obj.on_off is True:
bank_obj.on_off = False
bank_obj.save()
compare_result = pos_compare(content)
if bank_obj is None and bank_verify == 'PASS':
bank_class.objects.create(
application_id=application_id,
)
elif bank_obj is not None and bank_verify == 'PASS' and bank_obj.on_off is False:
bank_obj.on_off = True
bank_obj.save()
elif bank_obj is not None and bank_verify != 'PASS' and bank_obj.on_off is True:
bank_obj.on_off = False
bank_obj.save()
except Exception as e:
self.running_log.info('{0} [bankCard verify save db error] [applicationEntity={1}] '
'[application_id={2}] [bank_status={3}] [error={4}]'.format(
log_base, business_type, application_id, bank_verify, traceback.format_exc()))
# preSettlement比对
compare_result = self.pre_compare_entrance(content)
self.running_log.info('{0} [prese completed] [applicationEntity={1}] [application_id={2}] [uniq_seq={3}] '
'[result={4}]'.format(log_base, business_type, application_id, uniq_seq, compare_result))
return response.ok(data=compare_result)
......
......@@ -39,7 +39,6 @@ from apps.doc.exceptions import GCAPException
from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType
from common.tools.comparison import cp
from common.tools.des import decode_des
from pos import pos
compare_log = logging.getLogger('compare')
log_base = '[Compare]'
......@@ -2414,6 +2413,7 @@ def se_compare_license_id(license_en, id_res_list, field_list):
if is_find:
break
result_field_list.clear()
for idx, (name, value) in enumerate(field_list):
# if ocr_field == consts.MVI_OCR_FIELD and name == consts.SE_NEW_ADD_FIELD[9]:
# ocr_str = getattr(cp, consts.ZW_METHOD)(
......@@ -2493,6 +2493,7 @@ def se_compare_license_id(license_en, id_res_list, field_list):
result_field_list.append((name, value, result, ocr_str, img_path, error_type, compare_logic[name][3]))
if not is_find:
result_field_list.clear()
for name, value in field_list:
if isinstance(value, list):
value = json.dumps(value, ensure_ascii=False)
......@@ -3200,135 +3201,3 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True
'[error={4}]'.format(log_base, application_entity, application_id, ocr_res_id,
traceback.format_exc()))
# pos接口
def pos_compare(pos_content, application_id, application_entity, uniq_seq, ocr_res_id=None, 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
compare_log.info('{0} [pos_compare] [entity={1}] [id={2}] [uniq_seq={3}] [is_ca={4}] '
'[is_cms={5}]'.format(log_base, application_entity, application_id, uniq_seq,
is_ca, is_cms))
# 根据application_id查找最新的比对信息,如果没有,结束
# if is_ca:
# comparison_class = HILComparisonInfo if application_entity == consts.HIL_PREFIX else AFCComparisonInfo
# else:
# if application_entity == consts.HIL_PREFIX:
# comparison_class = HILSECMSInfo if is_cms else HILSEComparisonInfo
# else:
# comparison_class = AFCSECMSInfo if is_cms 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}] '
# '[is_ca={4}] [is_cms]={5}'.format(log_base, application_entity, application_id, uniq_seq,
# is_ca, is_cms))
# return
# 根据application_id查找OCR累计结果指定license字段,如果没有,结束
if is_ca:
result_class = HILOCRResult if application_entity == consts.HIL_PREFIX else AFCOCRResult
ca_ocr_res_dict = dict()
else:
result_class = HILSEOCRResult if application_entity == consts.HIL_PREFIX else AFCSEOCRResult
ca_result_class = HILOCRResult if application_entity == consts.HIL_PREFIX else AFCOCRResult
# if ocr_res_id is None:
ca_ocr_res_dict = ca_result_class.objects.filter(application_id=application_id).values(
*consts.CA_ADD_COMPARE_FIELDS).first()
# else:
# ca_ocr_res_dict = ca_result_class.objects.filter(id=ocr_res_id).values(
# *consts.CA_ADD_COMPARE_FIELDS).first()
ocr_res_dict = result_class.objects.filter(application_id=application_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}] [is_cms]={6}'.format(log_base, application_entity, application_id,
uniq_seq, ocr_res_id, is_ca, is_cms))
return
pos_content_obj = json.loads(pos_content)
if is_ca:
# 比对逻辑
# compare_info = get_ca_compare_info(pos_content_obj)
# compare_result, total_fields, failed_count = ca_compare_process(compare_info, ocr_res_dict)
# compare_log.info('{0} [CA] [compare success] [entity={1}] [id={2}] [ocr_res_id={3}] [result={4}]'.format(
# log_base, application_entity, application_id, ocr_res_id, compare_result))
# ca_compare(application_id, application_entity, ocr_res_id, pos_content_obj, ocr_res_dict)
compare_result = pos.PosCompare.ca_compare(pos_content_obj, ocr_res_dict)
else:
id_res_list = []
for field_name in consts.CA_ADD_COMPARE_FIELDS:
if field_name == consts.IC_OCR_FIELD:
id_res_list.append(ocr_res_dict.get(field_name))
id_res_list.append(ca_ocr_res_dict.get(field_name) if isinstance(ca_ocr_res_dict, dict) else None)
if isinstance(ca_ocr_res_dict, dict) and isinstance(ca_ocr_res_dict.get(field_name), str):
tmp_ca_result = json.loads(ca_ocr_res_dict.get(field_name))
if isinstance(ocr_res_dict.get(field_name), str):
tmp_se_result = json.loads(ocr_res_dict.get(field_name))
tmp_ca_result.extend(tmp_se_result)
ocr_res_dict[field_name] = json.dumps(tmp_ca_result)
# auto settlement
# auto_class = HILAutoSettlement if application_entity == consts.HIL_PREFIX else AFCAutoSettlement
# auto_obj = auto_class.objects.filter(application_id=application_id, on_off=True).first()
# bank_class = HILbankVerification if application_entity == consts.HIL_PREFIX else AFCbankVerification
# ignore_bank = bank_class.objects.filter(application_id=application_id, on_off=True).exists()
# if auto_obj is not None:
# auto_result = se_compare_auto(application_id, application_entity, ocr_res_id, pos_content_obj, ocr_res_dict, auto_obj, ignore_bank, id_res_list)
# else:
# auto_result = None
#
# full_result = se_compare(application_id, application_entity, ocr_res_id, pos_content_obj, ocr_res_dict, is_cms, auto_result, ignore_bank, id_res_list)
#
# if auto_obj is not None:
# try:
# auto_obj.ocr_whole_result_pass = full_result
# auto_obj.save()
# compare_log.info('{0} [Auto 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} [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()))
# result_table = HILCACompareResult if application_entity == consts.HIL_PREFIX else AFCCACompareResult
# res_obj = result_table.objects.filter(application_id=application_id).first()
compare_result = pos.PosCompare.se_compare(pos_content_obj, ocr_res_dict, id_res_list=id_res_list)
return pos_result_output(compare_result)
# pos输出解析
def pos_result_output(compare_result):
result_obj = json.loads(compare_result)
license_map = dict()
for item in result_obj:
license_en = item.get("License")
if license_map.get(license_en):
license_map.get(license_en).append(item)
else:
info_items = [item]
license_map[license_en] = info_items
is_pass = True
particulars = []
for license, license_items in license_map.items():
particular = {"object_name": license}
# license_comments = OCR_COMPARE_COMMENT.get(license)
# if not license_comments:
# continue
fields = []
particular["fields"] = fields
for license_item in license_items:
field = dict()
field["input"] = license_item.get("Input")
field["ocr"] = license_item.get("OCR")
field["field_is_pass"] = license_item.get("Result") == 'Y'
if not field["field_is_pass"]:
is_pass = False
field["comments"] = license_item.get('comments', '')
fields.append(field)
particular["fields"] = fields
particulars.append(particular)
return {
"is_pass": is_pass,
"particulars": particulars
}
......
......@@ -29,8 +29,6 @@ class Comparison:
self.RESULT_Y = 'Y'
self.RESULT_N = 'N'
self.RESULT_N1 = 'N1'
self.RESULT_N2 = 'N2'
self.RESULT_NA = 'NA'
self.TRANS_MAP = {
......@@ -610,19 +608,19 @@ class Comparison:
return self.RESULT_N
return self.se_date_compare_2(input_str, ocr_date_set.pop(), three_month=True)
def se_date_compare_pos(self, input_str, ocr_str, **kwargs):
try:
ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d").date()
today = datetime.now().date()
if ocr_date < today:
return self.RESULT_N1
elif today <= ocr_date <= (today + timedelta(days=8)):
return self.RESULT_N2
elif ocr_date > (today + timedelta(days=8)):
return self.RESULT_Y
except Exception as e:
return self.RESULT_N
return self.RESULT_N
# def se_date_compare_pos(self, input_str, ocr_str, **kwargs):
# try:
# ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d").date()
# today = datetime.now().date()
# if ocr_date < today:
# return self.RESULT_N1
# elif today <= ocr_date <= (today + timedelta(days=8)):
# return self.RESULT_N2
# elif ocr_date > (today + timedelta(days=8)):
# return self.RESULT_Y
# except Exception as e:
# return self.RESULT_N
# return self.RESULT_N
cp = Comparison()
......
HIL_SET = {'HIL', 'HIl', 'HiL', 'Hil', 'hIL', 'hIl', 'hiL', 'hil', 'CO00002', 'SF5_CL'}
ID_TYPE = 'ITPRC'
ID_FIELDS = ['姓名', '身份证号码', '有效期限']
MVI_FIELDS = ['车架号', '价税合计(小写)', '购买方姓名', '购买方证件号码', '开票日期', '发票联']
MVI_FPL_VALUE = '发票联'
BC_FIELDS = ['卡号', '开户行名称', '卡片类型']
BC_TYPE_VALUE = '借记卡'
HMH_FIELDS = ['借款人/承租人姓名', '借款人/承租人证件号', '申请号', '渠道', '签字']
HMH_CHANNEL_MAP = {
'AFC': '宝马金融(中国)有限公司',
'HIL': '先锋国际融资租赁有限公司'
}
HAVE_CN = '有'
BD_FIELDS = ['被保险人姓名', '被保险人证件号码', '车架号']
ID_EN = 'idCard'
MVI_EN = 'newCar Invoice'
BC_EN = 'Bank Card'
HMH_EN = 'Mortgage Waiver Letter'
BD_EN = 'Insurance'
ID_OCR_FIELD = 'ic_ocr'
MVI_OCR_FIELD = 'mvi_ocr'
BC_OCR_FIELD = 'bc_ocr'
HMH_OCR_FIELD = 'hmh_ocr'
BD_FIELD = 'bd_ocr'
MVI_COMPARE_LOGIC = {
MVI_FIELDS[0]: ('车辆识别代码', 'se_common_compare', {}, '发票车架号与系统不一致'),
MVI_FIELDS[1]: ('价税合计小写', 'se_amount_compare', {}, '发票车辆价格与系统不一致'),
MVI_FIELDS[2]: ('购方名称', 'se_name_compare', {'is_passport': True, 'replace_kuohao': True}, '发票购买方姓名与系统不一致'),
MVI_FIELDS[3]: ('购买方身份证号或组织机构代码', 'se_common_compare', {}, '发票购买方证件号码与系统不一致'),
MVI_FIELDS[4]: ('开票日期', 'se_date_compare_2', {'three_month': True}, '请确认发票开票日期,若发票开票日期早于首次提交审批日期则无法受理放款申请'),
MVI_FIELDS[5]: ('发票类型', 'se_common_compare', {}, '发票疑似非发票联'),
}
BC_COMPARE_LOGIC = {
BC_FIELDS[0]: ('CardNum', 'se_common_compare', {'remove_space': True}, '银行卡卡号与系统不一致'),
BC_FIELDS[1]: ('BankName', 'se_both_contain_compare', {}, '银行卡开户行与系统不一致'),
BC_FIELDS[2]: ('CardType', 'se_common_compare', {}, '银行卡疑似非借记卡'),
}
HMH_COMPARE_LOGIC = {
HMH_FIELDS[0]: ('借款/承租人姓名', 'se_name_compare', {}, '抵押登记豁免函借款人/承租人姓名与系统不符'),
HMH_FIELDS[1]: ('证件号码', 'se_common_compare', {}, '抵押登记豁免函借款人/承租人证件号码与系统不符'),
HMH_FIELDS[2]: ('合同编号', 'se_common_compare', {}, '抵押登记豁免函申请号与系统不符'),
HMH_FIELDS[3]: ('渠道', 'se_channel_compare', {}, '抵押登记豁免函渠道与系统不符'),
HMH_FIELDS[4]: ('借款人签字/盖章', 'se_common_compare', {}, '抵押登记豁免函无签字'),
}
BD_COMPARE_LOGIC = {
BD_FIELDS[0]: ('被保险人姓名', 'super_list_compare', {'method': 'name'}, '保单被保险人姓名与系统不一致'),
BD_FIELDS[1]: ('被保险人证件号码', 'super_list_compare', {'method': 'common', 'is_bd_id': True}, '保单身份证号需人工核查'),
BD_FIELDS[2]: ('车架号', 'se_common_compare', {}, '保单车架号与系统不一致'),
}
PRE_COMPARE_LOGIC_MAP = {
ID_EN: (ID_OCR_FIELD, ID_COMPARE_LOGIC, '请确认是否提供身份证件'),
MVI_EN: (MVI_OCR_FIELD, MVI_COMPARE_LOGIC, '请确认是否提供发票'),
BC_EN: (BC_OCR_FIELD, BC_COMPARE_LOGIC, '请确认是否提供银行卡'),
HMH_EN: (HMH_OCR_FIELD, HMH_COMPARE_LOGIC, '请确认是否已完成抵押登记豁免函签署'),
BD_EN: (BD_FIELD, BD_COMPARE_LOGIC, '请确认是否提供保单'),
AFC_CONTRACT_EN: (HT_FIELD, HT_COMPARE_LOGIC, '请确认是否已完成车辆抵押贷款合同签署'),
HIL_CONTRACT_1_EN: (HIL_CONTRACT_1_FIELD, HIL_CONTRACT_1_COMPARE_LOGIC, '请确认是否已完成售后回租合同签署'),
HIL_CONTRACT_2_EN: (HIL_CONTRACT_2_FIELD, HIL_CONTRACT_2_COMPARE_LOGIC, '请确认是否已完成车辆租赁抵押合同签署'),
}
RESULT_Y = 'Y'
RESULT_N = 'N'
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!