prese part 1
Showing
11 changed files
with
455 additions
and
2285 deletions
| ... | @@ -1234,8 +1234,10 @@ RESULT_MAPPING = { | ... | @@ -1234,8 +1234,10 @@ RESULT_MAPPING = { |
| 1234 | } | 1234 | } |
| 1235 | 1235 | ||
| 1236 | CA_ADD_COMPARE_FIELDS = (IC_OCR_FIELD, BL_OCR_FIELD, BS_FIELD) | 1236 | CA_ADD_COMPARE_FIELDS = (IC_OCR_FIELD, BL_OCR_FIELD, BS_FIELD) |
| 1237 | CA_ADD_COMPARE_FIELDS_PRE = (IC_OCR_FIELD,) | ||
| 1237 | 1238 | ||
| 1238 | COMPARE_FIELDS = (MVI_OCR_FIELD, | 1239 | COMPARE_FIELDS = ( |
| 1240 | MVI_OCR_FIELD, | ||
| 1239 | IC_OCR_FIELD, | 1241 | IC_OCR_FIELD, |
| 1240 | RP_OCR_FIELD, | 1242 | RP_OCR_FIELD, |
| 1241 | BC_OCR_FIELD, | 1243 | BC_OCR_FIELD, |
| ... | @@ -1256,6 +1258,17 @@ COMPARE_FIELDS = (MVI_OCR_FIELD, | ... | @@ -1256,6 +1258,17 @@ COMPARE_FIELDS = (MVI_OCR_FIELD, |
| 1256 | HIL_CONTRACT_3_FIELD, | 1258 | HIL_CONTRACT_3_FIELD, |
| 1257 | ) | 1259 | ) |
| 1258 | 1260 | ||
| 1261 | PRE_COMPARE_FIELDS = ( | ||
| 1262 | MVI_OCR_FIELD, | ||
| 1263 | IC_OCR_FIELD, | ||
| 1264 | BC_OCR_FIELD, | ||
| 1265 | HMH_OCR_FIELD, | ||
| 1266 | HT_FIELD, | ||
| 1267 | BD_FIELD, | ||
| 1268 | HIL_CONTRACT_1_FIELD, | ||
| 1269 | HIL_CONTRACT_2_FIELD, | ||
| 1270 | ) | ||
| 1271 | |||
| 1259 | # 身份证 | 1272 | # 身份证 |
| 1260 | ITPRC = [ | 1273 | ITPRC = [ |
| 1261 | ('customerChineseName', '姓名', 'name_compare', {}, 'customerChineseNameResult'), | 1274 | ('customerChineseName', '姓名', 'name_compare', {}, 'customerChineseNameResult'), | ... | ... |
| ... | @@ -2,8 +2,9 @@ import re | ... | @@ -2,8 +2,9 @@ import re |
| 2 | import json | 2 | import json |
| 3 | import requests | 3 | import requests |
| 4 | from .named_enum import DocStatus | 4 | from .named_enum import DocStatus |
| 5 | from .models import HILDoc, AFCDoc | 5 | from .models import HILDoc, AFCDoc, AFCSEOCRResult, AFCOCRResult, HILSEOCRResult, HILOCRResult |
| 6 | from . import consts | 6 | from . import consts |
| 7 | from prese.compare import pre_compare | ||
| 7 | 8 | ||
| 8 | 9 | ||
| 9 | class MPOSHandler: | 10 | class MPOSHandler: |
| ... | @@ -141,3 +142,31 @@ class DocHandler: | ... | @@ -141,3 +142,31 @@ class DocHandler: |
| 141 | else: | 142 | else: |
| 142 | return consts.DATA_SOURCE_LIST[0] | 143 | return consts.DATA_SOURCE_LIST[0] |
| 143 | 144 | ||
| 145 | |||
| 146 | class PreSEHandler: | ||
| 147 | |||
| 148 | # preSettlement | ||
| 149 | @staticmethod | ||
| 150 | def pre_compare_entrance(pos_content): | ||
| 151 | application_entity = pos_content.get('applicationEntity') | ||
| 152 | application_id = pos_content.get('applicationId') | ||
| 153 | |||
| 154 | # 根据application_id查找OCR累计结果指定license字段,如果没有,结束 | ||
| 155 | result_class = HILSEOCRResult if application_entity in consts.HIL_SET else AFCSEOCRResult | ||
| 156 | ca_result_class = HILOCRResult if application_entity in consts.HIL_SET else AFCOCRResult | ||
| 157 | |||
| 158 | ca_ocr_res_dict = ca_result_class.objects.filter(application_id=application_id).values( | ||
| 159 | *consts.CA_ADD_COMPARE_FIELDS_PRE).first() | ||
| 160 | ocr_res_dict = result_class.objects.filter(application_id=application_id).values( | ||
| 161 | *consts.PRE_COMPARE_FIELDS).first() | ||
| 162 | if ocr_res_dict is None: | ||
| 163 | return | ||
| 164 | |||
| 165 | id_res_list = [] | ||
| 166 | for field_name in consts.CA_ADD_COMPARE_FIELDS_PRE: | ||
| 167 | if field_name == consts.IC_OCR_FIELD: | ||
| 168 | id_res_list.append(ca_ocr_res_dict.get(field_name) if isinstance(ca_ocr_res_dict, dict) else None) | ||
| 169 | id_res_list.append(ocr_res_dict.get(field_name)) | ||
| 170 | |||
| 171 | rebuild_compare_result = pre_compare(pos_content, ocr_res_dict, id_res_list) | ||
| 172 | return rebuild_compare_result | ... | ... |
| ... | @@ -48,10 +48,10 @@ from .models import ( | ... | @@ -48,10 +48,10 @@ from .models import ( |
| 48 | MposReport, | 48 | MposReport, |
| 49 | ) | 49 | ) |
| 50 | from .named_enum import ErrorType, AutoResult, WholeResult, RPAResult | 50 | from .named_enum import ErrorType, AutoResult, WholeResult, RPAResult |
| 51 | from .mixins import DocHandler, MPOSHandler | 51 | from .mixins import DocHandler, MPOSHandler, PreSEHandler |
| 52 | from . import consts | 52 | from . import consts |
| 53 | from apps.account.authentication import OAuth2AuthenticationWithUser | 53 | from apps.account.authentication import OAuth2AuthenticationWithUser |
| 54 | from celery_compare.tasks import compare, pos_compare | 54 | from celery_compare.tasks import compare |
| 55 | 55 | ||
| 56 | 56 | ||
| 57 | class CustomDate(fields.Date): | 57 | class CustomDate(fields.Date): |
| ... | @@ -87,6 +87,8 @@ se_vehicle_args = { | ... | @@ -87,6 +87,8 @@ se_vehicle_args = { |
| 87 | 'vehicleTransactionAmount': CustomDecimal(required=True), | 87 | 'vehicleTransactionAmount': CustomDecimal(required=True), |
| 88 | 'vinNo': fields.Str(required=True, validate=validate.Length(max=256)), | 88 | 'vinNo': fields.Str(required=True, validate=validate.Length(max=256)), |
| 89 | 'dealer': fields.Str(required=True, validate=validate.Length(max=256)), | 89 | 'dealer': fields.Str(required=True, validate=validate.Length(max=256)), |
| 90 | 'showRoom': fields.Str(required=False), | ||
| 91 | 'agencyDealer': fields.Str(required=False), | ||
| 90 | 'option': CustomDecimal(required=False), | 92 | 'option': CustomDecimal(required=False), |
| 91 | 'msrp': CustomDecimal(required=False), | 93 | 'msrp': CustomDecimal(required=False), |
| 92 | 'totalAmount': CustomDecimal(required=False), | 94 | 'totalAmount': CustomDecimal(required=False), |
| ... | @@ -125,6 +127,7 @@ se_quotationt_args = { | ... | @@ -125,6 +127,7 @@ se_quotationt_args = { |
| 125 | 'loanTerm': fields.Int(required=True), | 127 | 'loanTerm': fields.Int(required=True), |
| 126 | 'vehiclePrincipal': CustomDecimal(required=True), | 128 | 'vehiclePrincipal': CustomDecimal(required=True), |
| 127 | 'associatedServicePrincipal': CustomDecimal(required=False), | 129 | 'associatedServicePrincipal': CustomDecimal(required=False), |
| 130 | 'mortgageType': fields.Str(required=True, validate=validate.Length(max=16)), | ||
| 128 | 'associatedServiceInfo': fields.List(fields.Nested(se_associated_args), required=False), | 131 | 'associatedServiceInfo': fields.List(fields.Nested(se_associated_args), required=False), |
| 129 | 'monthlyPaymentInfo': fields.List(fields.Nested(se_payment_args), required=True, validate=validate.Length(min=1)), | 132 | 'monthlyPaymentInfo': fields.List(fields.Nested(se_payment_args), required=True, validate=validate.Length(min=1)), |
| 130 | } | 133 | } |
| ... | @@ -224,6 +227,10 @@ se_compare_content = { | ... | @@ -224,6 +227,10 @@ se_compare_content = { |
| 224 | 'applicationId': fields.Str(required=True, validate=validate.Length(max=64)), | 227 | 'applicationId': fields.Str(required=True, validate=validate.Length(max=64)), |
| 225 | "applicationVersion": fields.Int(required=True), | 228 | "applicationVersion": fields.Int(required=True), |
| 226 | 'applicationEntity': fields.Str(required=True, validate=validate.OneOf(consts.ENTITY)), | 229 | 'applicationEntity': fields.Str(required=True, validate=validate.OneOf(consts.ENTITY)), |
| 230 | |||
| 231 | 'productGroup': fields.Str(required=False), | ||
| 232 | 'productGroupID': fields.Str(required=False), | ||
| 233 | |||
| 227 | 'customerType': fields.Str(required=True, validate=validate.OneOf(consts.CUSTOMER_TYPE)), | 234 | 'customerType': fields.Str(required=True, validate=validate.OneOf(consts.CUSTOMER_TYPE)), |
| 228 | "firstSubmmisonDate": CustomDate(required=True), | 235 | "firstSubmmisonDate": CustomDate(required=True), |
| 229 | 'propertyDocumentPolicy': fields.Str(required=False, validate=validate.Length(max=16)), | 236 | 'propertyDocumentPolicy': fields.Str(required=False, validate=validate.Length(max=16)), |
| ... | @@ -754,19 +761,23 @@ class CompareView(GenericView): | ... | @@ -754,19 +761,23 @@ class CompareView(GenericView): |
| 754 | ''' | 761 | ''' |
| 755 | 762 | ||
| 756 | 763 | ||
| 757 | class SECompareView(GenericView): | 764 | class SECompareView(GenericView, PreSEHandler): |
| 758 | permission_classes = [IsAuthenticated] | 765 | permission_classes = [IsAuthenticated] |
| 759 | authentication_classes = [OAuth2AuthenticationWithUser] | 766 | authentication_classes = [OAuth2AuthenticationWithUser] |
| 760 | 767 | ||
| 761 | # pos上传比对信息接口 SE | 768 | # SE preSettlement |
| 762 | @use_args(se_compare_args, location='data') | 769 | @use_args(se_compare_args, location='data') |
| 763 | def post(self, request, args): | 770 | def post(self, request, args): |
| 764 | # 存库 | 771 | log_base = '[prese]' |
| 772 | |||
| 765 | content = args.get('content', {}) | 773 | content = args.get('content', {}) |
| 766 | business_type = content.get('applicationEntity') | 774 | business_type = content.get('applicationEntity') |
| 767 | application_id = content.get('applicationId') | 775 | application_id = content.get('applicationId') |
| 776 | uniq_seq = content.get('uniqSeq') | ||
| 768 | bank_verify = content.get('bankInfo', {}).get('bankVerificationStatus', '') | 777 | bank_verify = content.get('bankInfo', {}).get('bankVerificationStatus', '') |
| 769 | 778 | ||
| 779 | # 存库, 用于银行卡比对 | ||
| 780 | try: | ||
| 770 | bank_class = HILbankVerification if business_type in consts.HIL_SET else AFCbankVerification | 781 | bank_class = HILbankVerification if business_type in consts.HIL_SET else AFCbankVerification |
| 771 | bank_obj = bank_class.objects.filter(application_id=application_id).first() | 782 | bank_obj = bank_class.objects.filter(application_id=application_id).first() |
| 772 | 783 | ||
| ... | @@ -780,8 +791,15 @@ class SECompareView(GenericView): | ... | @@ -780,8 +791,15 @@ class SECompareView(GenericView): |
| 780 | elif bank_obj is not None and bank_verify != 'PASS' and bank_obj.on_off is True: | 791 | elif bank_obj is not None and bank_verify != 'PASS' and bank_obj.on_off is True: |
| 781 | bank_obj.on_off = False | 792 | bank_obj.on_off = False |
| 782 | bank_obj.save() | 793 | bank_obj.save() |
| 783 | 794 | except Exception as e: | |
| 784 | compare_result = pos_compare(content) | 795 | self.running_log.info('{0} [bankCard verify save db error] [applicationEntity={1}] ' |
| 796 | '[application_id={2}] [bank_status={3}] [error={4}]'.format( | ||
| 797 | log_base, business_type, application_id, bank_verify, traceback.format_exc())) | ||
| 798 | |||
| 799 | # preSettlement比对 | ||
| 800 | compare_result = self.pre_compare_entrance(content) | ||
| 801 | self.running_log.info('{0} [prese completed] [applicationEntity={1}] [application_id={2}] [uniq_seq={3}] ' | ||
| 802 | '[result={4}]'.format(log_base, business_type, application_id, uniq_seq, compare_result)) | ||
| 785 | 803 | ||
| 786 | return response.ok(data=compare_result) | 804 | return response.ok(data=compare_result) |
| 787 | 805 | ... | ... |
| ... | @@ -39,7 +39,6 @@ from apps.doc.exceptions import GCAPException | ... | @@ -39,7 +39,6 @@ from apps.doc.exceptions import GCAPException |
| 39 | from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType | 39 | from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType |
| 40 | from common.tools.comparison import cp | 40 | from common.tools.comparison import cp |
| 41 | from common.tools.des import decode_des | 41 | from common.tools.des import decode_des |
| 42 | from pos import pos | ||
| 43 | 42 | ||
| 44 | compare_log = logging.getLogger('compare') | 43 | compare_log = logging.getLogger('compare') |
| 45 | log_base = '[Compare]' | 44 | log_base = '[Compare]' |
| ... | @@ -2414,6 +2413,7 @@ def se_compare_license_id(license_en, id_res_list, field_list): | ... | @@ -2414,6 +2413,7 @@ def se_compare_license_id(license_en, id_res_list, field_list): |
| 2414 | if is_find: | 2413 | if is_find: |
| 2415 | break | 2414 | break |
| 2416 | 2415 | ||
| 2416 | result_field_list.clear() | ||
| 2417 | for idx, (name, value) in enumerate(field_list): | 2417 | for idx, (name, value) in enumerate(field_list): |
| 2418 | # if ocr_field == consts.MVI_OCR_FIELD and name == consts.SE_NEW_ADD_FIELD[9]: | 2418 | # if ocr_field == consts.MVI_OCR_FIELD and name == consts.SE_NEW_ADD_FIELD[9]: |
| 2419 | # ocr_str = getattr(cp, consts.ZW_METHOD)( | 2419 | # ocr_str = getattr(cp, consts.ZW_METHOD)( |
| ... | @@ -2493,6 +2493,7 @@ def se_compare_license_id(license_en, id_res_list, field_list): | ... | @@ -2493,6 +2493,7 @@ def se_compare_license_id(license_en, id_res_list, field_list): |
| 2493 | result_field_list.append((name, value, result, ocr_str, img_path, error_type, compare_logic[name][3])) | 2493 | result_field_list.append((name, value, result, ocr_str, img_path, error_type, compare_logic[name][3])) |
| 2494 | 2494 | ||
| 2495 | if not is_find: | 2495 | if not is_find: |
| 2496 | result_field_list.clear() | ||
| 2496 | for name, value in field_list: | 2497 | for name, value in field_list: |
| 2497 | if isinstance(value, list): | 2498 | if isinstance(value, list): |
| 2498 | value = json.dumps(value, ensure_ascii=False) | 2499 | 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 | ... | @@ -3200,135 +3201,3 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True |
| 3200 | '[error={4}]'.format(log_base, application_entity, application_id, ocr_res_id, | 3201 | '[error={4}]'.format(log_base, application_entity, application_id, ocr_res_id, |
| 3201 | traceback.format_exc())) | 3202 | traceback.format_exc())) |
| 3202 | 3203 | ||
| 3203 | |||
| 3204 | # pos接口 | ||
| 3205 | def pos_compare(pos_content, application_id, application_entity, uniq_seq, ocr_res_id=None, is_ca=True, is_cms=False): | ||
| 3206 | # POS: application_id, application_entity, uniq_seq, None | ||
| 3207 | # OCR: application_id, business_type(application_entity), None, ocr_res_id | ||
| 3208 | compare_log.info('{0} [pos_compare] [entity={1}] [id={2}] [uniq_seq={3}] [is_ca={4}] ' | ||
| 3209 | '[is_cms={5}]'.format(log_base, application_entity, application_id, uniq_seq, | ||
| 3210 | is_ca, is_cms)) | ||
| 3211 | |||
| 3212 | # 根据application_id查找最新的比对信息,如果没有,结束 | ||
| 3213 | # if is_ca: | ||
| 3214 | # comparison_class = HILComparisonInfo if application_entity == consts.HIL_PREFIX else AFCComparisonInfo | ||
| 3215 | # else: | ||
| 3216 | # if application_entity == consts.HIL_PREFIX: | ||
| 3217 | # comparison_class = HILSECMSInfo if is_cms else HILSEComparisonInfo | ||
| 3218 | # else: | ||
| 3219 | # comparison_class = AFCSECMSInfo if is_cms else AFCSEComparisonInfo | ||
| 3220 | # last_obj = comparison_class.objects.filter(application_id=application_id).last() | ||
| 3221 | # if last_obj is None: | ||
| 3222 | # compare_log.info('{0} [comparison info empty] [entity={1}] [id={2}] [uniq_seq={3}] ' | ||
| 3223 | # '[is_ca={4}] [is_cms]={5}'.format(log_base, application_entity, application_id, uniq_seq, | ||
| 3224 | # is_ca, is_cms)) | ||
| 3225 | # return | ||
| 3226 | |||
| 3227 | # 根据application_id查找OCR累计结果指定license字段,如果没有,结束 | ||
| 3228 | if is_ca: | ||
| 3229 | result_class = HILOCRResult if application_entity == consts.HIL_PREFIX else AFCOCRResult | ||
| 3230 | ca_ocr_res_dict = dict() | ||
| 3231 | else: | ||
| 3232 | result_class = HILSEOCRResult if application_entity == consts.HIL_PREFIX else AFCSEOCRResult | ||
| 3233 | ca_result_class = HILOCRResult if application_entity == consts.HIL_PREFIX else AFCOCRResult | ||
| 3234 | # if ocr_res_id is None: | ||
| 3235 | ca_ocr_res_dict = ca_result_class.objects.filter(application_id=application_id).values( | ||
| 3236 | *consts.CA_ADD_COMPARE_FIELDS).first() | ||
| 3237 | # else: | ||
| 3238 | # ca_ocr_res_dict = ca_result_class.objects.filter(id=ocr_res_id).values( | ||
| 3239 | # *consts.CA_ADD_COMPARE_FIELDS).first() | ||
| 3240 | ocr_res_dict = result_class.objects.filter(application_id=application_id).values(*consts.COMPARE_FIELDS).first() | ||
| 3241 | if ocr_res_dict is None: | ||
| 3242 | compare_log.info('{0} [ocr info empty] [entity={1}] [id={2}] [uniq_seq={3}] [ocr_res_id={4}] ' | ||
| 3243 | '[is_ca={5}] [is_cms]={6}'.format(log_base, application_entity, application_id, | ||
| 3244 | uniq_seq, ocr_res_id, is_ca, is_cms)) | ||
| 3245 | return | ||
| 3246 | |||
| 3247 | pos_content_obj = json.loads(pos_content) | ||
| 3248 | if is_ca: | ||
| 3249 | # 比对逻辑 | ||
| 3250 | # compare_info = get_ca_compare_info(pos_content_obj) | ||
| 3251 | # compare_result, total_fields, failed_count = ca_compare_process(compare_info, ocr_res_dict) | ||
| 3252 | # compare_log.info('{0} [CA] [compare success] [entity={1}] [id={2}] [ocr_res_id={3}] [result={4}]'.format( | ||
| 3253 | # log_base, application_entity, application_id, ocr_res_id, compare_result)) | ||
| 3254 | # ca_compare(application_id, application_entity, ocr_res_id, pos_content_obj, ocr_res_dict) | ||
| 3255 | compare_result = pos.PosCompare.ca_compare(pos_content_obj, ocr_res_dict) | ||
| 3256 | else: | ||
| 3257 | id_res_list = [] | ||
| 3258 | for field_name in consts.CA_ADD_COMPARE_FIELDS: | ||
| 3259 | if field_name == consts.IC_OCR_FIELD: | ||
| 3260 | id_res_list.append(ocr_res_dict.get(field_name)) | ||
| 3261 | id_res_list.append(ca_ocr_res_dict.get(field_name) if isinstance(ca_ocr_res_dict, dict) else None) | ||
| 3262 | |||
| 3263 | if isinstance(ca_ocr_res_dict, dict) and isinstance(ca_ocr_res_dict.get(field_name), str): | ||
| 3264 | tmp_ca_result = json.loads(ca_ocr_res_dict.get(field_name)) | ||
| 3265 | if isinstance(ocr_res_dict.get(field_name), str): | ||
| 3266 | tmp_se_result = json.loads(ocr_res_dict.get(field_name)) | ||
| 3267 | tmp_ca_result.extend(tmp_se_result) | ||
| 3268 | ocr_res_dict[field_name] = json.dumps(tmp_ca_result) | ||
| 3269 | # auto settlement | ||
| 3270 | # auto_class = HILAutoSettlement if application_entity == consts.HIL_PREFIX else AFCAutoSettlement | ||
| 3271 | # auto_obj = auto_class.objects.filter(application_id=application_id, on_off=True).first() | ||
| 3272 | # bank_class = HILbankVerification if application_entity == consts.HIL_PREFIX else AFCbankVerification | ||
| 3273 | # ignore_bank = bank_class.objects.filter(application_id=application_id, on_off=True).exists() | ||
| 3274 | # if auto_obj is not None: | ||
| 3275 | # 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) | ||
| 3276 | # else: | ||
| 3277 | # auto_result = None | ||
| 3278 | # | ||
| 3279 | # 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) | ||
| 3280 | # | ||
| 3281 | # if auto_obj is not None: | ||
| 3282 | # try: | ||
| 3283 | # auto_obj.ocr_whole_result_pass = full_result | ||
| 3284 | # auto_obj.save() | ||
| 3285 | # compare_log.info('{0} [Auto SE] [result save success] [entity={1}] [id={2}] [ocr_res_id={3}]'.format( | ||
| 3286 | # log_base, application_entity, application_id, ocr_res_id)) | ||
| 3287 | # except Exception as e: | ||
| 3288 | # compare_log.error('{0} [Auto SE] [result save error] [entity={1}] [id={2}] [ocr_res_id={3}] ' | ||
| 3289 | # '[error={4}]'.format(log_base, application_entity, application_id, ocr_res_id, | ||
| 3290 | # traceback.format_exc())) | ||
| 3291 | |||
| 3292 | # result_table = HILCACompareResult if application_entity == consts.HIL_PREFIX else AFCCACompareResult | ||
| 3293 | # res_obj = result_table.objects.filter(application_id=application_id).first() | ||
| 3294 | compare_result = pos.PosCompare.se_compare(pos_content_obj, ocr_res_dict, id_res_list=id_res_list) | ||
| 3295 | return pos_result_output(compare_result) | ||
| 3296 | |||
| 3297 | |||
| 3298 | # pos输出解析 | ||
| 3299 | def pos_result_output(compare_result): | ||
| 3300 | result_obj = json.loads(compare_result) | ||
| 3301 | license_map = dict() | ||
| 3302 | for item in result_obj: | ||
| 3303 | license_en = item.get("License") | ||
| 3304 | if license_map.get(license_en): | ||
| 3305 | license_map.get(license_en).append(item) | ||
| 3306 | else: | ||
| 3307 | info_items = [item] | ||
| 3308 | license_map[license_en] = info_items | ||
| 3309 | |||
| 3310 | is_pass = True | ||
| 3311 | particulars = [] | ||
| 3312 | for license, license_items in license_map.items(): | ||
| 3313 | particular = {"object_name": license} | ||
| 3314 | # license_comments = OCR_COMPARE_COMMENT.get(license) | ||
| 3315 | # if not license_comments: | ||
| 3316 | # continue | ||
| 3317 | fields = [] | ||
| 3318 | particular["fields"] = fields | ||
| 3319 | for license_item in license_items: | ||
| 3320 | field = dict() | ||
| 3321 | field["input"] = license_item.get("Input") | ||
| 3322 | field["ocr"] = license_item.get("OCR") | ||
| 3323 | field["field_is_pass"] = license_item.get("Result") == 'Y' | ||
| 3324 | if not field["field_is_pass"]: | ||
| 3325 | is_pass = False | ||
| 3326 | field["comments"] = license_item.get('comments', '') | ||
| 3327 | fields.append(field) | ||
| 3328 | particular["fields"] = fields | ||
| 3329 | particulars.append(particular) | ||
| 3330 | |||
| 3331 | return { | ||
| 3332 | "is_pass": is_pass, | ||
| 3333 | "particulars": particulars | ||
| 3334 | } | ... | ... |
| ... | @@ -29,8 +29,6 @@ class Comparison: | ... | @@ -29,8 +29,6 @@ class Comparison: |
| 29 | 29 | ||
| 30 | self.RESULT_Y = 'Y' | 30 | self.RESULT_Y = 'Y' |
| 31 | self.RESULT_N = 'N' | 31 | self.RESULT_N = 'N' |
| 32 | self.RESULT_N1 = 'N1' | ||
| 33 | self.RESULT_N2 = 'N2' | ||
| 34 | self.RESULT_NA = 'NA' | 32 | self.RESULT_NA = 'NA' |
| 35 | 33 | ||
| 36 | self.TRANS_MAP = { | 34 | self.TRANS_MAP = { |
| ... | @@ -610,19 +608,19 @@ class Comparison: | ... | @@ -610,19 +608,19 @@ class Comparison: |
| 610 | return self.RESULT_N | 608 | return self.RESULT_N |
| 611 | return self.se_date_compare_2(input_str, ocr_date_set.pop(), three_month=True) | 609 | return self.se_date_compare_2(input_str, ocr_date_set.pop(), three_month=True) |
| 612 | 610 | ||
| 613 | def se_date_compare_pos(self, input_str, ocr_str, **kwargs): | 611 | # def se_date_compare_pos(self, input_str, ocr_str, **kwargs): |
| 614 | try: | 612 | # try: |
| 615 | ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d").date() | 613 | # ocr_date = datetime.strptime(ocr_str, "%Y-%m-%d").date() |
| 616 | today = datetime.now().date() | 614 | # today = datetime.now().date() |
| 617 | if ocr_date < today: | 615 | # if ocr_date < today: |
| 618 | return self.RESULT_N1 | 616 | # return self.RESULT_N1 |
| 619 | elif today <= ocr_date <= (today + timedelta(days=8)): | 617 | # elif today <= ocr_date <= (today + timedelta(days=8)): |
| 620 | return self.RESULT_N2 | 618 | # return self.RESULT_N2 |
| 621 | elif ocr_date > (today + timedelta(days=8)): | 619 | # elif ocr_date > (today + timedelta(days=8)): |
| 622 | return self.RESULT_Y | 620 | # return self.RESULT_Y |
| 623 | except Exception as e: | 621 | # except Exception as e: |
| 624 | return self.RESULT_N | 622 | # return self.RESULT_N |
| 625 | return self.RESULT_N | 623 | # return self.RESULT_N |
| 626 | 624 | ||
| 627 | 625 | ||
| 628 | cp = Comparison() | 626 | cp = Comparison() | ... | ... |
src/pos/pos.py
deleted
100644 → 0
| 1 | from apps.doc import consts | ||
| 2 | import json | ||
| 3 | from common.tools.des import decode_des | ||
| 4 | from pos import pos_consts | ||
| 5 | from settings import conf | ||
| 6 | from pos_compare import SECompare, CACompare | ||
| 7 | |||
| 8 | empty_str = '' | ||
| 9 | des_key = conf.CMS_DES_KEY | ||
| 10 | empty_error_type = 1000 | ||
| 11 | |||
| 12 | |||
| 13 | def ca_compare_process(compare_info, ocr_res_dict): | ||
| 14 | # individualCusInfo | ||
| 15 | # corporateCusInfo | ||
| 16 | # usedCarInfo | ||
| 17 | compare_result = [] | ||
| 18 | total_fields = 0 | ||
| 19 | failed_count = 0 | ||
| 20 | |||
| 21 | for info_key, info_value in compare_info.items(): | ||
| 22 | if info_key == 'individualCusInfo': | ||
| 23 | for idx, license_list in info_value.items(): | ||
| 24 | for license_dict in license_list: | ||
| 25 | for license_en, field_list in license_dict.items(): | ||
| 26 | result_field_list, field_img_path_dict = CACompare.ca_compare_license(license_en, ocr_res_dict, field_list) | ||
| 27 | for name, value, result, ocr_str, img_path, error_type, reason in result_field_list: | ||
| 28 | total_fields += 1 | ||
| 29 | if result == consts.RESULT_N: | ||
| 30 | failed_count += 1 | ||
| 31 | compare_result.append( | ||
| 32 | { | ||
| 33 | consts.HEAD_LIST[0]: info_key, | ||
| 34 | consts.HEAD_LIST[1]: idx, | ||
| 35 | consts.HEAD_LIST[2]: license_en, | ||
| 36 | consts.HEAD_LIST[3]: name, | ||
| 37 | consts.HEAD_LIST[4]: value, | ||
| 38 | consts.HEAD_LIST[5]: ocr_str, | ||
| 39 | consts.HEAD_LIST[6]: result, | ||
| 40 | consts.HEAD_LIST[7]: field_img_path_dict.get(name, empty_str), | ||
| 41 | consts.HEAD_LIST[8]: img_path, | ||
| 42 | consts.HEAD_LIST[9]: error_type, | ||
| 43 | "comments": reason if result == consts.RESULT_N else '' | ||
| 44 | } | ||
| 45 | ) | ||
| 46 | else: | ||
| 47 | for license_en, field_list in info_value.items(): | ||
| 48 | result_field_list, field_img_path_dict = CACompare.ca_compare_license(license_en, ocr_res_dict, field_list) | ||
| 49 | for name, value, result, ocr_str, img_path, error_type, reason in result_field_list: | ||
| 50 | total_fields += 1 | ||
| 51 | if result == consts.RESULT_N: | ||
| 52 | failed_count += 1 | ||
| 53 | compare_result.append( | ||
| 54 | { | ||
| 55 | consts.HEAD_LIST[0]: info_key, | ||
| 56 | consts.HEAD_LIST[1]: "0", | ||
| 57 | consts.HEAD_LIST[2]: license_en, | ||
| 58 | consts.HEAD_LIST[3]: name, | ||
| 59 | consts.HEAD_LIST[4]: value, | ||
| 60 | consts.HEAD_LIST[5]: ocr_str, | ||
| 61 | consts.HEAD_LIST[6]: result, | ||
| 62 | consts.HEAD_LIST[7]: field_img_path_dict.get(name, empty_str), | ||
| 63 | consts.HEAD_LIST[8]: img_path, | ||
| 64 | consts.HEAD_LIST[9]: error_type, | ||
| 65 | "comments": reason if result == consts.RESULT_N else '' | ||
| 66 | } | ||
| 67 | ) | ||
| 68 | return compare_result, total_fields, failed_count | ||
| 69 | |||
| 70 | |||
| 71 | def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto, id_res_list): | ||
| 72 | # individualCusInfo | ||
| 73 | # corporateCusInfo | ||
| 74 | # vehicleInfo | ||
| 75 | # bankInfo | ||
| 76 | compare_result = [] | ||
| 77 | total_fields = 0 | ||
| 78 | failed_count = 0 | ||
| 79 | successful_at_this_level = True | ||
| 80 | failure_reason = {} | ||
| 81 | cn_reason_list = [] | ||
| 82 | rpa_failure_reason = {} | ||
| 83 | |||
| 84 | for info_key, info_value in compare_info.items(): | ||
| 85 | if info_key in ['individualCusInfo', 'applicantInformation']: | ||
| 86 | for idx, license_list in info_value.items(): | ||
| 87 | for license_dict in license_list: | ||
| 88 | for license_en, field_list in license_dict.items(): | ||
| 89 | strip_list = [] | ||
| 90 | for a, b in field_list: | ||
| 91 | if isinstance(b, str): | ||
| 92 | strip_list.append((a, b.strip())) | ||
| 93 | elif isinstance(b, list): | ||
| 94 | c = [] | ||
| 95 | for i in b: | ||
| 96 | if isinstance(i, str): | ||
| 97 | c.append(i.strip()) | ||
| 98 | else: | ||
| 99 | c.append(i) | ||
| 100 | strip_list.append((a, c)) | ||
| 101 | else: | ||
| 102 | strip_list.append((a, b)) | ||
| 103 | failure_field = [] | ||
| 104 | # 身份证先SE正反面,后CA正反面 | ||
| 105 | if license_en == consts.ID_EN: | ||
| 106 | result_field_list, no_ocr_result, field_img_path_dict = SECompare.se_compare_license_id( | ||
| 107 | license_en, id_res_list, strip_list) | ||
| 108 | else: | ||
| 109 | result_field_list, no_ocr_result, field_img_path_dict = SECompare.se_compare_license( | ||
| 110 | license_en, ocr_res_dict, strip_list) | ||
| 111 | for name, value, result, ocr_str, img_path, error_type, cn_reason in result_field_list: | ||
| 112 | if license_en not in consts.SKIP_CARD or not no_ocr_result: | ||
| 113 | total_fields += 1 | ||
| 114 | if result == consts.RESULT_N: | ||
| 115 | failed_count += 1 | ||
| 116 | successful_at_this_level = False | ||
| 117 | failure_field.append(name) | ||
| 118 | cn_reason_list.append(cn_reason) | ||
| 119 | rpa_failure_reason.setdefault(cn_reason, []).append(value) | ||
| 120 | compare_result.append( | ||
| 121 | { | ||
| 122 | consts.HEAD_LIST[0]: info_key, | ||
| 123 | consts.HEAD_LIST[1]: idx, | ||
| 124 | consts.HEAD_LIST[2]: license_en, | ||
| 125 | consts.HEAD_LIST[3]: name, | ||
| 126 | consts.HEAD_LIST[4]: value, | ||
| 127 | consts.HEAD_LIST[5]: ocr_str, | ||
| 128 | consts.HEAD_LIST[6]: result, | ||
| 129 | consts.HEAD_LIST[7]: field_img_path_dict.get(name, empty_str), | ||
| 130 | consts.HEAD_LIST[8]: img_path, | ||
| 131 | consts.HEAD_LIST[9]: error_type, | ||
| 132 | "comments": cn_reason if result == consts.RESULT_N else '' | ||
| 133 | } | ||
| 134 | ) | ||
| 135 | if len(failure_field) > 0: | ||
| 136 | failure_reason.setdefault(info_key, []).append(';'.join(failure_field)) | ||
| 137 | else: | ||
| 138 | for license_en, field_list in info_value.items(): | ||
| 139 | strip_list = [] | ||
| 140 | for a, b in field_list: | ||
| 141 | if isinstance(b, str): | ||
| 142 | strip_list.append((a, b.strip())) | ||
| 143 | elif isinstance(b, list): | ||
| 144 | c = [] | ||
| 145 | for i in b: | ||
| 146 | if isinstance(i, str): | ||
| 147 | c.append(i.strip()) | ||
| 148 | else: | ||
| 149 | c.append(i) | ||
| 150 | strip_list.append((a, c)) | ||
| 151 | else: | ||
| 152 | strip_list.append((a, b)) | ||
| 153 | failure_field = [] | ||
| 154 | if license_en == consts.MVC34_EN: | ||
| 155 | result_field_list, field_img_path_dict = SECompare.se_mvc34_compare(license_en, ocr_res_dict, strip_list) | ||
| 156 | elif license_en in [consts.HIL_CONTRACT_1_EN, consts.HIL_CONTRACT_2_EN, consts.HIL_CONTRACT_3_EN, consts.AFC_CONTRACT_EN]: | ||
| 157 | result_field_list, field_img_path_dict = SECompare.se_contract_compare(license_en, ocr_res_dict, strip_list, is_gsyh) | ||
| 158 | elif license_en == consts.BS_EN: | ||
| 159 | result_field_list, field_img_path_dict = SECompare.se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto) | ||
| 160 | else: | ||
| 161 | result_field_list, _, field_img_path_dict = SECompare.se_compare_license(license_en, ocr_res_dict, strip_list) | ||
| 162 | |||
| 163 | for name, value, result, ocr_str, img_path, error_type, cn_reason in result_field_list: | ||
| 164 | total_fields += 1 | ||
| 165 | if result == consts.RESULT_N: | ||
| 166 | # if license_en != consts.MVI_EN or name != consts.SE_NEW_ADD_FIELD[9]: | ||
| 167 | successful_at_this_level = False | ||
| 168 | failed_count += 1 | ||
| 169 | failure_field.append(name) | ||
| 170 | if isinstance(cn_reason, str): | ||
| 171 | cn_reason_list.append(cn_reason) | ||
| 172 | rpa_failure_reason.setdefault(cn_reason, []).append(value) | ||
| 173 | elif isinstance(cn_reason, list): | ||
| 174 | cn_reason_list.extend(cn_reason) | ||
| 175 | rpa_failure_reason.setdefault('、'.join(cn_reason), []).append(value) | ||
| 176 | compare_result.append( | ||
| 177 | { | ||
| 178 | consts.HEAD_LIST[0]: info_key, | ||
| 179 | consts.HEAD_LIST[1]: "0", | ||
| 180 | consts.HEAD_LIST[2]: license_en, | ||
| 181 | consts.HEAD_LIST[3]: name, | ||
| 182 | consts.HEAD_LIST[4]: value, | ||
| 183 | consts.HEAD_LIST[5]: ocr_str, | ||
| 184 | consts.HEAD_LIST[6]: result, | ||
| 185 | consts.HEAD_LIST[7]: field_img_path_dict.get(name, empty_str), | ||
| 186 | consts.HEAD_LIST[8]: img_path, | ||
| 187 | consts.HEAD_LIST[9]: error_type, | ||
| 188 | "comments": cn_reason if result == consts.RESULT_N else '' | ||
| 189 | } | ||
| 190 | ) | ||
| 191 | if len(failure_field) > 0: | ||
| 192 | failure_reason.setdefault(info_key, []).append(';'.join(failure_field)) | ||
| 193 | if failed_count == 0: | ||
| 194 | failure_reason_str = '' | ||
| 195 | cn_failure_reason_str = '' | ||
| 196 | bs_failure_reason_str = '' | ||
| 197 | else: | ||
| 198 | reason_list = [] | ||
| 199 | for key, value in failure_reason.items(): | ||
| 200 | if len(value) > 0: | ||
| 201 | value_str = json.dumps(value) | ||
| 202 | reason_list.append('{0}: {1}'.format(key, value_str)) | ||
| 203 | failure_reason_str = '、'.join(reason_list) | ||
| 204 | |||
| 205 | tmp_set = set() | ||
| 206 | last_cn_reason_list = [] | ||
| 207 | bs_cn_reason_list = [] | ||
| 208 | for i in cn_reason_list: | ||
| 209 | if i in tmp_set: | ||
| 210 | continue | ||
| 211 | # elif i in consts.BS_REASON: | ||
| 212 | # tmp_set.add(i) | ||
| 213 | # bs_cn_reason_list.append(i) | ||
| 214 | else: | ||
| 215 | tmp_set.add(i) | ||
| 216 | last_cn_reason_list.append(i) | ||
| 217 | cn_failure_reason_str = '\n'.join(last_cn_reason_list) | ||
| 218 | bs_failure_reason_str = '\n'.join(bs_cn_reason_list) | ||
| 219 | return compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str, cn_failure_reason_str, bs_failure_reason_str, rpa_failure_reason | ||
| 220 | |||
| 221 | |||
| 222 | class CorporateCusInfo: | ||
| 223 | def __init__(self): | ||
| 224 | self.customerType = '' | ||
| 225 | self.companyName = '' | ||
| 226 | self.firstIdType = '' | ||
| 227 | self.firstIdNo = '' | ||
| 228 | self.businessLicenseNo = '' | ||
| 229 | self.organizationCreditCode = '' | ||
| 230 | self.taxRegistrationCertificateNo = '' | ||
| 231 | self.establishmentDate = '' | ||
| 232 | self.incorporationDate = '' | ||
| 233 | self.businessLicenseDueDate = '' | ||
| 234 | self.legalRepName = '' | ||
| 235 | self.organizationType = '' | ||
| 236 | self.fleetCustomer = False | ||
| 237 | self.beneficialOwnerName = '' | ||
| 238 | self.beneficialOwnerIdType = '' | ||
| 239 | self.beneficialOwnerIdNo = '' | ||
| 240 | self.beneficialOwnerIdExpiryDate = '' | ||
| 241 | |||
| 242 | |||
| 243 | class VehicleInfo: | ||
| 244 | def __int__(self): | ||
| 245 | self.vehicleStatus = '' | ||
| 246 | self.vehicleTransactionAmount = 0.0 | ||
| 247 | self.vinNo = '' | ||
| 248 | self.dealer = '' | ||
| 249 | self.showRoom = '' | ||
| 250 | self.agencyDealer = '' | ||
| 251 | self.option = 0.0 | ||
| 252 | self.msrp = 0.0 | ||
| 253 | self.totalAmount = 0.0 | ||
| 254 | |||
| 255 | |||
| 256 | class InsuranceInfo: | ||
| 257 | def __init__(self): | ||
| 258 | self.insuredAmount = 0.0 | ||
| 259 | self.insuranceType = '' | ||
| 260 | self.startDate = '' | ||
| 261 | self.endDate = '' | ||
| 262 | |||
| 263 | |||
| 264 | class BankInfo: | ||
| 265 | def __init__(self): | ||
| 266 | self.bankName = '' | ||
| 267 | self.branchName = '' | ||
| 268 | self.applicantType = '' | ||
| 269 | self.accountHolderName = '' | ||
| 270 | self.accountNo = '' | ||
| 271 | self.accountNo = 'bankVerificationStatus' | ||
| 272 | self.isAllDocUploaded = False | ||
| 273 | |||
| 274 | |||
| 275 | class QuotationtInfo: | ||
| 276 | def __init__(self): | ||
| 277 | self.totalLoanAmount = 0.0 | ||
| 278 | self.loanTerm = 0 | ||
| 279 | self.vehiclePrincipal = 0.0 | ||
| 280 | self.associatedServicePrincipal = 0.0 | ||
| 281 | self.mortgageType = '' | ||
| 282 | self.associatedServiceInfo = [] | ||
| 283 | self.monthlyPaymentInfo = [] | ||
| 284 | |||
| 285 | |||
| 286 | class CompareInfoResult: | ||
| 287 | def __init__(self): | ||
| 288 | self.compare_info = None | ||
| 289 | self.is_cdfl_bo = False # 车贷分离,主借 | ||
| 290 | self.is_cdfl_co = False # 车贷分离,共借 | ||
| 291 | self.is_gsyh = False # 是否工商银行 | ||
| 292 | |||
| 293 | |||
| 294 | class CompareInfo: | ||
| 295 | def __init__(self, pos_content): | ||
| 296 | self.pos_content = pos_content | ||
| 297 | self.compare_info = {} | ||
| 298 | self.main_role_info = {} | ||
| 299 | self.company_info_list = [] | ||
| 300 | self.company_info = None | ||
| 301 | self.vehicleTransactionAmount = 0.0 | ||
| 302 | self.customer_name = '' | ||
| 303 | self.id_num = None | ||
| 304 | self.application_id = pos_content.get('applicationId', '') | ||
| 305 | self.application_version = pos_content.get('applicationVersion', 0) | ||
| 306 | self.application_entity = pos_content.get('applicationEntity', '') | ||
| 307 | self.is_auto_settlement = pos_content.get('isAutoSettlement', '') | ||
| 308 | self.first_submmison_date = pos_content.get('firstSubmmisonDate', '') | ||
| 309 | self.product_group_name = pos_content.get('productGroup', '') | ||
| 310 | self.account_holder_name = '' | ||
| 311 | |||
| 312 | self.is_cdfl_bo = False # 车贷分离,主借 | ||
| 313 | self.is_cdfl_co = False # 车贷分离,共借 | ||
| 314 | self.is_gsyh = False # 是否工商银行 | ||
| 315 | |||
| 316 | self.vin_no = '' | ||
| 317 | self.bank_name = '' | ||
| 318 | self.account_no = '' | ||
| 319 | |||
| 320 | def get(self, ignore_bank=False): | ||
| 321 | individual_cus_info = self.pos_content.get('individualCusInfo', []) | ||
| 322 | corporate_cus_info = self.pos_content.get('corporateCusInfo', {}) | ||
| 323 | vehicle_info = self.pos_content.get('vehicleInfo', {}) | ||
| 324 | insurance_info = self.pos_content.get('insuranceInfo', {}) | ||
| 325 | bank_info = self.pos_content.get('bankInfo', {}) | ||
| 326 | quotationt_info = self.pos_content.get('quotationtInfo', {}) | ||
| 327 | |||
| 328 | self.getApplicantInformation(individual_cus_info, corporate_cus_info) | ||
| 329 | self.getVehicleInfo(vehicle_info) | ||
| 330 | self.getBankInfo(bank_info, ignore_bank) | ||
| 331 | self.getContract(quotationt_info) | ||
| 332 | self.getOther(quotationt_info, insurance_info) | ||
| 333 | |||
| 334 | compare_result = CompareInfoResult() | ||
| 335 | compare_result.compare_info = self.compare_info | ||
| 336 | compare_result.is_cdfl_co = self.is_cdfl_co | ||
| 337 | compare_result.is_cdfl_bo = self.is_cdfl_bo | ||
| 338 | compare_result.is_gsyh = self.is_gsyh | ||
| 339 | return compare_result | ||
| 340 | |||
| 341 | def getApplicantInformation(self, individual_cus_info, corporate_cus_info): | ||
| 342 | individual_info_dict = {} | ||
| 343 | for individual_info in individual_cus_info: | ||
| 344 | all_id_num = [] | ||
| 345 | license_dict = {} | ||
| 346 | customer_name = individual_info.get('customerName', '').strip() | ||
| 347 | self.customer_name = customer_name | ||
| 348 | legal_name = corporate_cus_info.get('legalRepName', '') | ||
| 349 | establishment_date = corporate_cus_info.get('establishmentDate', '') | ||
| 350 | |||
| 351 | # 车贷分离判断 | ||
| 352 | is_corporate = individual_info.get('selfEmployedSubType', '') == 'Corporate' | ||
| 353 | if individual_info['applicantType'] == consts.APPLICANT_TYPE_ORDER[1] and is_corporate: | ||
| 354 | self.is_cdfl_co = True | ||
| 355 | if individual_info['applicantType'] == consts.APPLICANT_TYPE_ORDER[0] and not is_corporate: | ||
| 356 | self.is_cdfl_bo = True | ||
| 357 | |||
| 358 | if individual_info.get('idType') in consts.SE_CMS_FIRST_ID_FIELD_MAPPING: | ||
| 359 | license_en, is_prc = consts.SE_CMS_FIRST_ID_FIELD_MAPPING[individual_info['idType']] | ||
| 360 | # ['customerName', 'idNum', 'dateOfBirth', 'idExpiryDate', 'hukouProvince'] | ||
| 361 | id_num = decode_des(individual_info.get('idNum', ''), des_key) | ||
| 362 | self.id_num = id_num | ||
| 363 | field_input = [('customerName', customer_name), | ||
| 364 | ('idNum', id_num), | ||
| 365 | ('idExpiryDate', individual_info.get('idExpiryDate', ''))] | ||
| 366 | # if is_prc: | ||
| 367 | # field_input.append(('hukouProvince', province)) | ||
| 368 | # field_input.append(('真伪', consts.IC_RES_MAPPING.get(1))) | ||
| 369 | license_dict[license_en] = field_input | ||
| 370 | all_id_num.append(id_num) | ||
| 371 | |||
| 372 | if len(all_id_num) > 0: | ||
| 373 | self.main_role_info.setdefault(individual_info['applicantType'], []).append( | ||
| 374 | (customer_name, '、'.join(all_id_num), all_id_num[0]) | ||
| 375 | ) | ||
| 376 | |||
| 377 | if len(license_dict) > 0: | ||
| 378 | individual_info_dict.setdefault(individual_info['applicantType'], []).append(license_dict) | ||
| 379 | self.compare_info['applicantInformation'] = individual_info_dict | ||
| 380 | |||
| 381 | def getVehicleInfo(self, vehicleInfo): | ||
| 382 | main_name = main_id_all = main_id = '' | ||
| 383 | for applicant_type in consts.APPLICANT_TYPE_ORDER: | ||
| 384 | if applicant_type in self.main_role_info: | ||
| 385 | main_name, main_id_all, main_id = self.main_role_info[applicant_type][0] | ||
| 386 | # hmh_name, _, hmh_id = main_role_info[applicant_type][0] | ||
| 387 | break | ||
| 388 | |||
| 389 | # co_name = co_id = bo_name = bo_id = '' | ||
| 390 | # if is_cdfl: | ||
| 391 | # co_name, _, co_id = main_role_info[consts.APPLICANT_TYPE_ORDER[1]][0] | ||
| 392 | # bo_name, _, bo_id = main_role_info[consts.APPLICANT_TYPE_ORDER[0]][0] | ||
| 393 | |||
| 394 | co_name = co_id = bo_name = bo_id = '' | ||
| 395 | is_cdfl = self.is_cdfl_bo and self.is_cdfl_co | ||
| 396 | if is_cdfl: | ||
| 397 | if len(self.main_role_info.get(consts.APPLICANT_TYPE_ORDER[1], [])) > 0: | ||
| 398 | co_name, _, co_id = self.main_role_info[consts.APPLICANT_TYPE_ORDER[1]][0] | ||
| 399 | else: | ||
| 400 | co_name = co_id = '' | ||
| 401 | if len(self.main_role_info.get(consts.APPLICANT_TYPE_ORDER[0], [])) > 0: | ||
| 402 | bo_name, _, bo_id = self.main_role_info[consts.APPLICANT_TYPE_ORDER[0]][0] | ||
| 403 | else: | ||
| 404 | bo_name = bo_id = '' | ||
| 405 | |||
| 406 | # dda_name_list = [] | ||
| 407 | # dda_num_list = [] | ||
| 408 | if len(self.company_info_list) > 0: | ||
| 409 | # tmp_idx = 1 | ||
| 410 | self.company_info = self.company_info_list[0] | ||
| 411 | else: | ||
| 412 | # tmp_idx = 0 | ||
| 413 | self.company_info = None | ||
| 414 | |||
| 415 | vehicle_info = {} | ||
| 416 | vehicle_field_input = [] | ||
| 417 | vehicle_status = vehicleInfo.get('vehicleStatus', '') | ||
| 418 | first_submission_date = self.first_submmison_date | ||
| 419 | vin_no = vehicleInfo.get('vinNo', '') | ||
| 420 | self.vin_no = vin_no | ||
| 421 | # amount = str(vehicleInfo.get('vehiclePrice', '0.0')) | ||
| 422 | amount = str(vehicleInfo.get('vehicleTransactionAmount', '0.0')) | ||
| 423 | self.vehicleTransactionAmount = amount | ||
| 424 | dealer_name_list = vehicleInfo.get('dealer', '').split() | ||
| 425 | dealer_name = '' if len(dealer_name_list) == 0 else dealer_name_list[-1] | ||
| 426 | self.dealer_name = dealer_name | ||
| 427 | issuer_dealer = vehicleInfo.get('fapiaoIssuerDealer', '').strip() | ||
| 428 | # 新车发票---------------------------------------------------------------------------------------------------------- | ||
| 429 | if vehicle_status == 'New': | ||
| 430 | vehicle_field_input.append(('vinNo', vin_no)) | ||
| 431 | vehicle_field_input.append(('dealer', dealer_name if len(issuer_dealer) == 0 else issuer_dealer)) | ||
| 432 | vehicle_field_input.append(('vehicleTransactionAmount', amount)) | ||
| 433 | |||
| 434 | if isinstance(self.company_info, tuple): | ||
| 435 | vehicle_field_input.append( | ||
| 436 | (consts.SE_NEW_ADD_FIELD[0], co_name if self.is_cdfl else self.company_info[0])) # 车贷分离 | ||
| 437 | vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[1], self.co_id if self.is_cdfl else self.company_info[1])) # 车贷分离 | ||
| 438 | else: | ||
| 439 | vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[0], co_name if is_cdfl else main_name)) # 车贷分离 | ||
| 440 | vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[1], co_id if is_cdfl else main_id)) # 车贷分离 | ||
| 441 | vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[2], first_submission_date)) | ||
| 442 | # vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[3], consts.SE_STAMP_VALUE)) | ||
| 443 | vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[4], consts.SE_FPL_VALUE)) | ||
| 444 | bhsj = float(amount) / 1.13 | ||
| 445 | # vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[5], consts.SPLIT_STR.join([ | ||
| 446 | # format(bhsj, '.2f'), | ||
| 447 | # format(float(amount) - bhsj, '.2f'), | ||
| 448 | # consts.RESULT_Y | ||
| 449 | # ]))) | ||
| 450 | vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[7], format(bhsj, '.2f'))) | ||
| 451 | vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[8], format(float(amount) - bhsj, '.2f'))) | ||
| 452 | vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[9], consts.RESULT_Y)) | ||
| 453 | vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[6], consts.SE_LAYOUT_VALUE)) | ||
| 454 | vehicle_field_input.append(("firstSubmmisonDate", self.first_submmison_date)) | ||
| 455 | vehicle_field_input.append(("productGroupName", self.product_group_name)) | ||
| 456 | |||
| 457 | if self.product_group_name.find('官方认证二手车') == -1 and self.product_group_name.find('非官方认证二手车') == -1: | ||
| 458 | vehicle_info[consts.MVI_EN] = vehicle_field_input | ||
| 459 | |||
| 460 | # 二手车发票、交易凭证、绿本------------------------------------------------------------------------------------------ | ||
| 461 | # else: | ||
| 462 | # gb_field_input = [ | ||
| 463 | # ('vinNo', vin_no), | ||
| 464 | # ] | ||
| 465 | # gb34_field_input = [] | ||
| 466 | # jypz_field_input = [] | ||
| 467 | # vehicle_field_input.append(('vinNo', vin_no)) | ||
| 468 | # vehicle_field_input.append(('vehicleTransactionAmount', amount)) | ||
| 469 | # if isinstance(company_info, tuple): | ||
| 470 | # vehicle_field_input.append( | ||
| 471 | # (consts.SE_NEW_ADD_FIELD[0], co_name if is_cdfl else company_info[0])) # 车贷分离 | ||
| 472 | # vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[1], co_id if is_cdfl else company_info[1])) # 车贷分离 | ||
| 473 | # jypz_field_input.append((consts.SE_NEW_ADD_FIELD[0], co_name if is_cdfl else company_info[0])) # 车贷分离 | ||
| 474 | # jypz_field_input.append((consts.SE_NEW_ADD_FIELD[1], co_id if is_cdfl else company_info[1])) # 车贷分离 | ||
| 475 | # gb34_field_input.append((consts.SE_GB_USED_FIELD[0], co_name if is_cdfl else company_info[0])) # 车贷分离 | ||
| 476 | # gb34_field_input.append((consts.SE_GB_USED_FIELD[1], co_id if is_cdfl else company_info[1])) # 车贷分离 | ||
| 477 | # else: | ||
| 478 | # vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[0], co_name if is_cdfl else main_name)) # 车贷分离 | ||
| 479 | # vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[1], co_id if is_cdfl else main_id_all)) # 车贷分离 | ||
| 480 | # jypz_field_input.append((consts.SE_NEW_ADD_FIELD[0], co_name if is_cdfl else main_name)) # 车贷分离 | ||
| 481 | # jypz_field_input.append((consts.SE_NEW_ADD_FIELD[1], co_id if is_cdfl else main_id_all)) # 车贷分离 | ||
| 482 | # gb34_field_input.append((consts.SE_GB_USED_FIELD[0], co_name if is_cdfl else main_name)) # 车贷分离 | ||
| 483 | # gb34_field_input.append((consts.SE_GB_USED_FIELD[1], co_id if is_cdfl else main_id_all)) # 车贷分离 | ||
| 484 | # gb34_field_input.append((consts.SE_GB_USED_FIELD[2], first_submission_date)) | ||
| 485 | # vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[2], first_submission_date)) | ||
| 486 | # # vehicle_field_input.append((consts.SE_NEW_ADD_FIELD[3], consts.SE_STAMP_VALUE)) | ||
| 487 | # jypz_field_input.append(('dealerName', dealer_name)) | ||
| 488 | # jypz_field_input.append(('vinNo', vin_no)) | ||
| 489 | # jypz_field_input.append(('vehicleTransactionAmount', amount)) | ||
| 490 | # jypz_field_input.append((consts.SE_GB_USED_FIELD[2], first_submission_date)) | ||
| 491 | # if fp_group.find('Non OCU Product Group') != -1: | ||
| 492 | # jypz_field_input.append(('type', consts.JYPZ_TYPE_1)) | ||
| 493 | # elif fp_group.find('OCU Product Group') != -1: | ||
| 494 | # jypz_field_input.append(('type', consts.JYPZ_TYPE_2)) | ||
| 495 | # | ||
| 496 | # vehicle_info[consts.MVC_EN] = gb_field_input | ||
| 497 | # vehicle_info[consts.MVC34_EN] = gb34_field_input | ||
| 498 | # if not detect_list[0]: | ||
| 499 | # vehicle_info[consts.UCI_EN] = vehicle_field_input | ||
| 500 | # if not detect_list[1]: | ||
| 501 | # vehicle_info[consts.JYPZ_EN] = jypz_field_input | ||
| 502 | # if detect_list[0] and detect_list[1]: | ||
| 503 | # vehicle_info[consts.UCI_EN] = vehicle_field_input | ||
| 504 | self.compare_info['vehicleInfo'] = vehicle_info | ||
| 505 | |||
| 506 | def getBankInfo(self, bankInfo, ignore_bank): | ||
| 507 | bank_info = {} | ||
| 508 | bank_name = bankInfo.get('bankName', '') | ||
| 509 | self.bank_name = bank_name | ||
| 510 | account_no = decode_des(bankInfo.get('accountNo', ''), des_key) | ||
| 511 | self.account_no = account_no | ||
| 512 | account_holder_name = bankInfo.get('accountHolderName', '') | ||
| 513 | self.account_holder_name = account_holder_name | ||
| 514 | self.is_gsyh = True if '工商' in bank_name else False | ||
| 515 | bank_verification_status = bankInfo.get('bankVerificationStatus', '') | ||
| 516 | if isinstance(self.company_info, tuple) and self.company_info[0] == account_holder_name: | ||
| 517 | pass | ||
| 518 | elif not ignore_bank: | ||
| 519 | bank_field_input = [ | ||
| 520 | ('accountNo', account_no), | ||
| 521 | ('bankName', bank_name), | ||
| 522 | ('type', consts.BC_TYPE_VALUE) # 是否为借记卡 | ||
| 523 | ] | ||
| 524 | if bank_verification_status != 'PASS': | ||
| 525 | # pos 银行卡校验失败后需要走ocr校验 | ||
| 526 | if bank_verification_status == 'FAIL' or bank_verification_status == 'N/A': | ||
| 527 | bank_field_input.append(('bankVerificationStatus', '')) | ||
| 528 | bank_info[consts.BC_EN] = bank_field_input | ||
| 529 | # DDA------------------------------------------------------------------------------------------------------------ | ||
| 530 | # if is_gsyh or not detect_list[-1]: | ||
| 531 | # dda_field_input = [ | ||
| 532 | # ('applicationId(1)', last_obj.application_id), | ||
| 533 | # ('applicationId(2)', last_obj.application_id), | ||
| 534 | # ('bankName', bank_name), | ||
| 535 | # ('companyName', consts.HIL_COMPANY_NAME if application_entity in consts.HIL_SET else consts.AFC_COMPANY_NAME), | ||
| 536 | # ('customerName', dda_name), | ||
| 537 | # ('idNum', dda_num), | ||
| 538 | # ('accountHolderName', account_holder_name), | ||
| 539 | # ('accountNo', account_no), | ||
| 540 | # ] | ||
| 541 | # bank_info[consts.DDA_EN] = dda_field_input | ||
| 542 | if len(bank_info) > 0: | ||
| 543 | self.compare_info['bankInfo'] = bank_info | ||
| 544 | |||
| 545 | def getContract(self, quotationtInfo): | ||
| 546 | # ASP ------------------------------------------------------------------------------------------------------- | ||
| 547 | asp_list = [] | ||
| 548 | is_asp = False | ||
| 549 | insurance_price = None | ||
| 550 | gzs_price = None | ||
| 551 | have_other_asp = False | ||
| 552 | fin_total = 0 | ||
| 553 | if str(quotationtInfo.get('associatedServicePrincipal', '0.00')) != '0.00': | ||
| 554 | is_asp = True | ||
| 555 | # for asp_info in cms_info.get('associatedServices', []): | ||
| 556 | for asp_info in quotationtInfo.get('associatedServiceInfo', []): | ||
| 557 | tmp_asp_name = asp_info.get('service') | ||
| 558 | if isinstance(tmp_asp_name, str) and len(tmp_asp_name) > 0: | ||
| 559 | asp_list.append( | ||
| 560 | ( | ||
| 561 | tmp_asp_name, | ||
| 562 | asp_info.get('amount', '0.00'), | ||
| 563 | asp_info.get('financedAmount', '0.00') | ||
| 564 | ) | ||
| 565 | ) | ||
| 566 | fin_total += float(asp_info.get('financedAmount', '0.00')) | ||
| 567 | # 购置税 | ||
| 568 | if tmp_asp_name.find(consts.GZS_NAME) != -1: | ||
| 569 | gzs_price = asp_info.get('amount', '0.00') | ||
| 570 | # 保单费合计 | ||
| 571 | elif tmp_asp_name.find('机动车辆保险') != -1: | ||
| 572 | insurance_price = asp_info.get('amount', '0.00') | ||
| 573 | else: | ||
| 574 | have_other_asp = True | ||
| 575 | |||
| 576 | asp_list.append( | ||
| 577 | ( | ||
| 578 | consts.ASP_SUM_NAME, | ||
| 579 | '', | ||
| 580 | # fin_total, | ||
| 581 | format(fin_total, '.2f'), | ||
| 582 | ) | ||
| 583 | ) | ||
| 584 | |||
| 585 | # CMS Vehicle Price / 1.13 * 10 % | ||
| 586 | if isinstance(gzs_price, str): | ||
| 587 | try: | ||
| 588 | tmp_gzs_list = [float(self.vehicleTransactionAmount) * 0.1 / 1.13, float(gzs_price)] | ||
| 589 | except Exception as e: | ||
| 590 | tmp_gzs_list = [self.vehicleTransactionAmount, gzs_price] | ||
| 591 | else: | ||
| 592 | tmp_gzs_list = [self.vehicleTransactionAmount, ] | ||
| 593 | |||
| 594 | main_name = main_id_all = main_id = '' | ||
| 595 | for applicant_type in consts.APPLICANT_TYPE_ORDER: | ||
| 596 | if applicant_type in self.main_role_info: | ||
| 597 | main_name, main_id_all, main_id = self.main_role_info[applicant_type][0] | ||
| 598 | # hmh_name, _, hmh_id = main_role_info[applicant_type][0] | ||
| 599 | break | ||
| 600 | |||
| 601 | contract_info = {} | ||
| 602 | if self.application_entity in consts.HIL_SET: | ||
| 603 | # HIL合同 售后回租合同 -------------------------------------------------------------------------------------- | ||
| 604 | hil_contract_1_input = [ | ||
| 605 | # (pos_consts.SE_HIL_CON_1_FIELD[0], [full_no] if online_sign else full_no), | ||
| 606 | # (pos_consts.SE_HIL_CON_1_FIELD[1], full_no), | ||
| 607 | # (pos_consts.SE_HIL_CON_1_FIELD[2], self.vin_no), | ||
| 608 | # (pos_consts.SE_HIL_CON_1_FIELD[3], self.dealer_name), | ||
| 609 | # (pos_consts.SE_HIL_CON_1_FIELD[4], self.vehicleTransactionAmount), | ||
| 610 | # (pos_consts.SE_HIL_CON_1_FIELD[5], | ||
| 611 | # str(cms_info.get('financialInformation', {}).get('originationPrincipal', '0.0'))), | ||
| 612 | # (pos_consts.SE_HIL_CON_1_FIELD[6], str(quotationtInfo.get('loanTerm', '0'))), | ||
| 613 | # (pos_consts.SE_HIL_CON_1_FIELD[7], schedule_list_str), | ||
| 614 | # (pos_consts.SE_HIL_CON_1_FIELD[11], self.account_no), | ||
| 615 | # (pos_consts.SE_HIL_CON_1_FIELD[12], self.account_holder_name), | ||
| 616 | # (pos_consts.SE_HIL_CON_1_FIELD[13], self.bank_name), | ||
| 617 | ] | ||
| 618 | |||
| 619 | # if is_asp: | ||
| 620 | # # asp各项 | ||
| 621 | # hil_contract_1_input.append((consts.SE_HIL_CON_1_FIELD[8], asp_list)) | ||
| 622 | # # 购置税校验 | ||
| 623 | # if isinstance(gzs_price, str): | ||
| 624 | # hil_contract_1_input.append( | ||
| 625 | # (consts.SE_HIL_CON_1_FIELD[9], tmp_gzs_list)) | ||
| 626 | # # 非购置税非车辆保险的其他asp | ||
| 627 | # if have_other_asp: | ||
| 628 | # hil_contract_1_input.append((consts.SE_HIL_CON_1_FIELD[15], 'N')) | ||
| 629 | # | ||
| 630 | # if isinstance(self.company_info, tuple): | ||
| 631 | # if self.is_cdfl: | ||
| 632 | # hil_contract_1_input.append((consts.SE_HIL_CON_1_FIELD[14], self.company_info[2])) | ||
| 633 | # else: | ||
| 634 | # hil_contract_1_input.append((consts.SE_HIL_CON_1_FIELD[10], self.company_info[2])) | ||
| 635 | # contract_info[consts.HIL_CONTRACT_1_EN] = hil_contract_1_input | ||
| 636 | |||
| 637 | # HIL合同 车辆租赁抵押合同 -------------------------------------------------------------------------------------- | ||
| 638 | hil_contract_2_input = [ | ||
| 639 | (pos_consts.SE_HIL_CON_2_FIELD[0], self.application_id), | ||
| 640 | (pos_consts.SE_HIL_CON_2_FIELD[1], self.vin_no), | ||
| 641 | ('文档', '文档'), | ||
| 642 | ] | ||
| 643 | contract_info[consts.HIL_CONTRACT_2_EN] = hil_contract_2_input | ||
| 644 | self.compare_info['contract'] = contract_info | ||
| 645 | else: | ||
| 646 | # AFC合同------------------------------------------------------------------------------------------------------ | ||
| 647 | vehicle_principal_str = str(quotationtInfo.get('vehiclePrincipal', '0.0')) | ||
| 648 | afc_contract_input = [] | ||
| 649 | # if is_asp: | ||
| 650 | # afc_contract_input = [ | ||
| 651 | # (consts.SE_AFC_CON_FIELD[0], full_no), | ||
| 652 | # ] | ||
| 653 | # else: | ||
| 654 | # afc_contract_input = [ | ||
| 655 | # (consts.SE_AFC_CON_FIELD[23], full_no), | ||
| 656 | # ] | ||
| 657 | |||
| 658 | # afc_contract_input.extend([ | ||
| 659 | # (consts.SE_AFC_CON_FIELD[1], self.vehicleTransactionAmount), | ||
| 660 | # (consts.SE_AFC_CON_FIELD[2], self.vin_no), | ||
| 661 | # (consts.SE_AFC_CON_FIELD[3], | ||
| 662 | # str(cms_info.get('financialInformation', {}).get('originationPrincipal', '0.0'))), | ||
| 663 | # (consts.SE_AFC_CON_FIELD[4], str(cms_info.get('terms', '0'))), | ||
| 664 | # (consts.SE_AFC_CON_FIELD[5], vehicle_principal_str), | ||
| 665 | # (consts.SE_AFC_CON_FIELD[6], | ||
| 666 | # str(quotationtInfo.get('associatedServicePrincipal', '0.0'))), | ||
| 667 | # (consts.SE_AFC_CON_FIELD[7], self.vehicleTransactionAmount), | ||
| 668 | # (consts.SE_AFC_CON_FIELD[8], self.vin_no), | ||
| 669 | # (consts.SE_AFC_CON_FIELD[9], self.dealer_name), | ||
| 670 | # (consts.SE_AFC_CON_FIELD[10], | ||
| 671 | # str(cms_info.get('financialInformation', {}).get('originationPrincipal', '0.0'))), | ||
| 672 | # (consts.SE_AFC_CON_FIELD[11], vehicle_principal_str), | ||
| 673 | # (consts.SE_AFC_CON_FIELD[12], | ||
| 674 | # str(cms_info.get('financialInformation', {}).get('associatedServicePrincipal', '0.0'))), | ||
| 675 | # (consts.SE_AFC_CON_FIELD[13], str(cms_info.get('terms', '0'))), | ||
| 676 | # (consts.SE_AFC_CON_FIELD[14], self.account_no), | ||
| 677 | # (consts.SE_AFC_CON_FIELD[15], self.account_holder_name), | ||
| 678 | # (consts.SE_AFC_CON_FIELD[16], self.bank_name), | ||
| 679 | # (consts.SE_AFC_CON_FIELD[17], schedule_list_str), | ||
| 680 | # ]) | ||
| 681 | |||
| 682 | # if is_asp: | ||
| 683 | # afc_contract_input.append((consts.SE_AFC_CON_FIELD[20], asp_list)) | ||
| 684 | # afc_contract_input.append((consts.SE_AFC_CON_FIELD[22], asp_list)) | ||
| 685 | # # 购置税校验 | ||
| 686 | # if isinstance(gzs_price, str): | ||
| 687 | # afc_contract_input.append( | ||
| 688 | # (consts.SE_AFC_CON_FIELD[21], tmp_gzs_list)) | ||
| 689 | # # 非购置税非车辆保险的其他asp | ||
| 690 | # if have_other_asp: | ||
| 691 | # afc_contract_input.append((consts.SE_AFC_CON_FIELD[24], 'N')) | ||
| 692 | # else: | ||
| 693 | # afc_contract_input.pop(5) | ||
| 694 | # afc_contract_input.pop(5) | ||
| 695 | # afc_contract_input.pop(9) | ||
| 696 | # afc_contract_input.pop(9) | ||
| 697 | |||
| 698 | # contract_info[consts.AFC_CONTRACT_EN] = afc_contract_input | ||
| 699 | self.compare_info['contract'] = contract_info | ||
| 700 | |||
| 701 | def getOther(self, quotationtInfo, insurance_info): | ||
| 702 | main_name = main_id_all = main_id = '' | ||
| 703 | for applicant_type in consts.APPLICANT_TYPE_ORDER: | ||
| 704 | if applicant_type in self.main_role_info: | ||
| 705 | main_name, main_id_all, main_id = self.main_role_info[applicant_type][0] | ||
| 706 | # hmh_name, _, hmh_id = main_role_info[applicant_type][0] | ||
| 707 | break | ||
| 708 | |||
| 709 | other_info = {} | ||
| 710 | if quotationtInfo.get('mortgageType', '') == 'MOTGF': | ||
| 711 | hmh_field_input = [ | ||
| 712 | (consts.SE_HMH_FIELD[0], self.customer_name), | ||
| 713 | (consts.SE_HMH_FIELD[1], self.id_num), | ||
| 714 | (consts.SE_HMH_FIELD[2], self.application_id), | ||
| 715 | (consts.SE_HMH_FIELD[3], self.application_entity), | ||
| 716 | (consts.SE_HMH_FIELD[4], consts.SE_STAMP_VALUE), | ||
| 717 | ('文档', '') | ||
| 718 | ] | ||
| 719 | other_info[consts.HMH_EN] = hmh_field_input | ||
| 720 | |||
| 721 | # 保险 | ||
| 722 | if insurance_info.get('insuranceType') != 'Waive Insurance' and insurance_info.get('insuranceType') != 'Insurance After Check': | ||
| 723 | if insurance_info.get('insuranceType') == 'Comprehensive Insurance': | ||
| 724 | other_info[consts.BD_EN] = [ | ||
| 725 | (consts.SE_BD_FIELD[0], self.customer_name), | ||
| 726 | (consts.SE_BD_FIELD[1], self.id_num) | ||
| 727 | (consts.SE_BD_FIELD[2], self.vin_no) | ||
| 728 | ('文档', '') | ||
| 729 | ] | ||
| 730 | if len(other_info) > 0: | ||
| 731 | self.compare_info['other'] = other_info | ||
| 732 | |||
| 733 | |||
| 734 | class PosCompare: | ||
| 735 | @staticmethod | ||
| 736 | def ca_compare(pos_content, ocr_res_dict): | ||
| 737 | compare_info_result = CompareInfo(pos_content).get() | ||
| 738 | compare_result, total_fields, failed_count = ca_compare_process(compare_info_result, ocr_res_dict) | ||
| 739 | return compare_result | ||
| 740 | |||
| 741 | @staticmethod | ||
| 742 | def se_compare(pos_content, ocr_res_dict, id_res_list=None): | ||
| 743 | compare_info_result = CompareInfo(pos_content).get() | ||
| 744 | compare_result, total_fields, failed_count, successful_at_this_level, failure_reason_str, \ | ||
| 745 | cn_failure_reason_str, bs_failure_reason_str, rpa_failure_reason = se_compare_process( | ||
| 746 | compare_info_result.compare_info, ocr_res_dict, compare_info_result.is_gsyh, False, id_res_list) | ||
| 747 | return compare_result |
src/pos/pos_compare.py
deleted
100644 → 0
| 1 | from common.tools.comparison import cp | ||
| 2 | import os | ||
| 3 | from pos import pos_consts | ||
| 4 | from apps.doc import consts | ||
| 5 | import json | ||
| 6 | from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType | ||
| 7 | import time | ||
| 8 | |||
| 9 | empty_str = '' | ||
| 10 | empty_error_type = 1000 | ||
| 11 | |||
| 12 | |||
| 13 | class SECompare: | ||
| 14 | @staticmethod | ||
| 15 | def se_mvc34_compare(license_en, ocr_res_dict, field_list): | ||
| 16 | ocr_field, compare_logic, _ = pos_consts.SE_COMPARE_FIELD[license_en] | ||
| 17 | ocr_res_str = ocr_res_dict.get(ocr_field) | ||
| 18 | |||
| 19 | is_find = False | ||
| 20 | result_field_list = [] | ||
| 21 | field_img_path_dict = dict() | ||
| 22 | |||
| 23 | if ocr_res_str is not None: | ||
| 24 | ocr_res_list = json.loads(ocr_res_str) | ||
| 25 | length = len(ocr_res_list) | ||
| 26 | |||
| 27 | page34_date_dict = dict() | ||
| 28 | first_res = None | ||
| 29 | for res_idx in range(length - 1, -1, -1): | ||
| 30 | if consts.TRANSFER_DATE in ocr_res_list[res_idx]: | ||
| 31 | img_path = ocr_res_list[res_idx].get(consts.IMG_PATH_KEY_2, '') | ||
| 32 | section_img_path = ocr_res_list[res_idx].get(consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 33 | for idx, transfer_date in enumerate(ocr_res_list[res_idx].get(consts.TRANSFER_DATE, [])): | ||
| 34 | try: | ||
| 35 | transfer_name = ocr_res_list[res_idx].get(consts.TRANSFER_NAME, [])[idx] | ||
| 36 | except Exception as e: | ||
| 37 | transfer_name = empty_str | ||
| 38 | try: | ||
| 39 | transfer_num = ocr_res_list[res_idx].get(consts.TRANSFER_NUM, [])[idx] | ||
| 40 | except Exception as e: | ||
| 41 | transfer_num = empty_str | ||
| 42 | try: | ||
| 43 | position_info_date = ocr_res_list[res_idx].get(consts.ALL_POSITION_KEY_2, dict()).get( | ||
| 44 | consts.TRANSFER_DATE, [])[idx] | ||
| 45 | except Exception as e: | ||
| 46 | position_info_date = {} | ||
| 47 | try: | ||
| 48 | position_info_name = ocr_res_list[res_idx].get(consts.ALL_POSITION_KEY_2, dict()).get( | ||
| 49 | consts.TRANSFER_NAME, [])[idx] | ||
| 50 | except Exception as e: | ||
| 51 | position_info_name = {} | ||
| 52 | try: | ||
| 53 | position_info_num = ocr_res_list[res_idx].get(consts.ALL_POSITION_KEY_2, dict()).get( | ||
| 54 | consts.TRANSFER_NUM, [])[idx] | ||
| 55 | except Exception as e: | ||
| 56 | position_info_num = {} | ||
| 57 | core_info = { | ||
| 58 | consts.TRANSFER_NAME: transfer_name, | ||
| 59 | consts.TRANSFER_NUM: transfer_num, | ||
| 60 | consts.TRANSFER_DATE: transfer_date, | ||
| 61 | consts.IMG_PATH_KEY_2: img_path, | ||
| 62 | consts.SECTION_IMG_PATH_KEY_2: section_img_path, | ||
| 63 | consts.ALL_POSITION_KEY: { | ||
| 64 | consts.TRANSFER_NAME: position_info_name, | ||
| 65 | consts.TRANSFER_NUM: position_info_num, | ||
| 66 | consts.TRANSFER_DATE: position_info_date, | ||
| 67 | }, | ||
| 68 | } | ||
| 69 | page34_date_dict.setdefault(transfer_date, []).append(core_info) | ||
| 70 | if first_res is None: | ||
| 71 | first_res = core_info | ||
| 72 | |||
| 73 | max_date = None | ||
| 74 | for date_tmp in page34_date_dict.keys(): | ||
| 75 | try: | ||
| 76 | max_date_part = time.strptime(date_tmp, "%Y-%m-%d") | ||
| 77 | except Exception as e: | ||
| 78 | pass | ||
| 79 | else: | ||
| 80 | if max_date is None or max_date_part > max_date: | ||
| 81 | max_date = max_date_part | ||
| 82 | |||
| 83 | if max_date is not None or first_res is not None: | ||
| 84 | is_find = True | ||
| 85 | ocr_res = first_res if max_date is None else page34_date_dict[time.strftime('%Y-%m-%d', max_date)][0] | ||
| 86 | failed_field = [] | ||
| 87 | base_img_path = ocr_res.get(consts.IMG_PATH_KEY_2, '') | ||
| 88 | for name, value in field_list: | ||
| 89 | ocr_str = ocr_res.get(compare_logic[name][0]) | ||
| 90 | if not isinstance(ocr_str, str): | ||
| 91 | result = consts.RESULT_N | ||
| 92 | ocr_str = empty_str | ||
| 93 | else: | ||
| 94 | result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2]) | ||
| 95 | img_path = base_img_path if result == consts.RESULT_N else empty_str | ||
| 96 | error_type = empty_error_type if result == consts.RESULT_Y else ErrorType.OCR.value | ||
| 97 | result_field_list.append( | ||
| 98 | (name, value, result, ocr_str, img_path, error_type, compare_logic[name][3])) | ||
| 99 | |||
| 100 | if result == consts.RESULT_N: | ||
| 101 | failed_field.append(name) | ||
| 102 | |||
| 103 | # section_img_path = ocr_res.get(consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 104 | # if len(failed_field) > 0 and os.path.exists(section_img_path): | ||
| 105 | # info = ocr_res.get(consts.ALL_POSITION_KEY, {}) | ||
| 106 | # try: | ||
| 107 | # last_img = img_process(section_img_path, {}, 0) | ||
| 108 | # except Exception as e: | ||
| 109 | # for field in failed_field: | ||
| 110 | # field_img_path_dict[field] = base_img_path | ||
| 111 | # else: | ||
| 112 | # pre, suf = os.path.splitext(section_img_path) | ||
| 113 | # for field in failed_field: | ||
| 114 | # try: | ||
| 115 | # res_field = compare_logic[field][0] | ||
| 116 | # is_valid, coord_tuple = field_build_coordinates(info.get(res_field, {})) | ||
| 117 | # if is_valid: | ||
| 118 | # save_path = '{0}_{1}{2}'.format(pre, field, suf) | ||
| 119 | # field_img = last_img[coord_tuple[0]:coord_tuple[1], coord_tuple[2]:coord_tuple[3], | ||
| 120 | # :] | ||
| 121 | # cv2.imwrite(save_path, field_img) | ||
| 122 | # field_img_path_dict[field] = save_path | ||
| 123 | # else: | ||
| 124 | # field_img_path_dict[field] = base_img_path | ||
| 125 | # except Exception as e: | ||
| 126 | # field_img_path_dict[field] = base_img_path | ||
| 127 | |||
| 128 | if not is_find: | ||
| 129 | for name, value in field_list: | ||
| 130 | result_field_list.append((name, value, consts.RESULT_N, empty_str, empty_str, ErrorType.NF.value, | ||
| 131 | '{0}未找到'.format(license_en))) | ||
| 132 | |||
| 133 | return result_field_list, field_img_path_dict | ||
| 134 | |||
| 135 | @staticmethod | ||
| 136 | def se_contract_compare(license_en, ocr_res_dict, strip_list, is_gsyh): | ||
| 137 | ocr_field, compare_logic, _ = pos_consts.SE_COMPARE_FIELD[license_en] | ||
| 138 | ocr_res_str = ocr_res_dict.get(ocr_field) | ||
| 139 | |||
| 140 | result_field_list = [] | ||
| 141 | field_img_path_dict = dict() | ||
| 142 | |||
| 143 | ocr_res = dict() | ||
| 144 | if ocr_res_str is not None: | ||
| 145 | ocr_res_list = json.loads(ocr_res_str) | ||
| 146 | ocr_res = ocr_res_list.pop() | ||
| 147 | |||
| 148 | for name, value in strip_list: | ||
| 149 | # 购置税校验 | ||
| 150 | # if name == consts.SE_AFC_CON_FIELD[21]: | ||
| 151 | # if len(value) == 3: | ||
| 152 | # reason = [] | ||
| 153 | # gzs_verify = value[1] >= value[2] | ||
| 154 | # if gzs_verify: | ||
| 155 | # if value[0] == consts.GZS_STATUS[0]: | ||
| 156 | # reason.append(consts.GZS_REASON_1) | ||
| 157 | # result = consts.RESULT_N | ||
| 158 | # else: | ||
| 159 | # result = consts.RESULT_Y | ||
| 160 | # else: | ||
| 161 | # if value[0] == consts.GZS_STATUS[0]: | ||
| 162 | # reason.append(consts.GZS_REASON_1) | ||
| 163 | # result = consts.RESULT_N | ||
| 164 | # reason.append(consts.GZS_REASON_2) | ||
| 165 | # else: | ||
| 166 | # result = consts.RESULT_N | ||
| 167 | # reason = consts.GZS_REASON_1 | ||
| 168 | # ocr_str = empty_str | ||
| 169 | # else: | ||
| 170 | |||
| 171 | if name == consts.SE_HIL_CON_1_FIELD[9] or name == consts.SE_HIL_CON_1_FIELD[15] or \ | ||
| 172 | name == consts.SE_AFC_CON_FIELD[21] or name == consts.SE_AFC_CON_FIELD[24]: | ||
| 173 | ocr_str_or_list = '' | ||
| 174 | else: | ||
| 175 | ocr_str_or_list = ocr_res.get(compare_logic[name][0]) | ||
| 176 | |||
| 177 | # 招商银行特殊 | ||
| 178 | # if ocr_str_or_list is None and license_en == consts.AFC_CONTRACT_EN \ | ||
| 179 | # and is_gsyh is True and name in consts.CON_BANK_FIELD: | ||
| 180 | # result = consts.RESULT_Y | ||
| 181 | # ocr_str = empty_str | ||
| 182 | # reason = compare_logic[name][3] | ||
| 183 | # 见证人日期 | ||
| 184 | if name == consts.SE_AFC_CON_FIELD[19]: | ||
| 185 | if not isinstance(ocr_str_or_list, str) or len(ocr_str_or_list) == 0: | ||
| 186 | result = consts.RESULT_N | ||
| 187 | ocr_str = empty_str | ||
| 188 | else: | ||
| 189 | is_find_date = False | ||
| 190 | all_date_list = [ocr_str_or_list] | ||
| 191 | for date_name in consts.AFC_HT_DATE_FIELDS: | ||
| 192 | all_date_list.append(ocr_res.get(compare_logic[date_name][0], '')) | ||
| 193 | if not is_find_date and ocr_str_or_list == ocr_res.get(compare_logic[date_name][0], ''): | ||
| 194 | is_find_date = True | ||
| 195 | result = consts.RESULT_Y if is_find_date else consts.RESULT_N | ||
| 196 | ocr_str = json.dumps(all_date_list, ensure_ascii=False) | ||
| 197 | reason = compare_logic[name][3] | ||
| 198 | elif isinstance(ocr_str_or_list, str) or isinstance(ocr_str_or_list, list): | ||
| 199 | # if is_gsyh is True and name in consts.CON_BANK_FIELD: | ||
| 200 | # update_args = {'is_gsyh': is_gsyh} | ||
| 201 | # for k, v in compare_logic[name][2].items(): | ||
| 202 | # update_args[k] = v | ||
| 203 | # else: | ||
| 204 | # update_args = compare_logic[name][2] | ||
| 205 | if isinstance(ocr_str_or_list, list): | ||
| 206 | # no-asp 合同编号-每页(no-asp) | ||
| 207 | if name == consts.SE_AFC_CON_FIELD[23]: | ||
| 208 | ocr_str_or_list.pop() | ||
| 209 | ocr_str = json.dumps(ocr_str_or_list, ensure_ascii=False) | ||
| 210 | else: | ||
| 211 | ocr_str_or_list = ocr_str_or_list.strip() | ||
| 212 | ocr_str = ocr_str_or_list | ||
| 213 | result = getattr(cp, compare_logic[name][1])(value, ocr_str_or_list, **compare_logic[name][2]) | ||
| 214 | reason = compare_logic[name][3] | ||
| 215 | else: | ||
| 216 | result = consts.RESULT_N | ||
| 217 | ocr_str = empty_str | ||
| 218 | reason = compare_logic[name][3] | ||
| 219 | |||
| 220 | # img_path = empty_str | ||
| 221 | if name not in compare_logic: | ||
| 222 | img_path = empty_str | ||
| 223 | else: | ||
| 224 | img_path = ocr_res.get(consts.IMG_PATH_KEY, {}).get(compare_logic[name][0], | ||
| 225 | empty_str) if result == consts.RESULT_N else empty_str | ||
| 226 | error_type = empty_error_type if result == consts.RESULT_Y else ErrorType.OCR.value | ||
| 227 | if isinstance(value, list): | ||
| 228 | value = json.dumps(value, ensure_ascii=False) | ||
| 229 | result_field_list.append((name, value, result, ocr_str, img_path, error_type, reason)) | ||
| 230 | else: | ||
| 231 | for name, value in strip_list: | ||
| 232 | if isinstance(value, list): | ||
| 233 | value = json.dumps(value, ensure_ascii=False) | ||
| 234 | result_field_list.append((name, value, consts.RESULT_N, empty_str, empty_str, ErrorType.NF.value, | ||
| 235 | '{0}未找到'.format(license_en))) | ||
| 236 | |||
| 237 | # if ocr_res_str is not None: | ||
| 238 | # img_map = {} | ||
| 239 | # for name, _, result, _, img_path, _, _ in result_field_list: | ||
| 240 | # if result == consts.RESULT_N: | ||
| 241 | # img_map.setdefault(img_path, []).append(name) | ||
| 242 | # for path, field_list in img_map.items(): | ||
| 243 | # if os.path.exists(path): | ||
| 244 | # pre, suf = os.path.splitext(path) | ||
| 245 | # last_img = cv2.imread(path) | ||
| 246 | # for field_idx, field in enumerate(field_list): | ||
| 247 | # try: | ||
| 248 | # save_path = '{0}_{1}{2}'.format(pre, str(field_idx), suf) | ||
| 249 | # section_position_list = ocr_res.get(consts.ALL_POSITION_KEY, {}).get(field, []) | ||
| 250 | # if isinstance(section_position_list, list) and len(section_position_list) == 4: | ||
| 251 | # field_img = last_img[section_position_list[1]: section_position_list[3], | ||
| 252 | # section_position_list[0]: section_position_list[2], :] | ||
| 253 | # cv2.imwrite(save_path, field_img) | ||
| 254 | # field_img_path_dict[field] = save_path | ||
| 255 | # else: | ||
| 256 | # field_img_path_dict[field] = path | ||
| 257 | # except Exception as e: | ||
| 258 | # field_img_path_dict[field] = path | ||
| 259 | |||
| 260 | return result_field_list, field_img_path_dict | ||
| 261 | |||
| 262 | @staticmethod | ||
| 263 | def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto): | ||
| 264 | # 主共借至少提供一个 | ||
| 265 | # 有担保人,担保人必须提供。主共借没有时,修改comment:人工查看担保人亲属关系 | ||
| 266 | |||
| 267 | if is_auto: | ||
| 268 | ocr_field, compare_logic, _ = consts.SE_COMPARE_FIELD_AUTO[license_en] | ||
| 269 | else: | ||
| 270 | ocr_field, compare_logic, _ = pos_consts.SE_COMPARE_FIELD[license_en] | ||
| 271 | ocr_res_str = ocr_res_dict.get(ocr_field) | ||
| 272 | |||
| 273 | result_field_list = [] | ||
| 274 | field_img_path_dict = dict() | ||
| 275 | |||
| 276 | if ocr_res_str is not None: | ||
| 277 | pre_field_list = strip_list[:3] | ||
| 278 | dbr1_field_list = strip_list[3:6] | ||
| 279 | dbr2_field_list = strip_list[6:] | ||
| 280 | |||
| 281 | ocr_res_list = json.loads(ocr_res_str) | ||
| 282 | # length = len(ocr_res_list) | ||
| 283 | |||
| 284 | # 主共借人 | ||
| 285 | pre_best_res = {} | ||
| 286 | max_correct_count = 0 | ||
| 287 | verify_list = [] | ||
| 288 | verify_false_idx_list = [] | ||
| 289 | |||
| 290 | for tmp_idx, ocr_res in enumerate(ocr_res_list): | ||
| 291 | correct_count = 0 | ||
| 292 | pre_tmp_res_part = {} | ||
| 293 | verify_bool = ocr_res.get('verify', True) | ||
| 294 | verify_list.append(verify_bool) | ||
| 295 | if not verify_bool: | ||
| 296 | verify_false_idx_list.append(str(tmp_idx + 1)) | ||
| 297 | for idx, (name, value) in enumerate(pre_field_list): | ||
| 298 | ocr_str_or_list = ocr_res.get(compare_logic[name][0]) | ||
| 299 | if isinstance(ocr_str_or_list, str) or isinstance(ocr_str_or_list, list) \ | ||
| 300 | or isinstance(ocr_str_or_list, int): | ||
| 301 | result = getattr(cp, compare_logic[name][1])(value, ocr_str_or_list, **compare_logic[name][2]) | ||
| 302 | if isinstance(ocr_str_or_list, list): | ||
| 303 | ocr_str = json.dumps(ocr_str_or_list, ensure_ascii=False) | ||
| 304 | else: | ||
| 305 | ocr_str = ocr_str_or_list | ||
| 306 | reason = compare_logic[name][3] | ||
| 307 | else: | ||
| 308 | result = consts.RESULT_N | ||
| 309 | ocr_str = empty_str | ||
| 310 | reason = compare_logic[name][3] | ||
| 311 | |||
| 312 | if idx == 0 and result == consts.RESULT_N: | ||
| 313 | break | ||
| 314 | |||
| 315 | if result == consts.RESULT_Y: | ||
| 316 | correct_count += 1 | ||
| 317 | pre_tmp_res_part[name] = (result, ocr_str, reason) | ||
| 318 | |||
| 319 | if correct_count > 0 and correct_count >= max_correct_count: | ||
| 320 | max_correct_count = correct_count | ||
| 321 | pre_best_res = pre_tmp_res_part | ||
| 322 | |||
| 323 | # 真伪 | ||
| 324 | if not is_auto: | ||
| 325 | name = '真伪' | ||
| 326 | result = consts.RESULT_Y if all(verify_list) else consts.RESULT_N | ||
| 327 | reason = '第{0}份银行流水疑似造假,需人工核查'.format('、'.join(verify_false_idx_list)) | ||
| 328 | result_field_list.append((name, empty_str, result, json.dumps(verify_list, ensure_ascii=False), | ||
| 329 | empty_str, empty_error_type, reason)) | ||
| 330 | |||
| 331 | # 担保人1 | ||
| 332 | dbr1_best_res = {} | ||
| 333 | if len(dbr1_field_list) > 0: | ||
| 334 | max_correct_count = 0 | ||
| 335 | for ocr_res in ocr_res_list: | ||
| 336 | correct_count = 0 | ||
| 337 | dbr1_tmp_res_part = {} | ||
| 338 | for idx, (name, value) in enumerate(dbr1_field_list): | ||
| 339 | ocr_str_or_list = ocr_res.get(compare_logic[name][0]) | ||
| 340 | if isinstance(ocr_str_or_list, str) or isinstance(ocr_str_or_list, list) or isinstance( | ||
| 341 | ocr_str_or_list, int): | ||
| 342 | result = getattr(cp, compare_logic[name][1])(value, ocr_str_or_list, | ||
| 343 | **compare_logic[name][2]) | ||
| 344 | if isinstance(ocr_str_or_list, list): | ||
| 345 | ocr_str = json.dumps(ocr_str_or_list, ensure_ascii=False) | ||
| 346 | else: | ||
| 347 | ocr_str = ocr_str_or_list | ||
| 348 | reason = compare_logic[name][3] | ||
| 349 | else: | ||
| 350 | result = consts.RESULT_N | ||
| 351 | ocr_str = empty_str | ||
| 352 | reason = compare_logic[name][3] | ||
| 353 | |||
| 354 | if idx == 0 and result == consts.RESULT_N: | ||
| 355 | break | ||
| 356 | |||
| 357 | if result == consts.RESULT_Y: | ||
| 358 | correct_count += 1 | ||
| 359 | dbr1_tmp_res_part[name] = (result, ocr_str, reason) | ||
| 360 | |||
| 361 | if correct_count > 0 and correct_count >= max_correct_count: | ||
| 362 | max_correct_count = correct_count | ||
| 363 | dbr1_best_res = dbr1_tmp_res_part | ||
| 364 | |||
| 365 | # 担保人2 | ||
| 366 | dbr2_best_res = {} | ||
| 367 | if len(dbr1_field_list) > 0: | ||
| 368 | max_correct_count = 0 | ||
| 369 | for ocr_res in ocr_res_list: | ||
| 370 | correct_count = 0 | ||
| 371 | dbr2_tmp_res_part = {} | ||
| 372 | for idx, (name, value) in enumerate(dbr2_field_list): | ||
| 373 | ocr_str_or_list = ocr_res.get(compare_logic[name][0]) | ||
| 374 | if isinstance(ocr_str_or_list, str) or isinstance(ocr_str_or_list, list) or isinstance( | ||
| 375 | ocr_str_or_list, int): | ||
| 376 | result = getattr(cp, compare_logic[name][1])(value, ocr_str_or_list, | ||
| 377 | **compare_logic[name][2]) | ||
| 378 | if isinstance(ocr_str_or_list, list): | ||
| 379 | ocr_str = json.dumps(ocr_str_or_list, ensure_ascii=False) | ||
| 380 | else: | ||
| 381 | ocr_str = ocr_str_or_list | ||
| 382 | reason = compare_logic[name][3] | ||
| 383 | else: | ||
| 384 | result = consts.RESULT_N | ||
| 385 | ocr_str = empty_str | ||
| 386 | reason = compare_logic[name][3] | ||
| 387 | |||
| 388 | if idx == 0 and result == consts.RESULT_N: | ||
| 389 | break | ||
| 390 | |||
| 391 | if result == consts.RESULT_Y: | ||
| 392 | correct_count += 1 | ||
| 393 | dbr2_tmp_res_part[name] = (result, ocr_str, reason) | ||
| 394 | |||
| 395 | if correct_count > 0 and correct_count >= max_correct_count: | ||
| 396 | max_correct_count = correct_count | ||
| 397 | dbr2_best_res = dbr2_tmp_res_part | ||
| 398 | |||
| 399 | dbr_ok = False | ||
| 400 | # 有担保人 | ||
| 401 | if len(dbr1_field_list) > 0: | ||
| 402 | # 有担保人12 | ||
| 403 | if len(dbr2_field_list) > 0: | ||
| 404 | if len(dbr1_best_res) > 0 and len(dbr2_best_res) > 0: | ||
| 405 | dbr_ok = True | ||
| 406 | # 有担保人1 | ||
| 407 | else: | ||
| 408 | if len(dbr1_best_res) > 0: | ||
| 409 | dbr_ok = True | ||
| 410 | # 无担保人 | ||
| 411 | # else: | ||
| 412 | # pass | ||
| 413 | |||
| 414 | best_res_empty = False | ||
| 415 | if len(pre_best_res) == 0 and len(dbr1_best_res) == 0 and len(dbr2_best_res) == 0: | ||
| 416 | best_res_empty = True | ||
| 417 | |||
| 418 | for name, value in pre_field_list: | ||
| 419 | if len(pre_best_res) > 0: | ||
| 420 | result, ocr_str, reason = pre_best_res[name] | ||
| 421 | else: | ||
| 422 | result = consts.RESULT_N | ||
| 423 | ocr_str = empty_str | ||
| 424 | if best_res_empty: | ||
| 425 | reason = consts.SPECIAL_REASON_3 | ||
| 426 | elif dbr_ok: # 有担保人且担保人都提供了流水 | ||
| 427 | reason = consts.SPECIAL_REASON | ||
| 428 | else: | ||
| 429 | reason = compare_logic[pre_field_list[0][0]][3] | ||
| 430 | img_path = empty_str | ||
| 431 | error_type = empty_error_type if result == consts.RESULT_Y else ErrorType.OCR.value | ||
| 432 | if isinstance(value, list): | ||
| 433 | value = json.dumps(value, ensure_ascii=False) | ||
| 434 | result_field_list.append((name, value, result, ocr_str, img_path, error_type, reason)) | ||
| 435 | |||
| 436 | if len(dbr1_field_list) > 0: | ||
| 437 | for name, value in dbr1_field_list: | ||
| 438 | if len(dbr1_best_res) > 0: | ||
| 439 | result, ocr_str, reason = dbr1_best_res[name] | ||
| 440 | else: | ||
| 441 | result = consts.RESULT_N | ||
| 442 | ocr_str = empty_str | ||
| 443 | if best_res_empty: | ||
| 444 | reason = consts.SPECIAL_REASON_3 | ||
| 445 | elif len(pre_best_res) > 0: | ||
| 446 | reason = consts.SPECIAL_REASON_2 | ||
| 447 | else: | ||
| 448 | reason = compare_logic[dbr1_field_list[0][0]][3] | ||
| 449 | img_path = empty_str | ||
| 450 | error_type = empty_error_type if result == consts.RESULT_Y else ErrorType.OCR.value | ||
| 451 | if isinstance(value, list): | ||
| 452 | value = json.dumps(value, ensure_ascii=False) | ||
| 453 | result_field_list.append((name, value, result, ocr_str, img_path, error_type, reason)) | ||
| 454 | |||
| 455 | if len(dbr2_field_list) > 0: | ||
| 456 | for name, value in dbr2_field_list: | ||
| 457 | if len(dbr2_best_res) > 0: | ||
| 458 | result, ocr_str, reason = dbr2_best_res[name] | ||
| 459 | else: | ||
| 460 | result = consts.RESULT_N | ||
| 461 | ocr_str = empty_str | ||
| 462 | if best_res_empty: | ||
| 463 | reason = consts.SPECIAL_REASON_3 | ||
| 464 | elif len(pre_best_res) > 0: | ||
| 465 | reason = consts.SPECIAL_REASON_2 | ||
| 466 | else: | ||
| 467 | reason = compare_logic[dbr2_field_list[0][0]][3] | ||
| 468 | img_path = empty_str | ||
| 469 | error_type = empty_error_type if result == consts.RESULT_Y else ErrorType.OCR.value | ||
| 470 | if isinstance(value, list): | ||
| 471 | value = json.dumps(value, ensure_ascii=False) | ||
| 472 | result_field_list.append((name, value, result, ocr_str, img_path, error_type, reason)) | ||
| 473 | |||
| 474 | else: | ||
| 475 | for name, value in strip_list: | ||
| 476 | if isinstance(value, list): | ||
| 477 | value = json.dumps(value, ensure_ascii=False) | ||
| 478 | result_field_list.append((name, value, consts.RESULT_N, empty_str, empty_str, ErrorType.NF.value, | ||
| 479 | consts.SPECIAL_REASON_3)) | ||
| 480 | |||
| 481 | return result_field_list, field_img_path_dict | ||
| 482 | |||
| 483 | @staticmethod | ||
| 484 | def se_compare_license_id(license_en, id_res_list, field_list): | ||
| 485 | ocr_field, compare_logic, special_expiry_date = pos_consts.SE_COMPARE_FIELD[license_en] | ||
| 486 | |||
| 487 | is_find = False | ||
| 488 | no_ocr_result = True | ||
| 489 | special_expiry_date_slice = False | ||
| 490 | result_field_list = [] | ||
| 491 | section_img_info = dict() | ||
| 492 | field_img_path_dict = dict() | ||
| 493 | |||
| 494 | # ocr_res_str = ocr_res_dict.get(ocr_field) | ||
| 495 | for ocr_res_str in id_res_list: | ||
| 496 | if is_find: | ||
| 497 | break | ||
| 498 | |||
| 499 | if ocr_res_str is not None: | ||
| 500 | no_ocr_result = False | ||
| 501 | |||
| 502 | ocr_res_list = json.loads(ocr_res_str) | ||
| 503 | |||
| 504 | # 3/4页去除 | ||
| 505 | # if ocr_field == consts.MVC_OCR_FIELD: | ||
| 506 | # tmp_list = [] | ||
| 507 | # for res in ocr_res_list: | ||
| 508 | # if compare_logic['vinNo'][0] in res: | ||
| 509 | # tmp_list.append(res) | ||
| 510 | # ocr_res_list = tmp_list | ||
| 511 | |||
| 512 | length = len(ocr_res_list) | ||
| 513 | |||
| 514 | # 身份证、居住证 过期期限特殊处理 | ||
| 515 | if special_expiry_date: | ||
| 516 | expiry_dates = dict() | ||
| 517 | key = compare_logic.get('idExpiryDate')[0] | ||
| 518 | for date_tmp_idx, ocr_res in enumerate(ocr_res_list): | ||
| 519 | if key in ocr_res: | ||
| 520 | expiry_dates[ocr_res[key]] = (ocr_res.get(consts.IMG_PATH_KEY_2, ''), date_tmp_idx) | ||
| 521 | else: | ||
| 522 | expiry_dates = dict() | ||
| 523 | |||
| 524 | for res_idx in range(length - 1, -1, -1): | ||
| 525 | if is_find: | ||
| 526 | break | ||
| 527 | |||
| 528 | for idx, (name, value) in enumerate(field_list): | ||
| 529 | # if ocr_field == consts.MVI_OCR_FIELD and name == consts.SE_NEW_ADD_FIELD[9]: | ||
| 530 | # ocr_str = getattr(cp, consts.ZW_METHOD)( | ||
| 531 | # ocr_res_list[res_idx].get(consts.LOWER_AMOUNT_FIELD, ''), | ||
| 532 | # ocr_res_list[res_idx].get(consts.UPPER_AMOUNT_FIELD, ''), | ||
| 533 | # ) | ||
| 534 | # else: | ||
| 535 | ocr_str = ocr_res_list[res_idx].get(compare_logic[name][0]) | ||
| 536 | if not isinstance(ocr_str, str): | ||
| 537 | result = consts.RESULT_N | ||
| 538 | ocr_str = empty_str | ||
| 539 | no_key = True | ||
| 540 | else: | ||
| 541 | result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2]) | ||
| 542 | no_key = False | ||
| 543 | |||
| 544 | if idx == 0 and result == consts.RESULT_N and length > 1: | ||
| 545 | break | ||
| 546 | |||
| 547 | is_find = True | ||
| 548 | section_img_info[consts.SECTION_IMG_PATH_KEY] = ocr_res_list[res_idx].get( | ||
| 549 | consts.SECTION_IMG_PATH_KEY, '') | ||
| 550 | section_img_info[consts.ALL_POSITION_KEY] = ocr_res_list[res_idx].get(consts.ALL_POSITION_KEY, | ||
| 551 | {}) | ||
| 552 | if special_expiry_date: | ||
| 553 | section_img_info[consts.SECTION_IMG_PATH_KEY_2] = ocr_res_list[res_idx].get( | ||
| 554 | consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 555 | section_img_info[consts.ALL_POSITION_KEY_2] = ocr_res_list[res_idx].get( | ||
| 556 | consts.ALL_POSITION_KEY_2, {}) | ||
| 557 | |||
| 558 | # 过期期限特殊处理 | ||
| 559 | if special_expiry_date and name == 'idExpiryDate' and result == consts.RESULT_N: | ||
| 560 | if no_key: | ||
| 561 | if len(expiry_dates) == 0: | ||
| 562 | ocr_str = empty_str | ||
| 563 | result = consts.RESULT_N | ||
| 564 | img_path = empty_str | ||
| 565 | else: | ||
| 566 | for expiry_date, (date_img_path, date_res_idx) in expiry_dates.items(): | ||
| 567 | expiry_date_res = getattr(cp, compare_logic[name][1])(value, expiry_date, | ||
| 568 | **compare_logic[name][2]) | ||
| 569 | if expiry_date_res == consts.RESULT_N: | ||
| 570 | ocr_str = expiry_date | ||
| 571 | img_path = date_img_path | ||
| 572 | special_expiry_date_slice = True | ||
| 573 | section_img_info[consts.SECTION_IMG_PATH_KEY_2] = ocr_res_list[ | ||
| 574 | date_res_idx].get( | ||
| 575 | consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 576 | section_img_info[consts.ALL_POSITION_KEY_2] = ocr_res_list[ | ||
| 577 | date_res_idx].get( | ||
| 578 | consts.ALL_POSITION_KEY_2, {}) | ||
| 579 | break | ||
| 580 | else: | ||
| 581 | ocr_str = empty_str | ||
| 582 | result = consts.RESULT_Y | ||
| 583 | img_path = empty_str | ||
| 584 | else: | ||
| 585 | img_path = ocr_res_list[res_idx].get(consts.IMG_PATH_KEY_2, '') | ||
| 586 | special_expiry_date_slice = True | ||
| 587 | else: | ||
| 588 | img_path = ocr_res_list[res_idx].get(consts.IMG_PATH_KEY, | ||
| 589 | '') if result == consts.RESULT_N else empty_str | ||
| 590 | if isinstance(value, list): | ||
| 591 | value = json.dumps(value, ensure_ascii=False) | ||
| 592 | error_type = empty_error_type if result == consts.RESULT_Y else ErrorType.OCR.value | ||
| 593 | result_field_list.append( | ||
| 594 | (name, value, result, ocr_str, img_path, error_type, compare_logic[name][3])) | ||
| 595 | |||
| 596 | if not is_find: | ||
| 597 | for name, value in field_list: | ||
| 598 | if isinstance(value, list): | ||
| 599 | value = json.dumps(value, ensure_ascii=False) | ||
| 600 | no_find_str = consts.DDA_NO_FIND if license_en == consts.DDA_EN else '{0}未找到'.format(license_en) | ||
| 601 | result_field_list.append( | ||
| 602 | (name, value, consts.RESULT_N, empty_str, empty_str, ErrorType.NF.value, no_find_str)) | ||
| 603 | |||
| 604 | # if is_find: | ||
| 605 | # if special_expiry_date_slice: | ||
| 606 | # special_section_img_path = section_img_info.get(consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 607 | # if os.path.exists(special_section_img_path): | ||
| 608 | # field = 'idExpiryDate' | ||
| 609 | # special_info = section_img_info.get(consts.ALL_POSITION_KEY_2, {}) | ||
| 610 | # special_section_position = special_info.get(consts.POSITION_KEY, {}) | ||
| 611 | # special_section_angle = special_info.get(consts.ANGLE_KEY, 0) | ||
| 612 | # try: | ||
| 613 | # last_img = img_process(special_section_img_path, special_section_position, | ||
| 614 | # special_section_angle) | ||
| 615 | # except Exception as e: | ||
| 616 | # field_img_path_dict[field] = special_section_img_path | ||
| 617 | # else: | ||
| 618 | # pre, suf = os.path.splitext(special_section_img_path) | ||
| 619 | # try: | ||
| 620 | # res_field = compare_logic[field][0] | ||
| 621 | # is_valid, coord_tuple = field_build_coordinates(special_info.get(res_field, {})) | ||
| 622 | # if is_valid: | ||
| 623 | # save_path = '{0}_{1}{2}'.format(pre, field, suf) | ||
| 624 | # field_img = last_img[coord_tuple[0]:coord_tuple[1], coord_tuple[2]:coord_tuple[3], :] | ||
| 625 | # cv2.imwrite(save_path, field_img) | ||
| 626 | # field_img_path_dict[field] = save_path | ||
| 627 | # else: | ||
| 628 | # field_img_path_dict[field] = special_section_img_path | ||
| 629 | # except Exception as e: | ||
| 630 | # field_img_path_dict[field] = special_section_img_path | ||
| 631 | # | ||
| 632 | # section_img_path = section_img_info.get(consts.SECTION_IMG_PATH_KEY, '') | ||
| 633 | # if os.path.exists(section_img_path): | ||
| 634 | # failed_field = [] | ||
| 635 | # base_img_path = empty_str | ||
| 636 | # for name, _, result, _, img_path, _, _ in result_field_list: | ||
| 637 | # if result == consts.RESULT_N: | ||
| 638 | # if special_expiry_date_slice and name == 'idExpiryDate': | ||
| 639 | # continue | ||
| 640 | # failed_field.append(name) | ||
| 641 | # if base_img_path == empty_str: | ||
| 642 | # base_img_path = img_path | ||
| 643 | # if len(failed_field) > 0: | ||
| 644 | # info = section_img_info.get(consts.ALL_POSITION_KEY, {}) | ||
| 645 | # section_position = info.get(consts.POSITION_KEY, {}) | ||
| 646 | # section_angle = info.get(consts.ANGLE_KEY, 0) | ||
| 647 | # try: | ||
| 648 | # last_img = img_process(section_img_path, section_position, section_angle) | ||
| 649 | # except Exception as e: | ||
| 650 | # for field in failed_field: | ||
| 651 | # field_img_path_dict[field] = base_img_path | ||
| 652 | # else: | ||
| 653 | # pre, suf = os.path.splitext(section_img_path) | ||
| 654 | # for field in failed_field: | ||
| 655 | # try: | ||
| 656 | # res_field = compare_logic[field][0] | ||
| 657 | # is_valid, coord_tuple = field_build_coordinates(info.get(res_field, {})) | ||
| 658 | # if is_valid: | ||
| 659 | # save_path = '{0}_{1}{2}'.format(pre, field, suf) | ||
| 660 | # field_img = last_img[coord_tuple[0]:coord_tuple[1], coord_tuple[2]:coord_tuple[3], | ||
| 661 | # :] | ||
| 662 | # cv2.imwrite(save_path, field_img) | ||
| 663 | # field_img_path_dict[field] = save_path | ||
| 664 | # else: | ||
| 665 | # field_img_path_dict[field] = base_img_path | ||
| 666 | # except Exception as e: | ||
| 667 | # field_img_path_dict[field] = base_img_path | ||
| 668 | |||
| 669 | return result_field_list, no_ocr_result, field_img_path_dict | ||
| 670 | |||
| 671 | @staticmethod | ||
| 672 | def se_compare_license(license_en, ocr_res_dict, field_list): | ||
| 673 | ocr_field, compare_logic, special_expiry_date = pos_consts.SE_COMPARE_FIELD[license_en] | ||
| 674 | |||
| 675 | is_find = False | ||
| 676 | no_ocr_result = False | ||
| 677 | special_expiry_date_slice = False | ||
| 678 | result_field_list = [] | ||
| 679 | section_img_info = dict() | ||
| 680 | field_img_path_dict = dict() | ||
| 681 | ocr_res_str = ocr_res_dict.get(ocr_field) | ||
| 682 | |||
| 683 | if ocr_res_str is not None: | ||
| 684 | ocr_res_list = json.loads(ocr_res_str) | ||
| 685 | |||
| 686 | # 3/4页去除 | ||
| 687 | if ocr_field == consts.MVC_OCR_FIELD: | ||
| 688 | tmp_list = [] | ||
| 689 | for res in ocr_res_list: | ||
| 690 | if compare_logic['vinNo'][0] in res: | ||
| 691 | tmp_list.append(res) | ||
| 692 | ocr_res_list = tmp_list | ||
| 693 | |||
| 694 | length = len(ocr_res_list) | ||
| 695 | |||
| 696 | # 身份证、居住证 过期期限特殊处理 | ||
| 697 | if special_expiry_date: | ||
| 698 | expiry_dates = dict() | ||
| 699 | key = compare_logic.get('idExpiryDate')[0] | ||
| 700 | for date_tmp_idx, ocr_res in enumerate(ocr_res_list): | ||
| 701 | if key in ocr_res: | ||
| 702 | expiry_dates[ocr_res[key]] = (ocr_res.get(consts.IMG_PATH_KEY_2, ''), date_tmp_idx) | ||
| 703 | else: | ||
| 704 | expiry_dates = dict() | ||
| 705 | |||
| 706 | for res_idx in range(length - 1, -1, -1): | ||
| 707 | if is_find: | ||
| 708 | break | ||
| 709 | |||
| 710 | new_invoice_result = None | ||
| 711 | for idx, (name, value) in enumerate(field_list): | ||
| 712 | # 二手车交易凭证 日期 | ||
| 713 | if ocr_field == consts.JYPZ_OCR_FIELD and name == consts.SE_GB_USED_FIELD[2]: | ||
| 714 | date_1 = ocr_res_list[res_idx].get(consts.JYPZ_DATE_FIELD_1, '') | ||
| 715 | if len(date_1) > 0: | ||
| 716 | date_2 = date_3 = '' | ||
| 717 | else: | ||
| 718 | date_1 = ocr_res_list[res_idx].get(consts.JYPZ_DATE_FIELD_2, '') | ||
| 719 | date_2 = ocr_res_list[res_idx].get(consts.JYPZ_DATE_FIELD_3, '') | ||
| 720 | date_3 = ocr_res_list[res_idx].get(consts.JYPZ_DATE_FIELD_4, '') | ||
| 721 | ocr_str = [date_1, date_2, date_3] | ||
| 722 | # 购车发票 价税合计大小写检验 | ||
| 723 | elif ocr_field == consts.MVI_OCR_FIELD and name == consts.SE_NEW_ADD_FIELD[9]: | ||
| 724 | ocr_str = getattr(cp, consts.ZW_METHOD)( | ||
| 725 | ocr_res_list[res_idx].get(consts.LOWER_AMOUNT_FIELD, ''), | ||
| 726 | ocr_res_list[res_idx].get(consts.UPPER_AMOUNT_FIELD, ''), | ||
| 727 | ) | ||
| 728 | else: | ||
| 729 | ocr_str = ocr_res_list[res_idx].get(compare_logic[name][0]) | ||
| 730 | |||
| 731 | if isinstance(ocr_str, str): | ||
| 732 | result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2]) | ||
| 733 | no_key = False | ||
| 734 | # 二手车交易凭证 日期 | ||
| 735 | elif ocr_field == consts.JYPZ_OCR_FIELD and name == consts.SE_GB_USED_FIELD[2]: | ||
| 736 | result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2]) | ||
| 737 | no_key = False | ||
| 738 | else: | ||
| 739 | result = consts.RESULT_N | ||
| 740 | ocr_str = empty_str | ||
| 741 | no_key = True | ||
| 742 | |||
| 743 | if name == '发票联': | ||
| 744 | new_invoice_result = result | ||
| 745 | |||
| 746 | if name == 'productGroupName' and (name.find('官方认证二手车') > -1 or name.find('官方认证二手车') > -1): | ||
| 747 | # 发票联必须 | ||
| 748 | if new_invoice_result and new_invoice_result == consts.RESULT_Y: | ||
| 749 | result = consts.RESULT_Y | ||
| 750 | else: | ||
| 751 | result = consts.RESULT_N | ||
| 752 | |||
| 753 | if idx == 0 and result == consts.RESULT_N and length > 1: | ||
| 754 | break | ||
| 755 | |||
| 756 | is_find = True | ||
| 757 | # section_img_info[consts.SECTION_IMG_PATH_KEY] = ocr_res_list[res_idx].get( | ||
| 758 | # consts.SECTION_IMG_PATH_KEY, '') | ||
| 759 | # section_img_info[consts.ALL_POSITION_KEY] = ocr_res_list[res_idx].get(consts.ALL_POSITION_KEY, {}) | ||
| 760 | # if special_expiry_date: | ||
| 761 | # section_img_info[consts.SECTION_IMG_PATH_KEY_2] = ocr_res_list[res_idx].get( | ||
| 762 | # consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 763 | # section_img_info[consts.ALL_POSITION_KEY_2] = ocr_res_list[res_idx].get( | ||
| 764 | # consts.ALL_POSITION_KEY_2, {}) | ||
| 765 | |||
| 766 | # 过期期限特殊处理 | ||
| 767 | if special_expiry_date and name == 'idExpiryDate' and result == consts.RESULT_N: | ||
| 768 | if no_key: | ||
| 769 | if len(expiry_dates) == 0: | ||
| 770 | ocr_str = empty_str | ||
| 771 | result = consts.RESULT_N | ||
| 772 | img_path = empty_str | ||
| 773 | else: | ||
| 774 | for expiry_date, (date_img_path, date_res_idx) in expiry_dates.items(): | ||
| 775 | expiry_date_res = getattr(cp, compare_logic[name][1])(value, expiry_date, | ||
| 776 | **compare_logic[name][2]) | ||
| 777 | if expiry_date_res == consts.RESULT_N: | ||
| 778 | ocr_str = expiry_date | ||
| 779 | img_path = date_img_path | ||
| 780 | special_expiry_date_slice = True | ||
| 781 | section_img_info[consts.SECTION_IMG_PATH_KEY_2] = ocr_res_list[ | ||
| 782 | date_res_idx].get( | ||
| 783 | consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 784 | section_img_info[consts.ALL_POSITION_KEY_2] = ocr_res_list[date_res_idx].get( | ||
| 785 | consts.ALL_POSITION_KEY_2, {}) | ||
| 786 | break | ||
| 787 | else: | ||
| 788 | ocr_str = empty_str | ||
| 789 | result = consts.RESULT_Y | ||
| 790 | img_path = empty_str | ||
| 791 | else: | ||
| 792 | img_path = ocr_res_list[res_idx].get(consts.IMG_PATH_KEY_2, '') | ||
| 793 | special_expiry_date_slice = True | ||
| 794 | else: | ||
| 795 | img_path = ocr_res_list[res_idx].get(consts.IMG_PATH_KEY, | ||
| 796 | '') if result == consts.RESULT_N else empty_str | ||
| 797 | if isinstance(value, list): | ||
| 798 | value = json.dumps(value, ensure_ascii=False) | ||
| 799 | error_type = empty_error_type if result == consts.RESULT_Y else ErrorType.OCR.value | ||
| 800 | |||
| 801 | if ocr_field == pos_consts.IC_OCR_FIELD and name == 'idExpiryDate': | ||
| 802 | result_field_list.append( | ||
| 803 | (name, value, result, ocr_str, img_path, error_type, compare_logic[name][-1][result])) | ||
| 804 | else: | ||
| 805 | result_field_list.append((name, value, result, ocr_str, img_path, error_type, compare_logic[name][-1])) | ||
| 806 | |||
| 807 | else: | ||
| 808 | no_ocr_result = True | ||
| 809 | |||
| 810 | # 针对license文档类型输出 | ||
| 811 | if no_ocr_result: | ||
| 812 | # 保险 | ||
| 813 | if license_en == pos_consts.BD_EN: | ||
| 814 | # 整体文档相关 | ||
| 815 | pos_field, value = field_list[0] | ||
| 816 | if pos_field == 'insuranceType' and value == 'Comprehensive Insurance': | ||
| 817 | if no_ocr_result: | ||
| 818 | result_field_list.append((pos_field, value, consts.RESULT_N, ocr_str, img_path, error_type, | ||
| 819 | compare_logic['文档'][-1])) | ||
| 820 | elif license_en == pos_consts.HMH_EN: # 抵押登记豁免函 | ||
| 821 | pos_field, value = field_list[0] | ||
| 822 | if pos_field == 'mortgageType' and value == 'MOTGF': | ||
| 823 | if no_ocr_result: | ||
| 824 | result_field_list.append((pos_field, value, consts.RESULT_N, ocr_str, img_path, error_type, | ||
| 825 | compare_logic['文档'][-1])) | ||
| 826 | elif license_en == pos_consts.MVI_EN: # 新车发票 | ||
| 827 | pos_field, value = field_list[0] | ||
| 828 | if pos_field == 'productGroupName' and no_ocr_result: | ||
| 829 | result_field_list.append( | ||
| 830 | (pos_field, value, consts.RESULT_N, ocr_str, img_path, error_type, | ||
| 831 | compare_logic['文档'][-1])) | ||
| 832 | elif license_en == pos_consts.BC_EN: # 银行卡 | ||
| 833 | pos_field, value = field_list[0] | ||
| 834 | if pos_field == 'bankVerificationStatus' and (value == 'N/A' or value == 'FAIL'): | ||
| 835 | if no_ocr_result: | ||
| 836 | result_field_list.append( | ||
| 837 | (pos_field, value, consts.RESULT_N, ocr_str, img_path, error_type, | ||
| 838 | compare_logic['文档'][-1])) | ||
| 839 | elif license_en == pos_consts.AFC_CONTRACT_EN: # AFC 车辆抵押贷款合同(E-Contract-Non ASP/ASP) | ||
| 840 | pos_field, value = field_list[0] | ||
| 841 | if pos_field == 'applicationEntity' and value == 'AFC': | ||
| 842 | if no_ocr_result: | ||
| 843 | result_field_list.append((pos_field, value, consts.RESULT_N, ocr_str, img_path, error_type, | ||
| 844 | compare_logic['文档'][-1])) | ||
| 845 | elif license_en == pos_consts.HIL_CONTRACT_1_EN: # 售后回租合同(E-Sign-SLB / OC) | ||
| 846 | pos_field, value = field_list[0] | ||
| 847 | if pos_field == 'applicationEntity' and value == 'HIL': | ||
| 848 | if no_ocr_result: | ||
| 849 | result_field_list.append((pos_field, value, consts.RESULT_N, ocr_str, img_path, error_type, | ||
| 850 | compare_logic['文档'][-1])) | ||
| 851 | elif license_en == pos_consts.HIL_CONTRACT_2_EN: # 车辆租赁抵押合同(E-Sign-SLB / OC) | ||
| 852 | pos_field, value = field_list[0] | ||
| 853 | if pos_field == 'applicationEntity' and value == 'HIL': | ||
| 854 | if no_ocr_result: | ||
| 855 | result_field_list.append( | ||
| 856 | (pos_field, value, consts.RESULT_N, ocr_str, img_path, error_type, | ||
| 857 | compare_logic['文档'][-1])) | ||
| 858 | |||
| 859 | if not is_find: | ||
| 860 | for name, value in field_list: | ||
| 861 | if isinstance(value, list): | ||
| 862 | value = json.dumps(value, ensure_ascii=False) | ||
| 863 | no_find_str = consts.DDA_NO_FIND if license_en == consts.DDA_EN else '{0}未找到'.format(license_en) | ||
| 864 | result_field_list.append( | ||
| 865 | (name, value, consts.RESULT_N, empty_str, empty_str, ErrorType.NF.value, no_find_str)) | ||
| 866 | |||
| 867 | # if is_find: | ||
| 868 | # if special_expiry_date_slice: | ||
| 869 | # special_section_img_path = section_img_info.get(consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 870 | # if os.path.exists(special_section_img_path): | ||
| 871 | # field = 'idExpiryDate' | ||
| 872 | # special_info = section_img_info.get(consts.ALL_POSITION_KEY_2, {}) | ||
| 873 | # special_section_position = special_info.get(consts.POSITION_KEY, {}) | ||
| 874 | # special_section_angle = special_info.get(consts.ANGLE_KEY, 0) | ||
| 875 | # try: | ||
| 876 | # last_img = img_process(special_section_img_path, special_section_position, | ||
| 877 | # special_section_angle) | ||
| 878 | # except Exception as e: | ||
| 879 | # field_img_path_dict[field] = special_section_img_path | ||
| 880 | # else: | ||
| 881 | # pre, suf = os.path.splitext(special_section_img_path) | ||
| 882 | # try: | ||
| 883 | # res_field = compare_logic[field][0] | ||
| 884 | # is_valid, coord_tuple = field_build_coordinates(special_info.get(res_field, {})) | ||
| 885 | # if is_valid: | ||
| 886 | # save_path = '{0}_{1}{2}'.format(pre, field, suf) | ||
| 887 | # field_img = last_img[coord_tuple[0]:coord_tuple[1], coord_tuple[2]:coord_tuple[3], :] | ||
| 888 | # cv2.imwrite(save_path, field_img) | ||
| 889 | # field_img_path_dict[field] = save_path | ||
| 890 | # else: | ||
| 891 | # field_img_path_dict[field] = special_section_img_path | ||
| 892 | # except Exception as e: | ||
| 893 | # field_img_path_dict[field] = special_section_img_path | ||
| 894 | # | ||
| 895 | # section_img_path = section_img_info.get(consts.SECTION_IMG_PATH_KEY, '') | ||
| 896 | # if os.path.exists(section_img_path): | ||
| 897 | # failed_field = [] | ||
| 898 | # base_img_path = empty_str | ||
| 899 | # for name, _, result, _, img_path, _, _ in result_field_list: | ||
| 900 | # if result == consts.RESULT_N: | ||
| 901 | # if special_expiry_date_slice and name == 'idExpiryDate': | ||
| 902 | # continue | ||
| 903 | # failed_field.append(name) | ||
| 904 | # if base_img_path == empty_str: | ||
| 905 | # base_img_path = img_path | ||
| 906 | # if len(failed_field) > 0: | ||
| 907 | # info = section_img_info.get(consts.ALL_POSITION_KEY, {}) | ||
| 908 | # section_position = info.get(consts.POSITION_KEY, {}) | ||
| 909 | # section_angle = info.get(consts.ANGLE_KEY, 0) | ||
| 910 | # try: | ||
| 911 | # last_img = img_process(section_img_path, section_position, section_angle) | ||
| 912 | # except Exception as e: | ||
| 913 | # for field in failed_field: | ||
| 914 | # field_img_path_dict[field] = base_img_path | ||
| 915 | # else: | ||
| 916 | # pre, suf = os.path.splitext(section_img_path) | ||
| 917 | # for field in failed_field: | ||
| 918 | # try: | ||
| 919 | # res_field = compare_logic[field][0] | ||
| 920 | # is_valid, coord_tuple = field_build_coordinates(info.get(res_field, {})) | ||
| 921 | # if is_valid: | ||
| 922 | # save_path = '{0}_{1}{2}'.format(pre, field, suf) | ||
| 923 | # field_img = last_img[coord_tuple[0]:coord_tuple[1], coord_tuple[2]:coord_tuple[3], | ||
| 924 | # :] | ||
| 925 | # cv2.imwrite(save_path, field_img) | ||
| 926 | # field_img_path_dict[field] = save_path | ||
| 927 | # else: | ||
| 928 | # field_img_path_dict[field] = base_img_path | ||
| 929 | # except Exception as e: | ||
| 930 | # field_img_path_dict[field] = base_img_path | ||
| 931 | |||
| 932 | return result_field_list, no_ocr_result, field_img_path_dict | ||
| 933 | |||
| 934 | |||
| 935 | class CACompare: | ||
| 936 | @staticmethod | ||
| 937 | def ca_compare_license(license_en, ocr_res_dict, field_list): | ||
| 938 | ocr_field, compare_logic, special_expiry_date = consts.CA_COMPARE_FIELD[license_en] | ||
| 939 | |||
| 940 | is_find = False | ||
| 941 | special_expiry_date_slice = False | ||
| 942 | result_field_list = [] | ||
| 943 | section_img_info = dict() | ||
| 944 | field_img_path_dict = dict() | ||
| 945 | ocr_res_str = ocr_res_dict.get(ocr_field) | ||
| 946 | if ocr_res_str is not None: | ||
| 947 | ocr_res_list = json.loads(ocr_res_str) | ||
| 948 | |||
| 949 | # 副页去除 3/4页去除 | ||
| 950 | if ocr_field == consts.DL_OCR_FIELD or ocr_field == consts.MVC_OCR_FIELD: | ||
| 951 | tmp_list = [] | ||
| 952 | for res in ocr_res_list: | ||
| 953 | if compare_logic['vinNo'][0] in res: | ||
| 954 | tmp_list.append(res) | ||
| 955 | ocr_res_list = tmp_list | ||
| 956 | |||
| 957 | length = len(ocr_res_list) | ||
| 958 | |||
| 959 | # 身份证、居住证 过期期限特殊处理 | ||
| 960 | if special_expiry_date: | ||
| 961 | expiry_dates = set() | ||
| 962 | expiry_dates_img_path = set() | ||
| 963 | key = compare_logic.get('idExpiryDate')[0] | ||
| 964 | for ocr_res in ocr_res_list: | ||
| 965 | if key in ocr_res: | ||
| 966 | expiry_dates.add(ocr_res[key]) | ||
| 967 | expiry_dates_img_path.add(ocr_res.get(consts.IMG_PATH_KEY_2, '')) | ||
| 968 | else: | ||
| 969 | expiry_dates = set() | ||
| 970 | expiry_dates_img_path = set() | ||
| 971 | |||
| 972 | for res_idx in range(length - 1, -1, -1): | ||
| 973 | if is_find: | ||
| 974 | break | ||
| 975 | |||
| 976 | for idx, (name, value) in enumerate(field_list): | ||
| 977 | ocr_str = ocr_res_list[res_idx].get(compare_logic[name][0]) | ||
| 978 | if not isinstance(ocr_str, str): | ||
| 979 | result = consts.RESULT_N | ||
| 980 | ocr_str = empty_str | ||
| 981 | else: | ||
| 982 | result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2]) | ||
| 983 | |||
| 984 | if idx == 0 and result == consts.RESULT_N and length > 1: | ||
| 985 | break | ||
| 986 | |||
| 987 | is_find = True | ||
| 988 | # section_img_info[consts.SECTION_IMG_PATH_KEY] = ocr_res_list[res_idx].get( | ||
| 989 | # consts.SECTION_IMG_PATH_KEY, '') | ||
| 990 | # section_img_info[consts.ALL_POSITION_KEY] = ocr_res_list[res_idx].get(consts.ALL_POSITION_KEY, {}) | ||
| 991 | # if special_expiry_date: | ||
| 992 | # section_img_info[consts.SECTION_IMG_PATH_KEY_2] = ocr_res_list[res_idx].get( | ||
| 993 | # consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 994 | # section_img_info[consts.ALL_POSITION_KEY_2] = ocr_res_list[res_idx].get( | ||
| 995 | # consts.ALL_POSITION_KEY_2, {}) | ||
| 996 | |||
| 997 | # 过期期限特殊处理 | ||
| 998 | if special_expiry_date and name == 'idExpiryDate' and result == consts.RESULT_N: | ||
| 999 | for expiry_date in expiry_dates: | ||
| 1000 | expiry_date_res = getattr(cp, compare_logic[name][1])(value, expiry_date, | ||
| 1001 | **compare_logic[name][2]) | ||
| 1002 | if expiry_date_res == consts.RESULT_Y: | ||
| 1003 | ocr_str = expiry_date | ||
| 1004 | result = expiry_date_res | ||
| 1005 | break | ||
| 1006 | |||
| 1007 | if result == consts.RESULT_N: | ||
| 1008 | if consts.IMG_PATH_KEY_2 in ocr_res_list[res_idx]: | ||
| 1009 | img_path = ocr_res_list[res_idx].get(consts.IMG_PATH_KEY_2, '') | ||
| 1010 | special_expiry_date_slice = True | ||
| 1011 | else: | ||
| 1012 | img_path = expiry_dates_img_path.pop() if len(expiry_dates_img_path) > 0 else empty_str | ||
| 1013 | else: | ||
| 1014 | img_path = empty_str | ||
| 1015 | else: | ||
| 1016 | img_path = ocr_res_list[res_idx].get(consts.IMG_PATH_KEY, | ||
| 1017 | '') if result == consts.RESULT_N else empty_str | ||
| 1018 | error_type = empty_error_type if result == consts.RESULT_Y else ErrorType.OCR.value | ||
| 1019 | result_field_list.append((name, value, result, ocr_str, img_path, error_type, compare_logic[name][-1])) | ||
| 1020 | |||
| 1021 | if not is_find: | ||
| 1022 | for name, value in field_list: | ||
| 1023 | result_field_list.append((name, value, consts.RESULT_N, empty_str, empty_str, ErrorType.NF.value, compare_logic[name][-1])) | ||
| 1024 | |||
| 1025 | # if is_find: | ||
| 1026 | # if special_expiry_date_slice: | ||
| 1027 | # special_section_img_path = section_img_info.get(consts.SECTION_IMG_PATH_KEY_2, '') | ||
| 1028 | # if os.path.exists(special_section_img_path): | ||
| 1029 | # field = 'idExpiryDate' | ||
| 1030 | # special_info = section_img_info.get(consts.ALL_POSITION_KEY_2, {}) | ||
| 1031 | # special_section_position = special_info.get(consts.POSITION_KEY, {}) | ||
| 1032 | # special_section_angle = special_info.get(consts.ANGLE_KEY, 0) | ||
| 1033 | # try: | ||
| 1034 | # last_img = img_process(special_section_img_path, special_section_position, | ||
| 1035 | # special_section_angle) | ||
| 1036 | # except Exception as e: | ||
| 1037 | # field_img_path_dict[field] = special_section_img_path | ||
| 1038 | # else: | ||
| 1039 | # pre, suf = os.path.splitext(special_section_img_path) | ||
| 1040 | # try: | ||
| 1041 | # res_field = compare_logic[field][0] | ||
| 1042 | # is_valid, coord_tuple = field_build_coordinates(special_info.get(res_field, {})) | ||
| 1043 | # if is_valid: | ||
| 1044 | # save_path = '{0}_{1}{2}'.format(pre, field, suf) | ||
| 1045 | # field_img = last_img[coord_tuple[0]:coord_tuple[1], coord_tuple[2]:coord_tuple[3], :] | ||
| 1046 | # cv2.imwrite(save_path, field_img) | ||
| 1047 | # field_img_path_dict[field] = save_path | ||
| 1048 | # else: | ||
| 1049 | # field_img_path_dict[field] = special_section_img_path | ||
| 1050 | # except Exception as e: | ||
| 1051 | # field_img_path_dict[field] = special_section_img_path | ||
| 1052 | # | ||
| 1053 | # section_img_path = section_img_info.get(consts.SECTION_IMG_PATH_KEY, '') | ||
| 1054 | # if os.path.exists(section_img_path): | ||
| 1055 | # failed_field = [] | ||
| 1056 | # base_img_path = empty_str | ||
| 1057 | # for name, _, result, _, img_path, _ in result_field_list: | ||
| 1058 | # if result == consts.RESULT_N: | ||
| 1059 | # if special_expiry_date_slice and name == 'idExpiryDate': | ||
| 1060 | # continue | ||
| 1061 | # failed_field.append(name) | ||
| 1062 | # if base_img_path == empty_str: | ||
| 1063 | # base_img_path = img_path | ||
| 1064 | # if len(failed_field) > 0: | ||
| 1065 | # info = section_img_info.get(consts.ALL_POSITION_KEY, {}) | ||
| 1066 | # section_position = info.get(consts.POSITION_KEY, {}) | ||
| 1067 | # section_angle = info.get(consts.ANGLE_KEY, 0) | ||
| 1068 | # try: | ||
| 1069 | # last_img = img_process(section_img_path, section_position, section_angle) | ||
| 1070 | # except Exception as e: | ||
| 1071 | # for field in failed_field: | ||
| 1072 | # field_img_path_dict[field] = base_img_path | ||
| 1073 | # else: | ||
| 1074 | # pre, suf = os.path.splitext(section_img_path) | ||
| 1075 | # for field in failed_field: | ||
| 1076 | # try: | ||
| 1077 | # if license_en == consts.PP_EN: | ||
| 1078 | # res_field = consts.PP_SLICE_MAP[field] | ||
| 1079 | # else: | ||
| 1080 | # res_field = compare_logic[field][0] | ||
| 1081 | # is_valid, coord_tuple = field_build_coordinates(info.get(res_field, {})) | ||
| 1082 | # if is_valid: | ||
| 1083 | # save_path = '{0}_{1}{2}'.format(pre, field, suf) | ||
| 1084 | # field_img = last_img[coord_tuple[0]:coord_tuple[1], coord_tuple[2]:coord_tuple[3], | ||
| 1085 | # :] | ||
| 1086 | # cv2.imwrite(save_path, field_img) | ||
| 1087 | # field_img_path_dict[field] = save_path | ||
| 1088 | # else: | ||
| 1089 | # field_img_path_dict[field] = base_img_path | ||
| 1090 | # except Exception as e: | ||
| 1091 | # field_img_path_dict[field] = base_img_path | ||
| 1092 | |||
| 1093 | return result_field_list, field_img_path_dict | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/pos/pos_consts.py
deleted
100644 → 0
| 1 | |||
| 2 | GZS_REASON_1 = '此申请有ASP产品,需人工核查' | ||
| 3 | GZS_REASON_2 = 'ASP购置税金额小于系统金额' | ||
| 4 | |||
| 5 | # license (license_en) | ||
| 6 | ID_EN = 'PRC ID' | ||
| 7 | PP_EN = 'Passport' | ||
| 8 | EEP_EN = 'Resident Permit to Mainland' | ||
| 9 | RP_EN = 'Resident ID' | ||
| 10 | BL_EN = 'Business permit' | ||
| 11 | SME_BL_EN = 'SME Business permit' | ||
| 12 | MVI_EN = 'newCar Invoice' | ||
| 13 | UCI_EN = 'usedCar Invoice' | ||
| 14 | MVC_EN = 'Green Book(1/2)' | ||
| 15 | MVC34_EN = 'Green Book(3/4)' | ||
| 16 | BC_EN = 'Bank Card' | ||
| 17 | DDA_EN = 'DDA' | ||
| 18 | HMH_EN = 'Mortgage Waiver Letter' | ||
| 19 | JYPZ_EN = 'Used Car Document' | ||
| 20 | AFC_CONTRACT_EN = 'AFC Contract' | ||
| 21 | BD_EN = 'Insurance' | ||
| 22 | BS_EN = 'Bank Statement' | ||
| 23 | HIL_CONTRACT_1_EN = '售后回租合同' | ||
| 24 | HIL_CONTRACT_2_EN = '车辆租赁抵押合同' | ||
| 25 | HIL_CONTRACT_3_EN = '车辆处置协议' | ||
| 26 | |||
| 27 | # 对应ocr_result 表中的字段 | ||
| 28 | IC_OCR_FIELD = 'ic_ocr' | ||
| 29 | RP_OCR_FIELD = 'rp_ocr' | ||
| 30 | BL_OCR_FIELD = 'bl_ocr' | ||
| 31 | EEP_OCR_FIELD = 'eep_ocr' | ||
| 32 | DL_OCR_FIELD = 'dl_ocr' | ||
| 33 | PP_OCR_FIELD = 'pp_ocr' | ||
| 34 | MVC_OCR_FIELD = 'mvc_ocr' | ||
| 35 | MVI_OCR_FIELD = 'mvi_ocr' | ||
| 36 | BC_OCR_FIELD = 'bc_ocr' | ||
| 37 | UCI_OCR_FIELD = 'uci_ocr' | ||
| 38 | DDA_OCR_FIELD = 'bs_ocr' | ||
| 39 | HMH_OCR_FIELD = 'hmh_ocr' | ||
| 40 | JYPZ_OCR_FIELD = 'jypz_ocr' | ||
| 41 | HT_FIELD = 'ht_ocr' | ||
| 42 | BD_FIELD = 'bd_ocr' | ||
| 43 | BS_FIELD = 'bss_ocr' | ||
| 44 | HIL_CONTRACT_1_FIELD = 'hil_contract_1_ocr' | ||
| 45 | HIL_CONTRACT_2_FIELD = 'hil_contract_2_ocr' | ||
| 46 | HIL_CONTRACT_3_FIELD = 'hil_contract_3_ocr' | ||
| 47 | |||
| 48 | SE_AFC_CON_FIELD = ['合同编号-每页', '所购车辆价格-小写-重要条款', '车架号-重要条款', '贷款本金金额-重要条款', '贷款期限-重要条款', | ||
| 49 | '车辆贷款本金金额-重要条款', '附加产品融资贷款本金总额-重要条款', '所购车辆价格', '车架号', '经销商', | ||
| 50 | '贷款本金金额', '车辆贷款本金金额', '附加产品融资贷款本金总额', '贷款期限', '还款账号', '户名', '开户行', | ||
| 51 | '还款计划表', '见证人签字', '见证人日期', 'ASP项目详情-重要条款', '购置税校验', 'ASP项目详情', | ||
| 52 | '合同编号-每页(no-asp)', '无ASP产品'] | ||
| 53 | # '承租人姓名', '承租人证件号码', '承租人法定代表人或授权代表' | ||
| 54 | SE_HIL_CON_1_FIELD = ['合同编号-每页', '车辆识别代码', '车辆卖方', '车辆原始销售价格', '融资成本总额', '租期', | ||
| 55 | '还款计划表', 'ASP项目详情', '购置税校验', '承租人法定代表人或授权代表', '还款账号', '户名', '开户行', | ||
| 56 | '共同承租人法定代表人或授权代表', '无ASP产品'] | ||
| 57 | |||
| 58 | SE_HIL_CON_2_FIELD = ['合同编号', '车辆识别代码'] | ||
| 59 | |||
| 60 | # 大陆二代身份证 | ||
| 61 | ID_COMPARE_LOGIC = { | ||
| 62 | 'customerName': ('姓名', 'se_name_compare', {}, '身份证姓名与系统不一致'), | ||
| 63 | 'idNum': ('公民身份号码', 'se_common_compare', {}, '身份证号码与系统不一致'), | ||
| 64 | 'dateOfBirth': ('出生年月', 'se_date_compare', {'input_replace': ''}), | ||
| 65 | 'idExpiryDate': ('有效期限', 'se_date_compare_pos', {'long': True, 'ocr_split': True, 'input_replace': '', 'today': True}, { | ||
| 66 | 'N1': '身份证疑似过期', | ||
| 67 | 'N2': '身份证即将过期,请尽快提交放款申请' | ||
| 68 | }) | ||
| 69 | } | ||
| 70 | |||
| 71 | |||
| 72 | # 新车发票 | ||
| 73 | # key: pos field | ||
| 74 | # value: (ocr_result中的映射key,比较方法, 选项, comments/reason) | ||
| 75 | MVI_COMPARE_LOGIC = { | ||
| 76 | 'firstSubmmisonDate': ('开票日期', 'se_date_compare_2', {'three_month': True}, '请确认发票开票日期,若发票开票日期早于首次提交审批日期则无法受理放款申请'), | ||
| 77 | 'productGroupName': ('productGroupName', 'se_common_compare', {}, '请确认是否提供发票'), | ||
| 78 | 'vinNo': ('车辆识别代码', 'se_common_compare', {}, '发票车架号与系统不一致'), | ||
| 79 | 'vehicleTransactionAmount': ('价税合计小写', 'se_amount_compare', {}, '发票车辆价格与系统不一致'), | ||
| 80 | 'customerName': ('购方名称', 'se_name_compare', {'is_passport': True, 'replace_kuohao': True}, '发票购买方姓名与系统不一致'), | ||
| 81 | 'idNum': ('购买方身份证号或组织机构代码', 'se_common_compare', {}, '发票购买方证件号码与系统不一致'), | ||
| 82 | '发票联': ('发票联', 'se_common_compare', {}, '发票疑似非发票联'), | ||
| 83 | '文档': ('发票联', 'se_have_compare', {}, '请确认是否提供发票'), | ||
| 84 | } | ||
| 85 | |||
| 86 | # 银行卡 | ||
| 87 | BC_COMPARE_LOGIC = { | ||
| 88 | 'accountNo': ('CardNum', 'se_common_compare', {'remove_space': True}, '银行卡卡号与系统不一致'), | ||
| 89 | 'bankName': ('BankName', 'se_both_contain_compare', {}, '银行卡开户行与系统不一致'), | ||
| 90 | 'type': ('CardType', 'se_common_compare', {}, '银行卡非借记卡'), | ||
| 91 | 'bankVerificationStatus': ('CardType', 'se_have_compare', {}, '请确认是否提供银行卡'), | ||
| 92 | '文档': ('文档', 'se_common_compare', {}, '请确认是否提供银行卡'), | ||
| 93 | } | ||
| 94 | |||
| 95 | # AFC 车辆抵押贷款合同(E-Contract-Non ASP/ASP) | ||
| 96 | HT_COMPARE_LOGIC = { | ||
| 97 | '合同编号-每页': ('合同编号-每页', 'se_list_compare', {}, '合同编号与系统不一致'), | ||
| 98 | # '合同编号-每页(no-asp)': ('合同编号-每页', 'se_list_compare', {'pop_last': True}, '合同编号与系统不一致'), | ||
| 99 | '合同编号-每页(no-asp)': ('合同编号-每页', 'se_list_compare', {}, '合同编号与系统不一致'), | ||
| 100 | '所购车辆价格-小写-重要条款': ('所购车辆价格-小写-重要条款', 'se_amount_str_compare', {}, '合同首页中车辆价格与系统不一致'), | ||
| 101 | '车架号-重要条款': ('车架号-重要条款', 'se_common_compare', {}, '合同首页中车架号与系统不一致'), | ||
| 102 | '贷款本金金额-重要条款': ('贷款本金金额-重要条款', 'se_amount_str_compare', {}, '合同首页中贷款本金与系统不一致'), | ||
| 103 | '贷款期限-重要条款': ('贷款期限-重要条款', 'se_common_compare', {}, '合同首页中贷款期限与系统不一致'), | ||
| 104 | '车辆贷款本金金额-重要条款': ('车辆贷款本金金额-重要条款', 'se_amount_str_compare', {}, '合同车辆贷款本金金额-重要条款'), | ||
| 105 | '附加产品融资贷款本金总额-重要条款': ('附加产品融资贷款本金总额-重要条款', 'se_amount_str_compare', {}, '合同首页中附加产品融资金额与系统不一致'), | ||
| 106 | '所购车辆价格': ('所购车辆价格', 'se_amount_str_compare', {}, '主合同页中车辆价格与系统不一致'), | ||
| 107 | '车架号': ('车架号', 'se_common_compare', {}, '主合同页中车架号与系统不一致'), | ||
| 108 | '经销商': ('经销商', 'se_common_compare', {}, '主合同页中经销商与系统不一致'), | ||
| 109 | '贷款本金金额': ('贷款本金金额', 'se_amount_str_compare', {}, '主合同页中贷款本金金额与系统不一致'), | ||
| 110 | '车辆贷款本金金额': ('车辆贷款本金金额', 'se_amount_str_compare', {}, '主合同页中车辆贷款本金金额与系统不一致'), | ||
| 111 | '附加产品融资贷款本金总额': ('附加产品融资贷款本金总额', 'se_amount_str_compare', {}, '主合同页中附加产品融资贷款本金总额与系统不一致'), | ||
| 112 | '贷款期限': ('贷款期限', 'se_common_compare', {}, '主合同页中贷款期限与系统不一致'), | ||
| 113 | '还款账号': ('还款账号', 'se_common_compare', {'remove_space': True}, '主合同页中还款账号与系统不一致'), | ||
| 114 | '户名': ('户名', 'se_common_compare', {}, '主合同页中户名与系统不一致'), | ||
| 115 | '开户行': ('开户行', 'se_both_contain_compare', {}, '主合同页中开户行与系统不一致'), | ||
| 116 | |||
| 117 | '借款人签字及时间': ('借款人签字及时间', 'se_both_contain_compare', {}, '合同首页签字项与系统不一致'), | ||
| 118 | '借款人姓名': ('借款人姓名', 'se_common_compare', {}, '主合同主借人姓名与系统不一致'), | ||
| 119 | '借款人证件号': ('借款人证件号', 'se_common_compare', {}, '主合同主借人证件号码与系统不一致'), | ||
| 120 | '共借人姓名': ('共借人姓名', 'se_common_compare', {}, '主合同共借人姓名与系统不一致'), | ||
| 121 | '共借人&抵押人姓名': ('共借人姓名', 'se_common_compare', {}, '主合同共借人&抵押人姓名与系统不一致'), | ||
| 122 | '共借人证件号': ('共借人证件号', 'se_common_compare', {}, '主合同共借人证件号码与系统不一致'), | ||
| 123 | '共借人&抵押人证件号': ('共借人证件号', 'se_common_compare', {}, '主合同共借人&抵押人证件号与系统不一致'), | ||
| 124 | '保证人姓名1': ('保证人姓名1', 'se_common_compare', {}, '主合同担保人1姓名与系统不一致'), | ||
| 125 | '保证人证件号1': ('保证人证件号1', 'se_common_compare', {}, '主合同担保人1证件号码与系统不一致'), | ||
| 126 | '保证人姓名2': ('保证人姓名2', 'se_common_compare', {}, '主合同担保人2姓名与系统不一致'), | ||
| 127 | '保证人证件号2': ('保证人证件号2', 'se_common_compare', {}, '主合同担保人2证件号码与系统不一致'), | ||
| 128 | |||
| 129 | '主借人签字': ('主借人签字', 'se_common_compare', {}, '合同主借款人签字与系统不一致'), | ||
| 130 | '主借人日期': ('主借人日期', 'se_have_compare', {}, '合同主借款人签字日期无'), | ||
| 131 | '共借人签字': ('共借人签字', 'se_common_compare', {}, '合同共借人签字与系统不一致'), | ||
| 132 | '共借人日期': ('共借人日期', 'se_have_compare', {}, '合同共借人签字日期无'), | ||
| 133 | '保证人签字1': ('保证人签字1', 'se_common_compare', {}, '合同担保人1签字与系统不一致'), | ||
| 134 | '保证人日期1': ('保证人日期1', 'se_have_compare', {}, '合同担保人1签字日期无'), | ||
| 135 | '保证人签字2': ('保证人签字2', 'se_common_compare', {}, '合同担保人2签字与系统不一致'), | ||
| 136 | '保证人日期2': ('保证人日期2', 'se_have_compare', {}, '合同担保人2签字日期无'), | ||
| 137 | |||
| 138 | '见证人签字': ('见证人签字', 'se_have_compare', {}, '合同见证人无'), | ||
| 139 | '见证人日期': ('见证人日期', 'se_date_contain_compare', {}, '合同见证人签字日期不符合逻辑'), | ||
| 140 | |||
| 141 | '还款计划表': ('还款计划表', 'se_schedule_compare', {"value_idx": 1}, '合同还款计划表与系统不一致'), | ||
| 142 | |||
| 143 | 'ASP项目详情-重要条款': ('ASP项目详情-重要条款', 'se_asp_compare', {}, '合同(重要条款)ASP名称或者金额与系统不一致'), | ||
| 144 | 'ASP项目详情': ('ASP项目详情', 'se_asp_compare', {}, '合同ASP名称或者金额与系统不一致'), | ||
| 145 | |||
| 146 | '购置税校验': ('购置税校验', 'se_self_compare_gzs', {}, GZS_REASON_2), | ||
| 147 | '无ASP产品': ('无ASP产品', 'se_self_compare_other_asp', {}, GZS_REASON_1), | ||
| 148 | '文档': ('文档', 'se_common_compare', {}, '请确认是否已完成车辆抵押贷款合同签署'), | ||
| 149 | } | ||
| 150 | |||
| 151 | # 售后回租合同(E-Sign-SLB / OC) | ||
| 152 | HIL_CONTRACT_1_COMPARE_LOGIC = { | ||
| 153 | '合同编号-每页': ('合同编号-每页', 'se_list_compare', {}, '售后回租合同中合同编号系统不一致'), | ||
| 154 | '合同编号-正文': ('合同编号-正文', 'se_common_compare', {}, '售后回租合同正文中合同编号系统不一致'), | ||
| 155 | '车辆识别代码': ('车辆识别代码', 'se_common_compare', {}, '售后回租合同车辆识别代码与系统车架号不一致'), | ||
| 156 | '车辆卖方': ('车辆卖方', 'se_common_compare', {}, '售后回租合同车辆卖方与系统经销商不一致'), | ||
| 157 | '车辆原始销售价格': ('车辆原始销售价格', 'se_amount_str_compare', {}, '售后回租合同车辆原始销售价格与系统车辆价格不一致'), | ||
| 158 | '融资成本总额': ('融资成本总额', 'se_amount_str_compare', {}, '售后回租合同融资成本总额与系统不一致'), | ||
| 159 | '租期': ('租期', 'se_contain_compare', {}, '售后回租合同首页中贷款期限系统不一致'), | ||
| 160 | '还款计划表': ('还款计划表', 'se_schedule_compare', {"value_idx": 1}, '售后回租合同还款计划表与系统不一致'), | ||
| 161 | 'ASP项目详情': ('ASP项目详情', 'se_asp_compare', {}, '售后回租合同ASP名称或者金额与系统不一致'), | ||
| 162 | '承租人法定代表人或授权代表': ('承租人法定代表人或授权代表', 'se_name_compare', {}, '售后回租合同承租人法定代表人或授权代表与系统不一致'), | ||
| 163 | '共同承租人法定代表人或授权代表': ('共同承租人法定代表人或授权代表', 'se_name_compare', {}, '售后回租合同共同承租人法定代表人或授权代表与系统不一致'), | ||
| 164 | '还款账号': ('还款账号', 'se_common_compare', {'remove_space': True}, '售后回租合同还款账号与系统不一致'), | ||
| 165 | '户名': ('户名', 'se_common_compare', {}, '售后回租合同户名与系统不一致'), | ||
| 166 | '开户行': ('开户行', 'se_both_contain_compare', {}, '售后回租合同开户行与系统不一致'), | ||
| 167 | |||
| 168 | '承租人姓名': ('承租人姓名', 'se_name_compare', {}, '售后回租合同承租人姓名与系统不一致'), | ||
| 169 | '承租人证件号': ('承租人证件号', 'se_common_compare', {}, '售后回租合同承租人证件号与系统不一致'), | ||
| 170 | '承租人签字': ('承租人签字', 'se_contain_compare', {}, '售后回租合同承租人签字与系统不一致'), | ||
| 171 | |||
| 172 | '共同承租人姓名': ('共同承租人姓名', 'se_name_compare', {}, '售后回租合同共同承租人姓名与系统不一致'), | ||
| 173 | '共同承租人&抵押人姓名': ('共同承租人&抵押人姓名', 'se_name_compare', {}, '售后回租合同共同承租人&抵押人姓名与系统不一致'), | ||
| 174 | '共同承租人证件号': ('共同承租人证件号', 'se_common_compare', {}, '售后回租合同共同承租人证件号与系统不一致'), | ||
| 175 | '共同承租人&抵押人证件号': ('共同承租人&抵押人证件号', 'se_common_compare', {}, '售后回租合同共同承租人&抵押人证件号与系统不一致'), | ||
| 176 | '共同承租人签字': ('共同承租人签字', 'se_contain_compare', {}, '售后回租合同共同承租人签字与系统不一致'), | ||
| 177 | |||
| 178 | '保证人姓名1': ('保证人姓名1', 'se_name_compare', {}, '售后回租合同保证人姓名1与系统不一致'), | ||
| 179 | '保证人证件号1': ('保证人证件号1', 'se_common_compare', {}, '售后回租合同保证人证件号1与系统不一致'), | ||
| 180 | '保证人签字1': ('保证人签字1', 'se_contain_compare', {}, '售后回租合同保证人签字1与系统不一致'), | ||
| 181 | |||
| 182 | '保证人姓名2': ('保证人姓名2', 'se_name_compare', {}, '售后回租合同保证人姓名2与系统不一致'), | ||
| 183 | '保证人证件号2': ('保证人证件号2', 'se_common_compare', {}, '售后回租合同保证人证件号2与系统不一致'), | ||
| 184 | '保证人签字2': ('保证人签字2', 'se_contain_compare', {}, '售后回租合同保证人签字2与系统不一致'), | ||
| 185 | |||
| 186 | '购置税校验': ('购置税校验', 'se_self_compare_gzs', {}, GZS_REASON_2), | ||
| 187 | '无ASP产品': ('无ASP产品', 'se_self_compare_other_asp', {}, GZS_REASON_1), | ||
| 188 | '文档': ('文档', 'se_common_compare', {}, '请确认是否已完成售后回租合同签署'), | ||
| 189 | } | ||
| 190 | |||
| 191 | # 车辆租赁抵押合同(E-Sign-SLB / OC) | ||
| 192 | HIL_CONTRACT_2_COMPARE_LOGIC = { | ||
| 193 | '合同编号': ('合同编号', 'se_common_compare', {}, '车辆租赁抵押合同合同编号与系统合同编号不一致'), | ||
| 194 | '合同编号-正文': ('合同编号-正文', 'se_common_compare', {}, '车辆租赁抵押合同正文合同编号与系统合同编号不一致'), | ||
| 195 | '车辆识别代码': ('车辆识别代码', 'se_common_compare', {}, '车辆租赁抵押合同车辆识别代码与系统车架号不一致'), | ||
| 196 | '租金总额': ('租金总额', 'se_amount_str_compare', {}, '车辆租赁抵押合同租金总额与系统租金总额不一致'), | ||
| 197 | '融资租赁期限': ('融资租赁期限', 'se_common_compare', {}, '车辆租赁抵押合同融资租赁期限与系统不一致'), | ||
| 198 | '抵押人': ('抵押人', 'se_name_compare', {}, '车辆租赁抵押合同抵押人姓名与系统不一致'), | ||
| 199 | '抵押人证件号码': ('抵押人证件号码', 'se_common_compare', {}, '车辆租赁抵押合同抵押人证件号码与系统不一致'), | ||
| 200 | '抵押人签字': ('抵押人签字', 'se_contain_compare', {}, '车辆租赁抵押合同抵押人签字与系统承租人姓名不一致'), | ||
| 201 | '抵押人配偶': ('抵押人配偶', 'se_name_compare', {}, '车辆租赁抵押合同抵押人配偶姓名与系统不一致'), | ||
| 202 | '抵押人配偶证件号码': ('抵押人配偶证件号码', 'se_common_compare', {}, '车辆租赁抵押合同抵押人配偶证件号码与系统不一致'), | ||
| 203 | '抵押人配偶签字': ('抵押人配偶签字', 'se_contain_compare', {}, '车辆租赁抵押合同抵押人签字与系统承租人配偶姓名不一致'), | ||
| 204 | '文档': ('文档', 'se_common_compare', {}, '请确认是否已完成车辆租赁抵押合同签署'), | ||
| 205 | } | ||
| 206 | |||
| 207 | # 抵押登记豁免函 | ||
| 208 | HMH_COMPARE_LOGIC = { | ||
| 209 | '借款人/承租人姓名': ('借款/承租人姓名', 'se_name_compare', {}, '抵押登记豁免函借款人/承租人姓名与系统不符'), | ||
| 210 | '借款人/承租人证件号': ('证件号码', 'se_common_compare', {}, '抵押登记豁免函借款人/承租人证件号码与系统不符'), | ||
| 211 | '申请号': ('合同编号', 'se_common_compare', {}, '抵押登记豁免函申请号与系统不符'), | ||
| 212 | '渠道': ('渠道', 'se_channel_compare', {}, '抵押登记豁免函渠道与系统不符'), | ||
| 213 | '签字': ('借款人签字/盖章', 'se_have_compare', {}, '抵押登记豁免函签字需人工核查'), | ||
| 214 | '文档': ('文档', 'se_common_compare', {}, '请确认是否已完成抵押登记豁免函签署') | ||
| 215 | } | ||
| 216 | |||
| 217 | # 保单 | ||
| 218 | BD_COMPARE_LOGIC = { | ||
| 219 | '被保险人姓名': ('被保险人姓名', 'super_list_compare', {'method': 'name'}, '保单被保险人姓名与系统不一致'), | ||
| 220 | '被保险人证件号码': ('被保险人证件号码', 'super_list_compare', {'method': 'common', 'is_bd_id': True}, '保单身份证号需人工核查'), | ||
| 221 | '车架号': ('车架号', 'se_common_compare', {}, '保单车架号与系统不一致'), | ||
| 222 | '机动车损失保险金额': ('机动车损失保险金额', 'se_amount_lte_compare', {}, '保单车损险异常'), | ||
| 223 | '第三者责任保险金额': ('机动车第三者责任保险金额', 'se_amount_lte_compare', {}, '保单三者险异常'), | ||
| 224 | '绝对免赔率': ('机动车损失保险绝对免赔率/绝对免赔额', 'se_one_compare', {}, '保单无绝对免赔项'), | ||
| 225 | '保险起始日期': ('保险起始日期', 'se_bd_date_compare', {'start': True}, '保单起始时间有误'), | ||
| 226 | '保险截止日期': ('保险截止日期', 'se_bd_date_compare', {}, '保单截止时间有误'), | ||
| 227 | '保单章': ('保单章', 'se_common_compare', {}, '保单无保单章'), | ||
| 228 | '第一受益人': ('特别约定第一受益人', 'se_common_compare', {}, '保单第一受益人需人工核查'), | ||
| 229 | '保险费合计': ('保险费合计', 'se_amount_lte_compare', {}, '保单保费疑似无法覆盖ASP保险融资'), | ||
| 230 | '文档': ('文档', 'se_common_compare', {}, '请确认是否提供保单') | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 234 | SE_COMPARE_FIELD = { | ||
| 235 | ID_EN: (IC_OCR_FIELD, ID_COMPARE_LOGIC, True), | ||
| 236 | MVI_EN: (MVI_OCR_FIELD, MVI_COMPARE_LOGIC, False), | ||
| 237 | BC_EN: (BC_OCR_FIELD, BC_COMPARE_LOGIC, False), | ||
| 238 | HMH_EN: (HMH_OCR_FIELD, HMH_COMPARE_LOGIC, False), | ||
| 239 | AFC_CONTRACT_EN: (HT_FIELD, HT_COMPARE_LOGIC, False), | ||
| 240 | BD_EN: (BD_FIELD, BD_COMPARE_LOGIC, False), | ||
| 241 | HIL_CONTRACT_1_EN: (HIL_CONTRACT_1_FIELD, HIL_CONTRACT_1_COMPARE_LOGIC, False), | ||
| 242 | HIL_CONTRACT_2_EN: (HIL_CONTRACT_2_FIELD, HIL_CONTRACT_2_COMPARE_LOGIC, False) | ||
| 243 | } | ||
| 244 | |||
| 245 | |||
| 246 | OCR_COMPARE_COMMENT = { | ||
| 247 | ID_EN: { | ||
| 248 | 'idExpiryDate': '身份证疑似过期', | ||
| 249 | 'customerName': '身份证姓名与系统不一致', | ||
| 250 | 'idNum': '身份证号码与系统不一致', | ||
| 251 | 'other': '请确认是否提供身份证件' | ||
| 252 | }, | ||
| 253 | MVI_EN: { | ||
| 254 | 'firstSubmmisonDate': '请确认发票开票日期,若发票开票日期早于首次提交审批日期则无法受理放款申请', | ||
| 255 | 'customerName': '发票购买方姓名与系统不一致', | ||
| 256 | 'idNum': '发票购买方证件号码与系统不一致', | ||
| 257 | 'vinNo': '发票车架号与系统不一致', | ||
| 258 | 'vehicleTransactionAmount': '发票车辆价格与系统不一致', | ||
| 259 | 'productGroupName': '请确认是否提供发票' | ||
| 260 | }, | ||
| 261 | BC_EN: { | ||
| 262 | 'bankName': '银行卡开户行与系统不一致', | ||
| 263 | 'accountNo': '银行卡卡号与系统不一致', | ||
| 264 | 'bankVerificationStatus': '请确认是否提供银行卡' | ||
| 265 | }, | ||
| 266 | AFC_CONTRACT_EN: { | ||
| 267 | 'applicationId & applicationVersion': '', | ||
| 268 | 'service': '', | ||
| 269 | 'amount': '', | ||
| 270 | 'financedAmount': '', | ||
| 271 | 'associatedServicePrincipal': '', | ||
| 272 | 'vinNo': '', | ||
| 273 | 'accountNo': '', | ||
| 274 | 'accountHolderName': '', | ||
| 275 | 'bankName': '', | ||
| 276 | 'term': '', | ||
| 277 | 'applicationEntity': '' | ||
| 278 | }, | ||
| 279 | HIL_CONTRACT_1_EN: { | ||
| 280 | |||
| 281 | }, | ||
| 282 | HIL_CONTRACT_2_EN: { | ||
| 283 | |||
| 284 | }, | ||
| 285 | BD_EN: { | ||
| 286 | '': '' | ||
| 287 | } | ||
| 288 | } |
File moved
src/prese/compare.py
0 → 100644
| 1 | import json | ||
| 2 | import consts | ||
| 3 | from common.tools.comparison import cp | ||
| 4 | |||
| 5 | |||
| 6 | empty_str = '' | ||
| 7 | |||
| 8 | |||
| 9 | def get_pos_compare_info(pos_info): | ||
| 10 | compare_info = {} | ||
| 11 | |||
| 12 | application_entity = pos_info.get('applicationEntity', 'AFC') | ||
| 13 | application_id = pos_info.get('applicationId', '') | ||
| 14 | application_version = str(pos_info.get('applicationVersion', '')) | ||
| 15 | first_submission_date = pos_info.get('firstSubmmisonDate', '') | ||
| 16 | |||
| 17 | application_id_version = '{0}-{1}'.format(application_id, application_version) | ||
| 18 | |||
| 19 | custr_name = custr_id = '' | ||
| 20 | |||
| 21 | # 身份证 | ||
| 22 | individual_cus_info_list = pos_info.get('individualCusInfo', []) | ||
| 23 | for individual_cus_info in individual_cus_info_list: | ||
| 24 | customer_name = individual_cus_info.get('customerName', '').strip() | ||
| 25 | id_num = individual_cus_info.get('idNum', '') | ||
| 26 | |||
| 27 | if individual_cus_info.get('applicantType', '') == 'CUSTR': | ||
| 28 | custr_name = customer_name | ||
| 29 | custr_id = id_num | ||
| 30 | |||
| 31 | if individual_cus_info.get('idType', '') == consts.ID_TYPE: | ||
| 32 | field_input = [(consts.ID_FIELDS[0], customer_name), | ||
| 33 | (consts.ID_FIELDS[1], id_num), | ||
| 34 | (consts.ID_FIELDS[2], individual_cus_info.get('idExpiryDate', ''))] | ||
| 35 | compare_info.setdefault(consts.ID_EN, []).append(field_input) | ||
| 36 | |||
| 37 | # 新车发票 | ||
| 38 | vehicle_info = pos_info.get('vehicleInfo', {}) | ||
| 39 | vin_no = vehicle_info.get('vinNo', '') | ||
| 40 | amount = str(vehicle_info.get('vehicleTransactionAmount', '0.0')) | ||
| 41 | field_input = [ | ||
| 42 | (consts.MVI_FIELDS[0], vin_no), | ||
| 43 | (consts.MVI_FIELDS[1], amount), | ||
| 44 | (consts.MVI_FIELDS[2], custr_name), | ||
| 45 | (consts.MVI_FIELDS[3], custr_id), | ||
| 46 | (consts.MVI_FIELDS[4], first_submission_date), | ||
| 47 | (consts.MVI_FIELDS[5], consts.MVI_FPL_VALUE), | ||
| 48 | ] | ||
| 49 | compare_info.setdefault(consts.MVI_EN, []).append(field_input) | ||
| 50 | |||
| 51 | # 银行卡 | ||
| 52 | bank_info = pos_info.get('bankInfo', {}) | ||
| 53 | bank_status = bank_info.get('bankVerificationStatus', '') | ||
| 54 | |||
| 55 | if bank_status != 'PASS': | ||
| 56 | account_no = bank_info.get('accountNo', '') | ||
| 57 | bank_name = bank_info.get('bankName', '') | ||
| 58 | |||
| 59 | field_input = [ | ||
| 60 | (consts.BC_FIELDS[0], account_no), | ||
| 61 | (consts.BC_FIELDS[1], bank_name), | ||
| 62 | (consts.BC_FIELDS[2], consts.BC_TYPE_VALUE) # 是否为借记卡 | ||
| 63 | ] | ||
| 64 | compare_info.setdefault(consts.BC_EN, []).append(field_input) | ||
| 65 | |||
| 66 | # 抵押登记豁免函 | ||
| 67 | quotationt_info = pos_info.get('quotationtInfo', {}) | ||
| 68 | if quotationt_info.get('mortgageType', '') == 'MOTGF': | ||
| 69 | field_input = [ | ||
| 70 | (consts.HMH_FIELDS[0], custr_name), | ||
| 71 | (consts.HMH_FIELDS[1], custr_id), | ||
| 72 | (consts.HMH_FIELDS[2], application_id_version), | ||
| 73 | # 宝马金融(中国)有限公司 先锋国际融资租赁有限公司 | ||
| 74 | (consts.HMH_FIELDS[3], consts.HMH_CHANNEL_MAP.get(application_entity, '')), | ||
| 75 | (consts.HMH_FIELDS[4], consts.HAVE_CN), | ||
| 76 | ] | ||
| 77 | compare_info.setdefault(consts.HMH_EN, []).append(field_input) | ||
| 78 | |||
| 79 | # 保单 | ||
| 80 | insurance_info = pos_info.get('insuranceInfo', {}) | ||
| 81 | if insurance_info.get('insuranceType') == 'ITCOM': | ||
| 82 | field_input = [ | ||
| 83 | (consts.BD_FIELDS[0], [custr_name, ]), | ||
| 84 | (consts.BD_FIELDS[1], [custr_id, ]), | ||
| 85 | (consts.BD_FIELDS[2], vin_no) | ||
| 86 | ] | ||
| 87 | compare_info.setdefault(consts.BD_EN, []).append(field_input) | ||
| 88 | |||
| 89 | # HIL合同 | ||
| 90 | if application_entity in consts.HIL_SET: | ||
| 91 | pass | ||
| 92 | # AFC合同 | ||
| 93 | else: | ||
| 94 | pass | ||
| 95 | |||
| 96 | return compare_info | ||
| 97 | |||
| 98 | |||
| 99 | def pre_compare_process(compare_info, ocr_res_dict, id_res_list): | ||
| 100 | compare_result = {} | ||
| 101 | for license_en, items_list in compare_info.items(): | ||
| 102 | if license_en == consts.ID_EN: | ||
| 103 | for field_list in items_list: | ||
| 104 | result_list = pre_compare_license_id(license_en, id_res_list, field_list) | ||
| 105 | compare_result.setdefault(license_en, []).append(result_list) | ||
| 106 | elif license_en in [consts.HIL_CONTRACT_1_EN, consts.HIL_CONTRACT_2_EN, | ||
| 107 | consts.HIL_CONTRACT_3_EN, consts.AFC_CONTRACT_EN]: | ||
| 108 | pass | ||
| 109 | else: | ||
| 110 | for field_list in items_list: | ||
| 111 | result_list = pre_compare_license(license_en, ocr_res_dict, field_list) | ||
| 112 | compare_result.setdefault(license_en, []).append(result_list) | ||
| 113 | return compare_result | ||
| 114 | |||
| 115 | |||
| 116 | def pre_compare_license(license_en, ocr_res_dict, field_list): | ||
| 117 | ocr_field, compare_logic, no_find_comment = consts.PRE_COMPARE_LOGIC_MAP[license_en] | ||
| 118 | |||
| 119 | is_find = False | ||
| 120 | result_field_list = [] | ||
| 121 | |||
| 122 | ocr_res_str = ocr_res_dict.get(ocr_field) | ||
| 123 | if ocr_res_str is not None: | ||
| 124 | ocr_res_list = json.loads(ocr_res_str) | ||
| 125 | length = len(ocr_res_list) | ||
| 126 | |||
| 127 | for res_idx in range(length-1, -1, -1): | ||
| 128 | if is_find: | ||
| 129 | break | ||
| 130 | |||
| 131 | for idx, (name, value) in enumerate(field_list): | ||
| 132 | ocr_str = ocr_res_list[res_idx].get(compare_logic[name][0]) | ||
| 133 | |||
| 134 | if isinstance(ocr_str, str): | ||
| 135 | result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2]) | ||
| 136 | else: | ||
| 137 | result = consts.RESULT_N | ||
| 138 | ocr_str = empty_str | ||
| 139 | |||
| 140 | if idx == 0 and result == consts.RESULT_N and length > 1: | ||
| 141 | break | ||
| 142 | |||
| 143 | is_find = True | ||
| 144 | |||
| 145 | if isinstance(value, list): | ||
| 146 | value = json.dumps(value, ensure_ascii=False) | ||
| 147 | result_field_list.append((value, ocr_str, result, compare_logic[name][3])) | ||
| 148 | |||
| 149 | if not is_find: | ||
| 150 | result_field_list.append((empty_str, empty_str, consts.RESULT_N, no_find_comment)) | ||
| 151 | |||
| 152 | return result_field_list | ||
| 153 | |||
| 154 | |||
| 155 | def pre_compare_license_id(license_en, id_res_list, field_list): | ||
| 156 | ocr_field, compare_logic, no_find_comment = consts.PRE_COMPARE_LOGIC_MAP[license_en] | ||
| 157 | |||
| 158 | is_find = False | ||
| 159 | result_field_list = [] | ||
| 160 | field_last_idx = len(field_list) - 1 | ||
| 161 | |||
| 162 | for ca_or_se_idx, ocr_res_str in enumerate(id_res_list): | ||
| 163 | if is_find: | ||
| 164 | break | ||
| 165 | |||
| 166 | if ocr_res_str is not None: | ||
| 167 | ocr_res_list = json.loads(ocr_res_str) | ||
| 168 | length = len(ocr_res_list) | ||
| 169 | |||
| 170 | # 身份证、居住证 过期期限特殊处理 | ||
| 171 | expiry_dates = set() | ||
| 172 | key = compare_logic.get('idExpiryDate')[0] | ||
| 173 | for ocr_res in ocr_res_list: | ||
| 174 | if key in ocr_res: | ||
| 175 | expiry_dates.add(ocr_res[key]) | ||
| 176 | |||
| 177 | for res_idx in range(length-1, -1, -1): | ||
| 178 | if is_find: | ||
| 179 | break | ||
| 180 | |||
| 181 | result_field_list.clear() | ||
| 182 | for idx, (name, value) in enumerate(field_list): | ||
| 183 | ocr_str = ocr_res_list[res_idx].get(compare_logic[name][0]) | ||
| 184 | if not isinstance(ocr_str, str): | ||
| 185 | result = consts.RESULT_N | ||
| 186 | ocr_str = empty_str | ||
| 187 | else: | ||
| 188 | result = getattr(cp, compare_logic[name][1])(value, ocr_str, **compare_logic[name][2]) | ||
| 189 | |||
| 190 | if idx == 0 and result == consts.RESULT_N: | ||
| 191 | if ca_or_se_idx == 0: | ||
| 192 | break | ||
| 193 | elif length > 1: | ||
| 194 | break | ||
| 195 | |||
| 196 | # 过期期限特殊处理 | ||
| 197 | if name == 'idExpiryDate' and result == consts.RESULT_N: | ||
| 198 | if len(expiry_dates) == 0: | ||
| 199 | ocr_str = empty_str | ||
| 200 | result = consts.RESULT_N | ||
| 201 | else: | ||
| 202 | for expiry_date in expiry_dates: | ||
| 203 | expiry_date_res = getattr(cp, compare_logic[name][1])(value, expiry_date, | ||
| 204 | **compare_logic[name][2]) | ||
| 205 | if expiry_date_res == consts.RESULT_N: | ||
| 206 | ocr_str = expiry_date | ||
| 207 | break | ||
| 208 | else: | ||
| 209 | ocr_str = empty_str | ||
| 210 | result = consts.RESULT_Y | ||
| 211 | |||
| 212 | if ca_or_se_idx == 0 and result == consts.RESULT_N: | ||
| 213 | break | ||
| 214 | |||
| 215 | if ca_or_se_idx == 1: | ||
| 216 | is_find = True | ||
| 217 | elif idx == field_last_idx: | ||
| 218 | is_find = True | ||
| 219 | |||
| 220 | if isinstance(value, list): | ||
| 221 | value = json.dumps(value, ensure_ascii=False) | ||
| 222 | result_field_list.append((value, ocr_str, result, compare_logic[name][3])) | ||
| 223 | |||
| 224 | if not is_find: | ||
| 225 | result_field_list = [(empty_str, empty_str, consts.RESULT_N, no_find_comment)] | ||
| 226 | |||
| 227 | return result_field_list | ||
| 228 | |||
| 229 | |||
| 230 | def rebuild_result(compare_result): | ||
| 231 | # compare_result = { | ||
| 232 | # "is_pass": True, | ||
| 233 | # "particulars": [{ | ||
| 234 | # "object_name": "PRC ID", | ||
| 235 | # "fields": [{ | ||
| 236 | # "input": "张三", | ||
| 237 | # "ocr": "张三", | ||
| 238 | # "field_is_pass": True, | ||
| 239 | # "comments": "身份证姓名与系统不一致" | ||
| 240 | # }] | ||
| 241 | # }] | ||
| 242 | # } | ||
| 243 | is_pass = True | ||
| 244 | particulars_list = [] | ||
| 245 | for license_en, items_list in compare_result.items(): | ||
| 246 | for result_field_list in items_list: | ||
| 247 | field_list = [] | ||
| 248 | for input_str, ocr_str, result, comments in result_field_list: | ||
| 249 | if result == consts.RESULT_N: | ||
| 250 | is_pass = False | ||
| 251 | field_list.append( | ||
| 252 | { | ||
| 253 | 'input': input_str, | ||
| 254 | 'ocr': ocr_str, | ||
| 255 | 'field_is_pass': result == consts.RESULT_Y, | ||
| 256 | 'comments': comments, | ||
| 257 | } | ||
| 258 | ) | ||
| 259 | particulars_list.append( | ||
| 260 | { | ||
| 261 | 'object_name': license_en, | ||
| 262 | 'fields': field_list | ||
| 263 | } | ||
| 264 | ) | ||
| 265 | rebuild_compare_result = { | ||
| 266 | 'is_pass': is_pass, | ||
| 267 | 'particulars': particulars_list | ||
| 268 | } | ||
| 269 | return rebuild_compare_result | ||
| 270 | |||
| 271 | |||
| 272 | def pre_compare(pos_info, ocr_res_dict, id_res_list): | ||
| 273 | compare_info = get_pos_compare_info(pos_info) | ||
| 274 | compare_result = pre_compare_process(compare_info, ocr_res_dict, id_res_list) | ||
| 275 | rebuild_compare_result = rebuild_result(compare_result) | ||
| 276 | return rebuild_compare_result | ||
| 277 | |||
| 278 | |||
| 279 | def get_empty_result(): | ||
| 280 | empty_result = { | ||
| 281 | "is_pass": False, | ||
| 282 | "particulars": [{ | ||
| 283 | "object_name": "", | ||
| 284 | "fields": [{ | ||
| 285 | "input": "", | ||
| 286 | "ocr": "", | ||
| 287 | "field_is_pass": False, | ||
| 288 | "comments": "未查找到OCR识别结果" | ||
| 289 | }] | ||
| 290 | }] | ||
| 291 | } | ||
| 292 | return empty_result | ||
| 293 | |||
| 294 | |||
| 295 | |||
| 296 |
src/prese/consts.py
0 → 100644
| 1 | HIL_SET = {'HIL', 'HIl', 'HiL', 'Hil', 'hIL', 'hIl', 'hiL', 'hil', 'CO00002', 'SF5_CL'} | ||
| 2 | |||
| 3 | ID_TYPE = 'ITPRC' | ||
| 4 | ID_FIELDS = ['姓名', '身份证号码', '有效期限'] | ||
| 5 | |||
| 6 | MVI_FIELDS = ['车架号', '价税合计(小写)', '购买方姓名', '购买方证件号码', '开票日期', '发票联'] | ||
| 7 | MVI_FPL_VALUE = '发票联' | ||
| 8 | |||
| 9 | BC_FIELDS = ['卡号', '开户行名称', '卡片类型'] | ||
| 10 | BC_TYPE_VALUE = '借记卡' | ||
| 11 | |||
| 12 | HMH_FIELDS = ['借款人/承租人姓名', '借款人/承租人证件号', '申请号', '渠道', '签字'] | ||
| 13 | HMH_CHANNEL_MAP = { | ||
| 14 | 'AFC': '宝马金融(中国)有限公司', | ||
| 15 | 'HIL': '先锋国际融资租赁有限公司' | ||
| 16 | } | ||
| 17 | HAVE_CN = '有' | ||
| 18 | |||
| 19 | BD_FIELDS = ['被保险人姓名', '被保险人证件号码', '车架号'] | ||
| 20 | |||
| 21 | ID_EN = 'idCard' | ||
| 22 | MVI_EN = 'newCar Invoice' | ||
| 23 | BC_EN = 'Bank Card' | ||
| 24 | HMH_EN = 'Mortgage Waiver Letter' | ||
| 25 | BD_EN = 'Insurance' | ||
| 26 | |||
| 27 | ID_OCR_FIELD = 'ic_ocr' | ||
| 28 | MVI_OCR_FIELD = 'mvi_ocr' | ||
| 29 | BC_OCR_FIELD = 'bc_ocr' | ||
| 30 | HMH_OCR_FIELD = 'hmh_ocr' | ||
| 31 | BD_FIELD = 'bd_ocr' | ||
| 32 | |||
| 33 | MVI_COMPARE_LOGIC = { | ||
| 34 | MVI_FIELDS[0]: ('车辆识别代码', 'se_common_compare', {}, '发票车架号与系统不一致'), | ||
| 35 | MVI_FIELDS[1]: ('价税合计小写', 'se_amount_compare', {}, '发票车辆价格与系统不一致'), | ||
| 36 | MVI_FIELDS[2]: ('购方名称', 'se_name_compare', {'is_passport': True, 'replace_kuohao': True}, '发票购买方姓名与系统不一致'), | ||
| 37 | MVI_FIELDS[3]: ('购买方身份证号或组织机构代码', 'se_common_compare', {}, '发票购买方证件号码与系统不一致'), | ||
| 38 | MVI_FIELDS[4]: ('开票日期', 'se_date_compare_2', {'three_month': True}, '请确认发票开票日期,若发票开票日期早于首次提交审批日期则无法受理放款申请'), | ||
| 39 | MVI_FIELDS[5]: ('发票类型', 'se_common_compare', {}, '发票疑似非发票联'), | ||
| 40 | } | ||
| 41 | |||
| 42 | BC_COMPARE_LOGIC = { | ||
| 43 | BC_FIELDS[0]: ('CardNum', 'se_common_compare', {'remove_space': True}, '银行卡卡号与系统不一致'), | ||
| 44 | BC_FIELDS[1]: ('BankName', 'se_both_contain_compare', {}, '银行卡开户行与系统不一致'), | ||
| 45 | BC_FIELDS[2]: ('CardType', 'se_common_compare', {}, '银行卡疑似非借记卡'), | ||
| 46 | } | ||
| 47 | |||
| 48 | HMH_COMPARE_LOGIC = { | ||
| 49 | HMH_FIELDS[0]: ('借款/承租人姓名', 'se_name_compare', {}, '抵押登记豁免函借款人/承租人姓名与系统不符'), | ||
| 50 | HMH_FIELDS[1]: ('证件号码', 'se_common_compare', {}, '抵押登记豁免函借款人/承租人证件号码与系统不符'), | ||
| 51 | HMH_FIELDS[2]: ('合同编号', 'se_common_compare', {}, '抵押登记豁免函申请号与系统不符'), | ||
| 52 | HMH_FIELDS[3]: ('渠道', 'se_channel_compare', {}, '抵押登记豁免函渠道与系统不符'), | ||
| 53 | HMH_FIELDS[4]: ('借款人签字/盖章', 'se_common_compare', {}, '抵押登记豁免函无签字'), | ||
| 54 | } | ||
| 55 | |||
| 56 | BD_COMPARE_LOGIC = { | ||
| 57 | BD_FIELDS[0]: ('被保险人姓名', 'super_list_compare', {'method': 'name'}, '保单被保险人姓名与系统不一致'), | ||
| 58 | BD_FIELDS[1]: ('被保险人证件号码', 'super_list_compare', {'method': 'common', 'is_bd_id': True}, '保单身份证号需人工核查'), | ||
| 59 | BD_FIELDS[2]: ('车架号', 'se_common_compare', {}, '保单车架号与系统不一致'), | ||
| 60 | } | ||
| 61 | |||
| 62 | PRE_COMPARE_LOGIC_MAP = { | ||
| 63 | ID_EN: (ID_OCR_FIELD, ID_COMPARE_LOGIC, '请确认是否提供身份证件'), | ||
| 64 | MVI_EN: (MVI_OCR_FIELD, MVI_COMPARE_LOGIC, '请确认是否提供发票'), | ||
| 65 | BC_EN: (BC_OCR_FIELD, BC_COMPARE_LOGIC, '请确认是否提供银行卡'), | ||
| 66 | HMH_EN: (HMH_OCR_FIELD, HMH_COMPARE_LOGIC, '请确认是否已完成抵押登记豁免函签署'), | ||
| 67 | BD_EN: (BD_FIELD, BD_COMPARE_LOGIC, '请确认是否提供保单'), | ||
| 68 | AFC_CONTRACT_EN: (HT_FIELD, HT_COMPARE_LOGIC, '请确认是否已完成车辆抵押贷款合同签署'), | ||
| 69 | HIL_CONTRACT_1_EN: (HIL_CONTRACT_1_FIELD, HIL_CONTRACT_1_COMPARE_LOGIC, '请确认是否已完成售后回租合同签署'), | ||
| 70 | HIL_CONTRACT_2_EN: (HIL_CONTRACT_2_FIELD, HIL_CONTRACT_2_COMPARE_LOGIC, '请确认是否已完成车辆租赁抵押合同签署'), | ||
| 71 | } | ||
| 72 | |||
| 73 | RESULT_Y = 'Y' | ||
| 74 | RESULT_N = 'N' | ||
| 75 |
-
Please register or sign in to post a comment