prese part 1
Showing
11 changed files
with
485 additions
and
2315 deletions
... | @@ -1234,26 +1234,39 @@ RESULT_MAPPING = { | ... | @@ -1234,26 +1234,39 @@ 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,) | ||
1238 | |||
1239 | COMPARE_FIELDS = ( | ||
1240 | MVI_OCR_FIELD, | ||
1241 | IC_OCR_FIELD, | ||
1242 | RP_OCR_FIELD, | ||
1243 | BC_OCR_FIELD, | ||
1244 | BL_OCR_FIELD, | ||
1245 | UCI_OCR_FIELD, | ||
1246 | EEP_OCR_FIELD, | ||
1247 | DL_OCR_FIELD, | ||
1248 | PP_OCR_FIELD, | ||
1249 | MVC_OCR_FIELD, | ||
1250 | DDA_OCR_FIELD, | ||
1251 | HMH_OCR_FIELD, | ||
1252 | JYPZ_OCR_FIELD, | ||
1253 | HT_FIELD, | ||
1254 | BD_FIELD, | ||
1255 | BS_FIELD, | ||
1256 | HIL_CONTRACT_1_FIELD, | ||
1257 | HIL_CONTRACT_2_FIELD, | ||
1258 | HIL_CONTRACT_3_FIELD, | ||
1259 | ) | ||
1237 | 1260 | ||
1238 | COMPARE_FIELDS = (MVI_OCR_FIELD, | 1261 | PRE_COMPARE_FIELDS = ( |
1239 | IC_OCR_FIELD, | 1262 | MVI_OCR_FIELD, |
1240 | RP_OCR_FIELD, | 1263 | IC_OCR_FIELD, |
1241 | BC_OCR_FIELD, | 1264 | BC_OCR_FIELD, |
1242 | BL_OCR_FIELD, | 1265 | HMH_OCR_FIELD, |
1243 | UCI_OCR_FIELD, | 1266 | HT_FIELD, |
1244 | EEP_OCR_FIELD, | 1267 | BD_FIELD, |
1245 | DL_OCR_FIELD, | 1268 | HIL_CONTRACT_1_FIELD, |
1246 | PP_OCR_FIELD, | 1269 | HIL_CONTRACT_2_FIELD, |
1247 | MVC_OCR_FIELD, | ||
1248 | DDA_OCR_FIELD, | ||
1249 | HMH_OCR_FIELD, | ||
1250 | JYPZ_OCR_FIELD, | ||
1251 | HT_FIELD, | ||
1252 | BD_FIELD, | ||
1253 | BS_FIELD, | ||
1254 | HIL_CONTRACT_1_FIELD, | ||
1255 | HIL_CONTRACT_2_FIELD, | ||
1256 | HIL_CONTRACT_3_FIELD, | ||
1257 | ) | 1270 | ) |
1258 | 1271 | ||
1259 | # 身份证 | 1272 | # 身份证 | ... | ... |
... | @@ -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,34 +761,45 @@ class CompareView(GenericView): | ... | @@ -754,34 +761,45 @@ 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 | ||
770 | bank_class = HILbankVerification if business_type in consts.HIL_SET else AFCbankVerification | 779 | # 存库, 用于银行卡比对 |
771 | bank_obj = bank_class.objects.filter(application_id=application_id).first() | 780 | try: |
781 | bank_class = HILbankVerification if business_type in consts.HIL_SET else AFCbankVerification | ||
782 | bank_obj = bank_class.objects.filter(application_id=application_id).first() | ||
772 | 783 | ||
773 | if bank_obj is None and bank_verify == 'PASS': | 784 | if bank_obj is None and bank_verify == 'PASS': |
774 | bank_class.objects.create( | 785 | bank_class.objects.create( |
775 | application_id=application_id, | 786 | application_id=application_id, |
776 | ) | 787 | ) |
777 | elif bank_obj is not None and bank_verify == 'PASS' and bank_obj.on_off is False: | 788 | elif bank_obj is not None and bank_verify == 'PASS' and bank_obj.on_off is False: |
778 | bank_obj.on_off = True | 789 | bank_obj.on_off = True |
779 | bank_obj.save() | 790 | bank_obj.save() |
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