Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
周伟奇
/
bmw-ocr
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
f80b8302
authored
2022-08-24 18:32:44 +0800
by
周伟奇
Browse Files
Options
Browse Files
Tag
Download
Plain Diff
Merge branch 'feature/SE3'
2 parents
6dce1268
94c1a856
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
593 additions
and
198 deletions
src/apps/doc/consts.py
src/apps/doc/management/commands/ocr_process.py
src/apps/doc/models.py
src/apps/doc/ocr/wb.py
src/apps/doc/views.py
src/celery_compare/tasks.py
src/common/tools/comparison.py
src/common/tools/mssql_script18.py
src/common/tools/pdf_to_img.py
src/apps/doc/consts.py
View file @
f80b830
...
...
@@ -1031,9 +1031,9 @@ JYPZ_FIELD_ORDER = (("type", "标题"),
(
"buyer_id"
,
"购买方身份证号码/营业执照号码"
),
(
"vin"
,
"车辆识别代号/车架号码"
),
(
"price"
,
"车辆价格"
),
(
"date"
,
"购买方交易日期"
),
(
"date"
,
"出卖方交易日期"
),
(
"date"
,
"经销商交易日期"
),
(
"
buyer_
date"
,
"购买方交易日期"
),
(
"
seller_
date"
,
"出卖方交易日期"
),
(
"
agent_
date"
,
"经销商交易日期"
),
(
"stamp_signature_buyer"
,
"购买方签字/盖章"
),
(
"stamp_signature_seller"
,
"出卖方签字/盖章"
),
(
"stamp_signature_agent"
,
"经销商签字/盖章"
),)
...
...
@@ -1439,6 +1439,8 @@ SE_BS_FIELD = ['户名', '打印日期', '流水日期', '(担保人1)户名', '
SE_HMH_FIELD
=
[
'借款人/承租人姓名'
,
'借款人/承租人证件号'
,
'申请号'
,
'渠道'
,
'签字'
]
SE_BD_FIELD
=
[
'被保险人姓名'
,
'被保险人证件号码'
,
'车架号'
,
'机动车损失保险金额'
,
'第三者责任保险金额'
,
'绝对免赔率'
,
'保险起始日期'
,
'保险截止日期'
,
'保单章'
,
'第一受益人'
,
'保险费合计'
]
JDMPV_VALUE
=
[
'-'
,
'--'
,
'0
%
'
,
'0.00'
,
'/'
,
'0'
,
''
]
JYPZ_TYPE_1
=
[
'二手车交易凭证'
]
JYPZ_TYPE_2
=
[
'BMW官方认证二手车交易凭证'
,
'二手车交易凭证'
]
SE_BANK_FIELD
=
[
'accountNo'
,
'bankName'
]
SE_DDA_FIELD
=
[
'applicationId(1)'
,
'applicationId(2)'
,
'bankName'
,
'companyName'
,
'customerName'
,
'idNum'
,
'accountHolderName'
,
'accountNo'
]
...
...
@@ -1582,19 +1584,21 @@ SE_HIL_CON_MAP = {
SE_AFC_CON_FIELD
=
[
'合同编号-每页'
,
'所购车辆价格-小写-重要条款'
,
'车架号-重要条款'
,
'贷款本金金额-重要条款'
,
'贷款期限-重要条款'
,
'车辆贷款本金金额-重要条款'
,
'附加产品融资贷款本金总额-重要条款'
,
'所购车辆价格'
,
'车架号'
,
'经销商'
,
'贷款本金金额'
,
'车辆贷款本金金额'
,
'附加产品融资贷款本金总额'
,
'贷款期限'
,
'还款账号'
,
'户名'
,
'开户行'
,
'还款计划表'
,
'见证人签字'
,
'见证人日期'
,
'ASP项目详情-重要条款'
,
'购置税校验'
,
'ASP项目详情'
]
'还款计划表'
,
'见证人签字'
,
'见证人日期'
,
'ASP项目详情-重要条款'
,
'购置税校验'
,
'ASP项目详情'
,
'合同编号-每页(no-asp)'
,
'无ASP产品'
]
CON_BANK_FIELD
=
[
'还款账号'
,
'户名'
,
'开户行'
]
# '承租人姓名', '承租人证件号码', '承租人法定代表人或授权代表'
SE_HIL_CON_1_FIELD
=
[
'合同编号-每页'
,
'合同编号-正文'
,
'车辆识别代码'
,
'车辆卖方'
,
'车辆原始销售价格'
,
'融资成本总额'
,
'租期'
,
'还款计划表'
,
'ASP项目详情'
,
'购置税校验'
,
'承租人法定代表人或授权代表'
,
'还款账号'
,
'户名'
,
'开户行'
,
'共同承租人法定代表人或授权代表'
]
'共同承租人法定代表人或授权代表'
,
'无ASP产品'
]
SE_HIL_CON_2_FIELD
=
[
'合同编号'
,
'合同编号-正文'
,
'车辆识别代码'
,
'租金总额'
,
'融资租赁期限'
]
SE_HIL_CON_3_FIELD
=
[
'合同编号-每页'
,
'承租人姓名'
,
'承租人证件号码'
,
'销售经销商'
,
'合同编号-正文'
,
'姓名/名称'
,
'自然人身份证件号码/法人执照号码'
,
'承租人签字'
]
ROLE_LIST
=
[
# key_afc1, cdfl_key, app_type, id_idx, field_idx, is_force, e_write
(
'借款人签字及时间'
,
'借款人签字及时间'
,
'Borrower'
,
0
,
0
,
True
,
False
),
(
'借款人姓名'
,
'借款人姓名'
,
'Borrower'
,
0
,
0
,
True
,
True
),
(
'借款人证件号'
,
'借款人证件号'
,
'Borrower'
,
0
,
2
,
True
,
True
),
...
...
@@ -1810,14 +1814,21 @@ DDA_COMPARE_LOGIC = {
}
JYPZ_COMPARE_LOGIC
=
{
'type'
:
(
'type'
,
'super_list_compare'
,
{},
'二手车凭证类型与产品不符'
),
'vinNo'
:
(
'vin'
,
'se_common_compare'
,
{},
'二手车凭证车辆识别代号与系统车架号不一致'
),
'dealerName'
:
(
'authorized_dealer'
,
'se_common_compare'
,
{},
'二手车凭证经销商与系统经销商不一致'
),
'vehicleTransactionAmount'
:
(
'price'
,
'se_amount_compare'
,
{},
'二手车凭证购买方交易价格与系统车辆价格不一致'
),
'customerName'
:
(
'buyer_name'
,
'se_name_compare'
,
{
'is_passport'
:
True
},
'二手车凭证购买方姓名与系统主借人姓名不一致'
),
'idNum'
:
(
'buyer_id'
,
'se_contain_compare_2'
,
{},
'二手车凭证购买方证件号与系统主借人证件号不一致'
),
'date'
:
(
'date'
,
'se_date_compare_2'
,
{
'three_month'
:
True
},
'二手车凭证交易日期早于submissionDate'
),
# 'date': ('date', 'se_date_compare_2', {'three_month': True}, '二手车凭证交易日期早于submissionDate'),
'date'
:
(
'buyer_date'
,
'se_jypz_date_compare'
,
{},
'二手车交易凭证交易日期不一致或二手车凭证交易日期早于submissionDate'
),
}
JYPZ_DATE_FIELD_1
=
'date'
JYPZ_DATE_FIELD_2
=
'buyer_date'
JYPZ_DATE_FIELD_3
=
'seller_date'
JYPZ_DATE_FIELD_4
=
'agent_date'
HMH_COMPARE_LOGIC
=
{
'借款人/承租人姓名'
:
(
'借款/承租人姓名'
,
'se_name_compare'
,
{},
'抵押登记豁免函借款人/承租人姓名与系统不符'
),
'借款人/承租人证件号'
:
(
'证件号码'
,
'se_common_compare'
,
{},
'抵押登记豁免函借款人/承租人证件号码与系统不符'
),
...
...
@@ -1911,6 +1922,9 @@ HIL_CONTRACT_1_COMPARE_LOGIC = {
'保证人姓名2'
:
(
'保证人姓名2'
,
'se_name_compare'
,
{},
'售后回租合同保证人姓名2与系统不一致'
),
'保证人证件号2'
:
(
'保证人证件号2'
,
'se_common_compare'
,
{},
'售后回租合同保证人证件号2与系统不一致'
),
'保证人签字2'
:
(
'保证人签字2'
,
'se_contain_compare'
,
{},
'售后回租合同保证人签字2与系统不一致'
),
'购置税校验'
:
(
'购置税校验'
,
'se_self_compare_gzs'
,
{},
GZS_REASON_2
),
'无ASP产品'
:
(
'无ASP产品'
,
'se_self_compare_other_asp'
,
{},
GZS_REASON_1
),
}
# ['合同编号', '合同编号-正文', '车辆识别代码', '租金总额', '融资租赁期限']
...
...
@@ -1943,6 +1957,8 @@ HIL_CONTRACT_3_COMPARE_LOGIC = {
HT_COMPARE_LOGIC
=
{
'合同编号-每页'
:
(
'合同编号-每页'
,
'se_list_compare'
,
{},
'合同编号与系统不一致'
),
# '合同编号-每页(no-asp)': ('合同编号-每页', 'se_list_compare', {'pop_last': True}, '合同编号与系统不一致'),
'合同编号-每页(no-asp)'
:
(
'合同编号-每页'
,
'se_list_compare'
,
{},
'合同编号与系统不一致'
),
'所购车辆价格-小写-重要条款'
:
(
'所购车辆价格-小写-重要条款'
,
'se_amount_str_compare'
,
{},
'合同首页中车辆价格与系统不一致'
),
'车架号-重要条款'
:
(
'车架号-重要条款'
,
'se_common_compare'
,
{},
'合同首页中车架号与系统不一致'
),
'贷款本金金额-重要条款'
:
(
'贷款本金金额-重要条款'
,
'se_amount_str_compare'
,
{},
'合同首页中贷款本金与系统不一致'
),
...
...
@@ -1988,8 +2004,12 @@ HT_COMPARE_LOGIC = {
'ASP项目详情-重要条款'
:
(
'ASP项目详情-重要条款'
,
'se_asp_compare'
,
{},
'合同(重要条款)ASP名称或者金额与系统不一致'
),
'ASP项目详情'
:
(
'ASP项目详情'
,
'se_asp_compare'
,
{},
'合同ASP名称或者金额与系统不一致'
),
'购置税校验'
:
(
'购置税校验'
,
'se_self_compare_gzs'
,
{},
GZS_REASON_2
),
'无ASP产品'
:
(
'无ASP产品'
,
'se_self_compare_other_asp'
,
{},
GZS_REASON_1
),
}
AFC_HT_DATE_FIELDS
=
[
'主借人日期'
,
'共借人日期'
,
'保证人日期1'
,
'保证人日期2'
]
# MVC_OCR_FIELD = 'mvc_ocr'
...
...
src/apps/doc/management/commands/ocr_process.py
View file @
f80b830
...
...
@@ -919,6 +919,7 @@ class Command(BaseCommand, LoggerMixin):
'role'
:
bs_info
.
get
(
'role'
,
''
),
'print_time'
:
print_date
,
'timedelta'
:
bs_info
.
get
(
'timedelta'
,
''
),
'verify'
:
bs_info
.
get
(
'verify'
,
True
)
}
)
return
res
...
...
@@ -928,12 +929,14 @@ class Command(BaseCommand, LoggerMixin):
if
classify
==
consts
.
CONTRACT_CLASSIFY
:
res
=
{}
is_asp
=
page_info_dict
.
get
(
consts
.
ASP_KEY
,
False
)
# is_asp = True
for
key
,
(
pno_not_asp
,
pno_asp
,
key1
,
key2
)
in
consts
.
SE_AFC_CON_MAP
.
items
():
pno
=
pno_asp
if
is_asp
else
pno_not_asp
if
pno
is
None
:
if
isinstance
(
pno_asp
,
int
):
continue
end_idx
=
9
if
is_asp
else
8
end_idx
=
9
# end_idx = 9 if is_asp else 8
for
i
in
range
(
1
,
end_idx
):
res
.
setdefault
(
key
,
list
())
.
append
(
page_info_dict
.
get
(
str
(
i
),
{})
.
get
(
key1
,
''
))
elif
key2
is
None
:
...
...
src/apps/doc/models.py
View file @
f80b830
...
...
@@ -882,3 +882,26 @@ class AFCAutoSettlement(models.Model):
situ_db_label
=
'afc'
class
HILbankVerification
(
models
.
Model
):
id
=
models
.
AutoField
(
primary_key
=
True
,
verbose_name
=
"id"
)
# 主键
application_id
=
models
.
CharField
(
max_length
=
64
,
verbose_name
=
"申请id"
)
# 索引
on_off
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
"是否有效"
)
update_time
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
'修改时间'
)
create_time
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
'创建时间'
)
class
Meta
:
managed
=
False
db_table
=
'hil_bank_verification'
class
AFCbankVerification
(
models
.
Model
):
id
=
models
.
AutoField
(
primary_key
=
True
,
verbose_name
=
"id"
)
# 主键
application_id
=
models
.
CharField
(
max_length
=
64
,
verbose_name
=
"申请id"
)
# 索引
on_off
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
"是否有效"
)
update_time
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
'修改时间'
)
create_time
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
'创建时间'
)
class
Meta
:
managed
=
False
db_table
=
'afc_bank_verification'
situ_db_label
=
'afc'
...
...
src/apps/doc/ocr/wb.py
View file @
f80b830
...
...
@@ -392,7 +392,9 @@ class BSWorkbook(Workbook):
cell
.
fill
=
self
.
amount_fill
for
cell
in
ms
[
4
]:
cell
.
fill
=
self
.
amount_fill
return
ms
,
timedelta
verify_res
=
False
if
len
(
metadata_highlight_row
)
>
0
or
len
(
verify_highlight_row
)
>
0
else
True
return
ms
,
timedelta
,
verify_res
@staticmethod
def
amount_format
(
amount_str
):
...
...
@@ -723,20 +725,21 @@ class BSWorkbook(Workbook):
# 2.元信息提取表
confidence
=
self
.
get_confidence
(
max_find_count
,
classify
)
is_verify_classify
=
classify
in
consts
.
BS_VERIFY_CLASSIFY
ms
,
timedelta
=
self
.
build_meta_sheet
(
role_name
,
new_card
,
confidence
,
summary
.
get
(
'code'
),
summary
.
get
(
'verify'
),
summary
.
get
(
'print_time'
),
start_date
,
end_date
,
res_count_tuple
,
is_verify_classify
,
metadata
)
ms
,
timedelta
,
verify_res
=
self
.
build_meta_sheet
(
role_name
,
new_card
,
confidence
,
summary
.
get
(
'code'
),
summary
.
get
(
'verify'
),
summary
.
get
(
'print_time'
),
start_date
,
end_date
,
res_count_tuple
,
is_verify_classify
,
metadata
)
summary
[
'timedelta'
]
=
timedelta
summary
[
'end_date'
]
=
end_date
summary
[
'verify'
]
=
verify_res
# 3.创建月份表、提取/高亮关键行
# 倒序处理
...
...
src/apps/doc/views.py
View file @
f80b830
...
...
@@ -42,6 +42,8 @@ from .models import (
HILSECompareResultRecord
,
HILAutoSettlement
,
AFCAutoSettlement
,
HILbankVerification
,
AFCbankVerification
,
)
from
.named_enum
import
ErrorType
,
AutoResult
,
WholeResult
,
RPAResult
from
.mixins
import
DocHandler
,
MPOSHandler
...
...
@@ -112,7 +114,7 @@ se_bank_args = {
'applicantType'
:
fields
.
Str
(
required
=
True
,
validate
=
validate
.
Length
(
max
=
16
)),
'accountHolderName'
:
fields
.
Str
(
required
=
True
,
validate
=
validate
.
Length
(
max
=
256
)),
'accountNo'
:
fields
.
Str
(
required
=
True
,
validate
=
validate
.
Length
(
max
=
256
)),
'bankVerificationStatus'
:
fields
.
Str
(
required
=
False
,
validate
=
validate
.
Length
(
max
=
1
6
)),
'bankVerificationStatus'
:
fields
.
Str
(
required
=
False
,
validate
=
validate
.
Length
(
max
=
1
28
)),
'isAllDocUploaded'
:
fields
.
Boolean
(
required
=
False
)
}
...
...
@@ -249,10 +251,10 @@ applicant_data_args = {
# 'coApplicantName': fields.Str(required=True, validate=validate.Length(max=16)),
# 'guarantor1Name': fields.Str(required=True, validate=validate.Length(max=16)),
# 'guarantor2Name': fields.Str(required=True, validate=validate.Length(max=16)),
'mainApplicantName'
:
fields
.
Str
(
required
=
Tru
e
),
'coApplicantName'
:
fields
.
Str
(
required
=
Tru
e
),
'guarantor1Name'
:
fields
.
Str
(
required
=
Tru
e
),
'guarantor2Name'
:
fields
.
Str
(
required
=
Tru
e
),
'mainApplicantName'
:
fields
.
Str
(
required
=
Fals
e
),
'coApplicantName'
:
fields
.
Str
(
required
=
Fals
e
),
'guarantor1Name'
:
fields
.
Str
(
required
=
Fals
e
),
'guarantor2Name'
:
fields
.
Str
(
required
=
Fals
e
),
}
document_args
=
{
...
...
@@ -267,7 +269,7 @@ document_args = {
doc_upload_args
=
{
'applicationData'
:
fields
.
Nested
(
application_data_args
,
required
=
True
),
'applicantData'
:
fields
.
Nested
(
applicant_data_args
,
required
=
Tru
e
),
'applicantData'
:
fields
.
Nested
(
applicant_data_args
,
required
=
Fals
e
),
'document'
:
fields
.
Nested
(
document_args
,
required
=
True
),
}
...
...
@@ -748,61 +750,26 @@ class SECompareView(GenericView):
@use_args
(
se_compare_args
,
location
=
'data'
)
def
post
(
self
,
request
,
args
):
# 存库
# content = args.get('content', {})
# business_type = content.get('applicationEntity')
# application_id = content.get('applicationId')
# is_auto = content.get('isAutoSettlement', False)
#
# auto_class = HILAutoSettlement if business_type in consts.HIL_SET else AFCAutoSettlement
# auto_obj = auto_class.objects.filter(application_id=application_id).first()
# if is_auto:
# # 加入优先级队列
# PriorityApplication.objects.update_or_create(
# application_id=application_id, defaults={'on_off': True})
# # 加入auto表
# if auto_obj is None:
# auto_class.objects.create(
# application_id=application_id,
# )
# elif auto_obj.on_off is False:
# auto_obj.on_off = True
# auto_obj.save()
# else:
# if auto_obj is not None and auto_obj.on_off is True:
# auto_obj.on_off = False
# auto_obj.save()
return
response
.
ok
()
content
=
args
.
get
(
'content'
,
{})
business_type
=
content
.
get
(
'applicationEntity'
)
application_id
=
content
.
get
(
'applicationId'
)
bank_verify
=
content
.
get
(
'bankInfo'
,
{})
.
get
(
'bankVerificationStatus'
,
''
)
bank_class
=
HILbankVerification
if
business_type
in
consts
.
HIL_SET
else
AFCbankVerification
bank_obj
=
bank_class
.
objects
.
filter
(
application_id
=
application_id
)
.
first
()
if
bank_obj
is
None
and
bank_verify
==
'PASS'
:
bank_class
.
objects
.
create
(
application_id
=
application_id
,
)
elif
bank_obj
is
not
None
and
bank_verify
==
'PASS'
and
bank_obj
.
on_off
is
False
:
bank_obj
.
on_off
=
True
bank_obj
.
save
()
elif
bank_obj
is
not
None
and
bank_verify
!=
'PASS'
and
bank_obj
.
on_off
is
True
:
bank_obj
.
on_off
=
False
bank_obj
.
save
()
# uniq_seq = content.get('uniqSeq')
# business_type = content.get('applicationEntity')
# application_id = content.get('applicationId')
#
# individual_cus_info = json.dumps(content.get('individualCusInfo'))
# vehicle_info = json.dumps(content.get('vehicleInfo'))
# insurance_info = json.dumps(content.get('insuranceInfo'))
# bank_info = json.dumps(content.get('bankInfo'))
# quotationt_info = json.dumps(content.get('quotationtInfo'))
# corporate_cus_info = json.dumps(content.get('corporateCusInfo')) if isinstance(
# content.get('corporateCusInfo'), dict) else None
# comparison_class = HILSEComparisonInfo if business_type in consts.HIL_SET else AFCSEComparisonInfo
# comparison_class.objects.create(
# uniq_seq=uniq_seq,
# application_id=application_id,
# application_version=content.get('applicationVersion'),
# customer_type=content.get('customerType'),
# first_submmison_date=content.get('firstSubmmisonDate'),
# property_doc_policy=content.get('propertyDocumentPolicy', None),
# individual_cus_info=individual_cus_info,
# corporate_cus_info=corporate_cus_info,
# vehicle_info=vehicle_info,
# insurance_info=insurance_info,
# bank_info=bank_info,
# quotationt_info=quotationt_info
# )
# 触发比对
# compare.apply_async((application_id, business_type, uniq_seq, None, False, False),
# queue='queue_compare')
return
response
.
ok
()
post
.
openapi_doc
=
'''
tags: [info]
...
...
src/celery_compare/tasks.py
View file @
f80b830
...
...
@@ -29,6 +29,8 @@ from apps.doc.models import (
HILCACompareResult
,
HILAutoSettlement
,
AFCAutoSettlement
,
HILbankVerification
,
AFCbankVerification
,
)
from
apps.doc
import
consts
from
apps.doc.ocr.gcap
import
gcap
...
...
@@ -872,7 +874,7 @@ def ca_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res
traceback
.
format_exc
()))
def
get_se_cms_compare_info_auto
(
last_obj
,
application_entity
,
auto
=
True
):
def
get_se_cms_compare_info_auto
(
last_obj
,
application_entity
,
auto
=
True
,
ignore_bank
=
False
):
cms_info
=
json
.
loads
(
last_obj
.
content
)
compare_info
=
{}
...
...
@@ -1062,7 +1064,7 @@ def get_se_cms_compare_info_auto(last_obj, application_entity, auto=True):
# jypz_field_input.append(('dealerName', dealer_name))
# jypz_field_input.append(('vinNo', vin_no))
# jypz_field_input.append(('vehicleTransactionAmount', amount))
# jypz_field_input.append((consts.SE_GB_USED_FIELD[
-1
], first_submission_date))
# jypz_field_input.append((consts.SE_GB_USED_FIELD[
2
], first_submission_date))
#
# vehicle_info[consts.MVC_EN] = gb_field_input
# vehicle_info[consts.MVC34_EN] = gb34_field_input
...
...
@@ -1083,7 +1085,7 @@ def get_se_cms_compare_info_auto(last_obj, application_entity, auto=True):
if
isinstance
(
company_info
,
tuple
)
and
company_info
[
0
]
==
account_holder_name
:
pass
el
se
:
el
if
not
ignore_bank
:
bank_field_input
=
[
(
'accountNo'
,
account_no
),
(
'bankName'
,
bank_name
),
...
...
@@ -1158,20 +1160,17 @@ def get_se_cms_compare_info_auto(last_obj, application_entity, auto=True):
# ASP -------------------------------------------------------------------------------------------------------
asp_list
=
[]
gzs_status
=
consts
.
GZS_STATUS
[
1
]
gzs_list
=
[
gzs_status
]
gzs_price
=
'0.00'
is_asp
=
False
# insurance_price = None
insurance_price
=
None
gzs_price
=
None
have_other_asp
=
False
fin_total
=
0
if
str
(
cms_info
.
get
(
'financialInformation'
,
{})
.
get
(
'associatedServicePrincipal'
,
'0.00'
))
!=
'0.00'
:
is_asp
=
True
# for asp_info in cms_info.get('associatedServices', []):
for
asp_info
in
cms_info
.
get
(
'associatedServices'
,
{})
.
get
(
'SubassociatedServices'
,
[]):
tmp_asp_name
=
asp_info
.
get
(
'associatedServices'
)
if
isinstance
(
tmp_asp_name
,
str
)
and
len
(
tmp_asp_name
)
>
0
:
if
gzs_status
==
consts
.
GZS_STATUS
[
1
]
and
tmp_asp_name
.
find
(
consts
.
GZS_NAME
)
!=
-
1
:
gzs_status
=
consts
.
GZS_STATUS
[
2
]
gzs_price
=
asp_info
.
get
(
'price'
,
'0.00'
)
asp_list
.
append
(
(
tmp_asp_name
,
...
...
@@ -1179,17 +1178,16 @@ def get_se_cms_compare_info_auto(last_obj, application_entity, auto=True):
asp_info
.
get
(
'financed'
,
'0.00'
)
)
)
fin_total
+=
float
(
asp_info
.
get
(
'financed'
,
'0.00'
))
# 购置税
if
tmp_asp_name
.
find
(
consts
.
GZS_NAME
)
!=
-
1
:
gzs_price
=
asp_info
.
get
(
'price'
,
'0.00'
)
# 保单费合计
# if tmp_asp_name.find('机动车辆保险') != -1:
# insurance_price = asp_info.get('price', '0.00')
fin_total
=
0
# fin_total_tmp = cms_info.get('associatedServices', {}).get('financed total', '0.00')
# fin_total = '0.00' if fin_total_tmp.strip() == '' else fin_total_tmp
for
asp_name
,
_
,
asp_fin
in
asp_list
:
if
gzs_status
==
consts
.
GZS_STATUS
[
2
]
and
asp_name
.
find
(
consts
.
GZS_NAME
)
==
-
1
:
gzs_status
=
consts
.
GZS_STATUS
[
0
]
fin_total
+=
float
(
asp_fin
)
elif
tmp_asp_name
.
find
(
'机动车辆保险'
)
!=
-
1
:
insurance_price
=
asp_info
.
get
(
'price'
,
'0.00'
)
else
:
have_other_asp
=
True
asp_list
.
append
(
(
consts
.
ASP_SUM_NAME
,
...
...
@@ -1199,12 +1197,14 @@ def get_se_cms_compare_info_auto(last_obj, application_entity, auto=True):
)
)
# CMS Vehicle Price / 1.13 * 10 %
gzs_list
=
[
gzs_status
]
if
gzs_status
!=
consts
.
GZS_STATUS
[
1
]:
gzs_value
=
float
(
amount
)
*
0.1
/
1.13
gzs_list
.
append
(
gzs_value
)
gzs_list
.
append
(
float
(
gzs_price
))
# CMS Vehicle Price / 1.13 * 10 %
if
isinstance
(
gzs_price
,
str
):
try
:
tmp_gzs_list
=
[
float
(
amount
)
*
0.1
/
1.13
,
float
(
gzs_price
)]
except
Exception
as
e
:
tmp_gzs_list
=
[
amount
,
gzs_price
]
else
:
tmp_gzs_list
=
[
amount
,
]
# 保单 -----------------------------------------------------------------------------------------------------------
# is_insurance = 0
...
...
@@ -1272,8 +1272,15 @@ def get_se_cms_compare_info_auto(last_obj, application_entity, auto=True):
]
if
is_asp
:
# asp各项
hil_contract_1_input
.
append
((
consts
.
SE_HIL_CON_1_FIELD
[
8
],
asp_list
))
hil_contract_1_input
.
append
((
consts
.
SE_HIL_CON_1_FIELD
[
9
],
gzs_list
))
# 购置税校验
if
isinstance
(
gzs_price
,
str
):
hil_contract_1_input
.
append
(
(
consts
.
SE_HIL_CON_1_FIELD
[
9
],
tmp_gzs_list
))
# 非购置税非车辆保险的其他asp
if
have_other_asp
:
hil_contract_1_input
.
append
((
consts
.
SE_HIL_CON_1_FIELD
[
15
],
'N'
))
if
isinstance
(
company_info
,
tuple
):
if
is_cdfl
:
...
...
@@ -1343,8 +1350,17 @@ def get_se_cms_compare_info_auto(last_obj, application_entity, auto=True):
else
:
# AFC合同------------------------------------------------------------------------------------------------------
vehicle_principal_str
=
str
(
cms_info
.
get
(
'financialInformation'
,
{})
.
get
(
'vehiclePrincipal'
,
'0.0'
))
afc_contract_input
=
[
(
consts
.
SE_AFC_CON_FIELD
[
0
],
full_no
),
if
is_asp
:
afc_contract_input
=
[
(
consts
.
SE_AFC_CON_FIELD
[
0
],
full_no
),
]
else
:
afc_contract_input
=
[
(
consts
.
SE_AFC_CON_FIELD
[
23
],
full_no
),
]
afc_contract_input
.
extend
([
(
consts
.
SE_AFC_CON_FIELD
[
1
],
amount
),
(
consts
.
SE_AFC_CON_FIELD
[
2
],
vin_no
),
(
consts
.
SE_AFC_CON_FIELD
[
3
],
str
(
cms_info
.
get
(
'financialInformation'
,
{})
.
get
(
'originationPrincipal'
,
'0.0'
))),
...
...
@@ -1362,12 +1378,18 @@ def get_se_cms_compare_info_auto(last_obj, application_entity, auto=True):
(
consts
.
SE_AFC_CON_FIELD
[
15
],
account_holder_name
),
(
consts
.
SE_AFC_CON_FIELD
[
16
],
bank_name
),
(
consts
.
SE_AFC_CON_FIELD
[
17
],
schedule_list_str
),
]
]
)
if
is_asp
:
afc_contract_input
.
append
((
consts
.
SE_AFC_CON_FIELD
[
20
],
asp_list
))
afc_contract_input
.
append
((
consts
.
SE_AFC_CON_FIELD
[
22
],
asp_list
))
afc_contract_input
.
append
((
consts
.
SE_AFC_CON_FIELD
[
21
],
gzs_list
))
# 购置税校验
if
isinstance
(
gzs_price
,
str
):
afc_contract_input
.
append
(
(
consts
.
SE_AFC_CON_FIELD
[
21
],
tmp_gzs_list
))
# 非购置税非车辆保险的其他asp
if
have_other_asp
:
afc_contract_input
.
append
((
consts
.
SE_AFC_CON_FIELD
[
24
],
'N'
))
else
:
afc_contract_input
.
pop
(
5
)
afc_contract_input
.
pop
(
5
)
...
...
@@ -1399,7 +1421,7 @@ def get_se_cms_compare_info_auto(last_obj, application_entity, auto=True):
return
compare_info
,
cms_info
.
get
(
'autoApprovedDetails'
,
{})
.
get
(
'aaType'
,
''
),
is_gsyh
def
get_se_cms_compare_info
(
last_obj
,
application_entity
,
detect_list
,
auto
=
False
):
def
get_se_cms_compare_info
(
last_obj
,
application_entity
,
detect_list
,
auto
=
False
,
ignore_bank
=
False
):
cms_info
=
json
.
loads
(
last_obj
.
content
)
compare_info
=
{}
...
...
@@ -1522,6 +1544,7 @@ def get_se_cms_compare_info(last_obj, application_entity, detect_list, auto=Fals
# dda_num = '、'.join(dda_num_list)
# del main_role_info
fp_group
=
cms_info
.
get
(
'fpGroup'
,
''
)
vehicle_info
=
{}
vehicle_field_input
=
[]
vehicle_status
=
cms_info
.
get
(
'vehicleStatus'
,
''
)
...
...
@@ -1583,7 +1606,11 @@ def get_se_cms_compare_info(last_obj, application_entity, detect_list, auto=Fals
jypz_field_input
.
append
((
'dealerName'
,
dealer_name
))
jypz_field_input
.
append
((
'vinNo'
,
vin_no
))
jypz_field_input
.
append
((
'vehicleTransactionAmount'
,
amount
))
jypz_field_input
.
append
((
consts
.
SE_GB_USED_FIELD
[
-
1
],
first_submission_date
))
jypz_field_input
.
append
((
consts
.
SE_GB_USED_FIELD
[
2
],
first_submission_date
))
if
fp_group
.
find
(
'Non OCU Product Group'
)
!=
-
1
:
jypz_field_input
.
append
((
'type'
,
consts
.
JYPZ_TYPE_1
))
elif
fp_group
.
find
(
'OCU Product Group'
)
!=
-
1
:
jypz_field_input
.
append
((
'type'
,
consts
.
JYPZ_TYPE_2
))
vehicle_info
[
consts
.
MVC_EN
]
=
gb_field_input
vehicle_info
[
consts
.
MVC34_EN
]
=
gb34_field_input
...
...
@@ -1604,7 +1631,7 @@ def get_se_cms_compare_info(last_obj, application_entity, detect_list, auto=Fals
if
isinstance
(
company_info
,
tuple
)
and
company_info
[
0
]
==
account_holder_name
:
pass
el
se
:
el
if
not
ignore_bank
:
bank_field_input
=
[
(
'accountNo'
,
account_no
),
(
'bankName'
,
bank_name
),
...
...
@@ -1679,20 +1706,16 @@ def get_se_cms_compare_info(last_obj, application_entity, detect_list, auto=Fals
# ASP -------------------------------------------------------------------------------------------------------
asp_list
=
[]
gzs_status
=
consts
.
GZS_STATUS
[
1
]
gzs_list
=
[
gzs_status
]
gzs_price
=
'0.00'
is_asp
=
False
insurance_price
=
None
gzs_price
=
None
have_other_asp
=
False
fin_total
=
0
if
str
(
cms_info
.
get
(
'financialInformation'
,
{})
.
get
(
'associatedServicePrincipal'
,
'0.00'
))
!=
'0.00'
:
is_asp
=
True
# for asp_info in cms_info.get('associatedServices', []):
for
asp_info
in
cms_info
.
get
(
'associatedServices'
,
{})
.
get
(
'SubassociatedServices'
,
[]):
tmp_asp_name
=
asp_info
.
get
(
'associatedServices'
)
if
isinstance
(
tmp_asp_name
,
str
)
and
len
(
tmp_asp_name
)
>
0
:
if
gzs_status
==
consts
.
GZS_STATUS
[
1
]
and
tmp_asp_name
.
find
(
consts
.
GZS_NAME
)
!=
-
1
:
gzs_status
=
consts
.
GZS_STATUS
[
2
]
gzs_price
=
asp_info
.
get
(
'price'
,
'0.00'
)
asp_list
.
append
(
(
tmp_asp_name
,
...
...
@@ -1700,17 +1723,16 @@ def get_se_cms_compare_info(last_obj, application_entity, detect_list, auto=Fals
asp_info
.
get
(
'financed'
,
'0.00'
)
)
)
fin_total
+=
float
(
asp_info
.
get
(
'financed'
,
'0.00'
))
# 购置税
if
tmp_asp_name
.
find
(
consts
.
GZS_NAME
)
!=
-
1
:
gzs_price
=
asp_info
.
get
(
'price'
,
'0.00'
)
# 保单费合计
if
tmp_asp_name
.
find
(
'机动车辆保险'
)
!=
-
1
:
el
if
tmp_asp_name
.
find
(
'机动车辆保险'
)
!=
-
1
:
insurance_price
=
asp_info
.
get
(
'price'
,
'0.00'
)
else
:
have_other_asp
=
True
fin_total
=
0
# fin_total_tmp = cms_info.get('associatedServices', {}).get('financed total', '0.00')
# fin_total = '0.00' if fin_total_tmp.strip() == '' else fin_total_tmp
for
asp_name
,
_
,
asp_fin
in
asp_list
:
if
gzs_status
==
consts
.
GZS_STATUS
[
2
]
and
asp_name
.
find
(
consts
.
GZS_NAME
)
==
-
1
:
gzs_status
=
consts
.
GZS_STATUS
[
0
]
fin_total
+=
float
(
asp_fin
)
asp_list
.
append
(
(
consts
.
ASP_SUM_NAME
,
...
...
@@ -1720,19 +1742,20 @@ def get_se_cms_compare_info(last_obj, application_entity, detect_list, auto=Fals
)
)
# CMS Vehicle Price / 1.13 * 10 %
gzs_list
=
[
gzs_status
]
if
gzs_status
!=
consts
.
GZS_STATUS
[
1
]:
gzs_value
=
float
(
amount
)
*
0.1
/
1.13
gzs_list
.
append
(
gzs_value
)
gzs_list
.
append
(
float
(
gzs_price
))
# CMS Vehicle Price / 1.13 * 10 %
if
isinstance
(
gzs_price
,
str
):
try
:
tmp_gzs_list
=
[
float
(
amount
)
*
0.1
/
1.13
,
float
(
gzs_price
)]
except
Exception
as
e
:
tmp_gzs_list
=
[
amount
,
gzs_price
]
else
:
tmp_gzs_list
=
[
amount
,
]
# 保单 -----------------------------------------------------------------------------------------------------------
is_insurance
=
0
fp_campaign
=
cms_info
.
get
(
'fpCampaign'
,
''
)
fp_group
=
cms_info
.
get
(
'fpGroup'
,
''
)
insurance_type
=
cms_info
.
get
(
'insuranceDetails'
,
{})
.
get
(
'insuranceType'
,
''
)
if
i
nsurance_type
==
'Waive Insurance'
and
i
sinstance
(
insurance_price
,
str
):
if
isinstance
(
insurance_price
,
str
):
is_insurance
=
1
elif
insurance_type
==
'Comprehensive Insurance'
:
is_insurance
=
2
...
...
@@ -1793,8 +1816,14 @@ def get_se_cms_compare_info(last_obj, application_entity, detect_list, auto=Fals
]
if
is_asp
:
# asp各项
hil_contract_1_input
.
append
((
consts
.
SE_HIL_CON_1_FIELD
[
8
],
asp_list
))
hil_contract_1_input
.
append
((
consts
.
SE_HIL_CON_1_FIELD
[
9
],
gzs_list
))
# 购置税校验
if
isinstance
(
gzs_price
,
str
):
hil_contract_1_input
.
append
((
consts
.
SE_HIL_CON_1_FIELD
[
9
],
tmp_gzs_list
))
# 非购置税非车辆保险的其他asp
if
have_other_asp
:
hil_contract_1_input
.
append
((
consts
.
SE_HIL_CON_1_FIELD
[
15
],
'N'
))
if
isinstance
(
company_info
,
tuple
):
if
is_cdfl
:
...
...
@@ -1864,8 +1893,16 @@ def get_se_cms_compare_info(last_obj, application_entity, detect_list, auto=Fals
else
:
# AFC合同------------------------------------------------------------------------------------------------------
vehicle_principal_str
=
str
(
cms_info
.
get
(
'financialInformation'
,
{})
.
get
(
'vehiclePrincipal'
,
'0.0'
))
afc_contract_input
=
[
(
consts
.
SE_AFC_CON_FIELD
[
0
],
full_no
),
if
is_asp
:
afc_contract_input
=
[
(
consts
.
SE_AFC_CON_FIELD
[
0
],
full_no
),
]
else
:
afc_contract_input
=
[
(
consts
.
SE_AFC_CON_FIELD
[
23
],
full_no
),
]
afc_contract_input
.
extend
([
(
consts
.
SE_AFC_CON_FIELD
[
1
],
amount
),
(
consts
.
SE_AFC_CON_FIELD
[
2
],
vin_no
),
(
consts
.
SE_AFC_CON_FIELD
[
3
],
str
(
cms_info
.
get
(
'financialInformation'
,
{})
.
get
(
'originationPrincipal'
,
'0.0'
))),
...
...
@@ -1883,12 +1920,19 @@ def get_se_cms_compare_info(last_obj, application_entity, detect_list, auto=Fals
(
consts
.
SE_AFC_CON_FIELD
[
15
],
account_holder_name
),
(
consts
.
SE_AFC_CON_FIELD
[
16
],
bank_name
),
(
consts
.
SE_AFC_CON_FIELD
[
17
],
schedule_list_str
),
]
]
)
if
is_asp
:
# asp各项
afc_contract_input
.
append
((
consts
.
SE_AFC_CON_FIELD
[
20
],
asp_list
))
afc_contract_input
.
append
((
consts
.
SE_AFC_CON_FIELD
[
22
],
asp_list
))
afc_contract_input
.
append
((
consts
.
SE_AFC_CON_FIELD
[
21
],
gzs_list
))
# 购置税校验
if
isinstance
(
gzs_price
,
str
):
afc_contract_input
.
append
(
(
consts
.
SE_AFC_CON_FIELD
[
21
],
tmp_gzs_list
))
# 非购置税非车辆保险的其他asp
if
have_other_asp
:
afc_contract_input
.
append
((
consts
.
SE_AFC_CON_FIELD
[
24
],
'N'
))
else
:
afc_contract_input
.
pop
(
5
)
afc_contract_input
.
pop
(
5
)
...
...
@@ -1944,9 +1988,16 @@ def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto):
# 主共借人
pre_best_res
=
{}
max_correct_count
=
0
for
ocr_res
in
ocr_res_list
:
verify_list
=
[]
verify_false_idx_list
=
[]
for
tmp_idx
,
ocr_res
in
enumerate
(
ocr_res_list
):
correct_count
=
0
pre_tmp_res_part
=
{}
verify_bool
=
ocr_res
.
get
(
'verify'
,
True
)
verify_list
.
append
(
verify_bool
)
if
not
verify_bool
:
verify_false_idx_list
.
append
(
str
(
tmp_idx
+
1
))
for
idx
,
(
name
,
value
)
in
enumerate
(
pre_field_list
):
ocr_str_or_list
=
ocr_res
.
get
(
compare_logic
[
name
][
0
])
if
isinstance
(
ocr_str_or_list
,
str
)
or
isinstance
(
ocr_str_or_list
,
list
)
\
...
...
@@ -1973,6 +2024,13 @@ def se_bs_compare(license_en, ocr_res_dict, strip_list, is_auto):
max_correct_count
=
correct_count
pre_best_res
=
pre_tmp_res_part
# 真伪
if
not
is_auto
:
name
=
'真伪'
result
=
consts
.
RESULT_Y
if
all
(
verify_list
)
else
consts
.
RESULT_N
reason
=
'第{0}份银行流水疑似造假,需人工核查'
.
format
(
'、'
.
join
(
verify_false_idx_list
))
result_field_list
.
append
((
name
,
empty_str
,
result
,
json
.
dumps
(
verify_list
,
ensure_ascii
=
False
),
empty_str
,
empty_error_type
,
reason
))
# 担保人1
dbr1_best_res
=
{}
if
len
(
dbr1_field_list
)
>
0
:
...
...
@@ -2160,20 +2218,36 @@ def se_compare_license(license_en, ocr_res_dict, field_list):
break
for
idx
,
(
name
,
value
)
in
enumerate
(
field_list
):
if
ocr_field
==
consts
.
MVI_OCR_FIELD
and
name
==
consts
.
SE_NEW_ADD_FIELD
[
9
]:
# 二手车交易凭证 日期
if
ocr_field
==
consts
.
JYPZ_OCR_FIELD
and
name
==
consts
.
SE_GB_USED_FIELD
[
2
]:
date_1
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
JYPZ_DATE_FIELD_1
,
''
)
if
len
(
date_1
)
>
0
:
date_2
=
date_3
=
''
else
:
date_1
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
JYPZ_DATE_FIELD_2
,
''
)
date_2
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
JYPZ_DATE_FIELD_3
,
''
)
date_3
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
JYPZ_DATE_FIELD_4
,
''
)
ocr_str
=
[
date_1
,
date_2
,
date_3
]
# 购车发票 价税合计大小写检验
elif
ocr_field
==
consts
.
MVI_OCR_FIELD
and
name
==
consts
.
SE_NEW_ADD_FIELD
[
9
]:
ocr_str
=
getattr
(
cp
,
consts
.
ZW_METHOD
)(
ocr_res_list
[
res_idx
]
.
get
(
consts
.
LOWER_AMOUNT_FIELD
,
''
),
ocr_res_list
[
res_idx
]
.
get
(
consts
.
UPPER_AMOUNT_FIELD
,
''
),
)
else
:
ocr_str
=
ocr_res_list
[
res_idx
]
.
get
(
compare_logic
[
name
][
0
])
if
not
isinstance
(
ocr_str
,
str
):
if
isinstance
(
ocr_str
,
str
):
result
=
getattr
(
cp
,
compare_logic
[
name
][
1
])(
value
,
ocr_str
,
**
compare_logic
[
name
][
2
])
no_key
=
False
# 二手车交易凭证 日期
elif
ocr_field
==
consts
.
JYPZ_OCR_FIELD
and
name
==
consts
.
SE_GB_USED_FIELD
[
2
]:
result
=
getattr
(
cp
,
compare_logic
[
name
][
1
])(
value
,
ocr_str
,
**
compare_logic
[
name
][
2
])
no_key
=
False
else
:
result
=
consts
.
RESULT_N
ocr_str
=
empty_str
no_key
=
True
else
:
result
=
getattr
(
cp
,
compare_logic
[
name
][
1
])(
value
,
ocr_str
,
**
compare_logic
[
name
][
2
])
no_key
=
False
if
idx
==
0
and
result
==
consts
.
RESULT_N
and
length
>
1
:
break
...
...
@@ -2294,6 +2368,183 @@ def se_compare_license(license_en, ocr_res_dict, field_list):
return
result_field_list
,
no_ocr_result
,
field_img_path_dict
def
se_compare_license_id
(
license_en
,
id_res_list
,
field_list
):
ocr_field
,
compare_logic
,
special_expiry_date
=
consts
.
SE_COMPARE_FIELD
[
license_en
]
is_find
=
False
no_ocr_result
=
True
special_expiry_date_slice
=
False
result_field_list
=
[]
section_img_info
=
dict
()
field_img_path_dict
=
dict
()
# ocr_res_str = ocr_res_dict.get(ocr_field)
for
ocr_res_str
in
id_res_list
:
if
is_find
:
break
if
ocr_res_str
is
not
None
:
no_ocr_result
=
False
ocr_res_list
=
json
.
loads
(
ocr_res_str
)
# 3/4页去除
# if ocr_field == consts.MVC_OCR_FIELD:
# tmp_list = []
# for res in ocr_res_list:
# if compare_logic['vinNo'][0] in res:
# tmp_list.append(res)
# ocr_res_list = tmp_list
length
=
len
(
ocr_res_list
)
# 身份证、居住证 过期期限特殊处理
if
special_expiry_date
:
expiry_dates
=
dict
()
key
=
compare_logic
.
get
(
'idExpiryDate'
)[
0
]
for
date_tmp_idx
,
ocr_res
in
enumerate
(
ocr_res_list
):
if
key
in
ocr_res
:
expiry_dates
[
ocr_res
[
key
]]
=
(
ocr_res
.
get
(
consts
.
IMG_PATH_KEY_2
,
''
),
date_tmp_idx
)
else
:
expiry_dates
=
dict
()
for
res_idx
in
range
(
length
-
1
,
-
1
,
-
1
):
if
is_find
:
break
for
idx
,
(
name
,
value
)
in
enumerate
(
field_list
):
# if ocr_field == consts.MVI_OCR_FIELD and name == consts.SE_NEW_ADD_FIELD[9]:
# ocr_str = getattr(cp, consts.ZW_METHOD)(
# ocr_res_list[res_idx].get(consts.LOWER_AMOUNT_FIELD, ''),
# ocr_res_list[res_idx].get(consts.UPPER_AMOUNT_FIELD, ''),
# )
# else:
ocr_str
=
ocr_res_list
[
res_idx
]
.
get
(
compare_logic
[
name
][
0
])
if
not
isinstance
(
ocr_str
,
str
):
result
=
consts
.
RESULT_N
ocr_str
=
empty_str
no_key
=
True
else
:
result
=
getattr
(
cp
,
compare_logic
[
name
][
1
])(
value
,
ocr_str
,
**
compare_logic
[
name
][
2
])
no_key
=
False
if
idx
==
0
and
result
==
consts
.
RESULT_N
and
length
>
1
:
break
is_find
=
True
section_img_info
[
consts
.
SECTION_IMG_PATH_KEY
]
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
SECTION_IMG_PATH_KEY
,
''
)
section_img_info
[
consts
.
ALL_POSITION_KEY
]
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
ALL_POSITION_KEY
,
{})
if
special_expiry_date
:
section_img_info
[
consts
.
SECTION_IMG_PATH_KEY_2
]
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
SECTION_IMG_PATH_KEY_2
,
''
)
section_img_info
[
consts
.
ALL_POSITION_KEY_2
]
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
ALL_POSITION_KEY_2
,
{})
# 过期期限特殊处理
if
special_expiry_date
and
name
==
'idExpiryDate'
and
result
==
consts
.
RESULT_N
:
if
no_key
:
if
len
(
expiry_dates
)
==
0
:
ocr_str
=
empty_str
result
=
consts
.
RESULT_N
img_path
=
empty_str
else
:
for
expiry_date
,
(
date_img_path
,
date_res_idx
)
in
expiry_dates
.
items
():
expiry_date_res
=
getattr
(
cp
,
compare_logic
[
name
][
1
])(
value
,
expiry_date
,
**
compare_logic
[
name
][
2
])
if
expiry_date_res
==
consts
.
RESULT_N
:
ocr_str
=
expiry_date
img_path
=
date_img_path
special_expiry_date_slice
=
True
section_img_info
[
consts
.
SECTION_IMG_PATH_KEY_2
]
=
ocr_res_list
[
date_res_idx
]
.
get
(
consts
.
SECTION_IMG_PATH_KEY_2
,
''
)
section_img_info
[
consts
.
ALL_POSITION_KEY_2
]
=
ocr_res_list
[
date_res_idx
]
.
get
(
consts
.
ALL_POSITION_KEY_2
,
{})
break
else
:
ocr_str
=
empty_str
result
=
consts
.
RESULT_Y
img_path
=
empty_str
else
:
img_path
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
IMG_PATH_KEY_2
,
''
)
special_expiry_date_slice
=
True
else
:
img_path
=
ocr_res_list
[
res_idx
]
.
get
(
consts
.
IMG_PATH_KEY
,
''
)
if
result
==
consts
.
RESULT_N
else
empty_str
if
isinstance
(
value
,
list
):
value
=
json
.
dumps
(
value
,
ensure_ascii
=
False
)
error_type
=
empty_error_type
if
result
==
consts
.
RESULT_Y
else
ErrorType
.
OCR
.
value
result_field_list
.
append
((
name
,
value
,
result
,
ocr_str
,
img_path
,
error_type
,
compare_logic
[
name
][
3
]))
if
not
is_find
:
for
name
,
value
in
field_list
:
if
isinstance
(
value
,
list
):
value
=
json
.
dumps
(
value
,
ensure_ascii
=
False
)
no_find_str
=
consts
.
DDA_NO_FIND
if
license_en
==
consts
.
DDA_EN
else
'{0}未找到'
.
format
(
license_en
)
result_field_list
.
append
((
name
,
value
,
consts
.
RESULT_N
,
empty_str
,
empty_str
,
ErrorType
.
NF
.
value
,
no_find_str
))
if
is_find
:
if
special_expiry_date_slice
:
special_section_img_path
=
section_img_info
.
get
(
consts
.
SECTION_IMG_PATH_KEY_2
,
''
)
if
os
.
path
.
exists
(
special_section_img_path
):
field
=
'idExpiryDate'
special_info
=
section_img_info
.
get
(
consts
.
ALL_POSITION_KEY_2
,
{})
special_section_position
=
special_info
.
get
(
consts
.
POSITION_KEY
,
{})
special_section_angle
=
special_info
.
get
(
consts
.
ANGLE_KEY
,
0
)
try
:
last_img
=
img_process
(
special_section_img_path
,
special_section_position
,
special_section_angle
)
except
Exception
as
e
:
field_img_path_dict
[
field
]
=
special_section_img_path
else
:
pre
,
suf
=
os
.
path
.
splitext
(
special_section_img_path
)
try
:
res_field
=
compare_logic
[
field
][
0
]
is_valid
,
coord_tuple
=
field_build_coordinates
(
special_info
.
get
(
res_field
,
{}))
if
is_valid
:
save_path
=
'{0}_{1}{2}'
.
format
(
pre
,
field
,
suf
)
field_img
=
last_img
[
coord_tuple
[
0
]:
coord_tuple
[
1
],
coord_tuple
[
2
]:
coord_tuple
[
3
],
:]
cv2
.
imwrite
(
save_path
,
field_img
)
field_img_path_dict
[
field
]
=
save_path
else
:
field_img_path_dict
[
field
]
=
special_section_img_path
except
Exception
as
e
:
field_img_path_dict
[
field
]
=
special_section_img_path
section_img_path
=
section_img_info
.
get
(
consts
.
SECTION_IMG_PATH_KEY
,
''
)
if
os
.
path
.
exists
(
section_img_path
):
failed_field
=
[]
base_img_path
=
empty_str
for
name
,
_
,
result
,
_
,
img_path
,
_
,
_
in
result_field_list
:
if
result
==
consts
.
RESULT_N
:
if
special_expiry_date_slice
and
name
==
'idExpiryDate'
:
continue
failed_field
.
append
(
name
)
if
base_img_path
==
empty_str
:
base_img_path
=
img_path
if
len
(
failed_field
)
>
0
:
info
=
section_img_info
.
get
(
consts
.
ALL_POSITION_KEY
,
{})
section_position
=
info
.
get
(
consts
.
POSITION_KEY
,
{})
section_angle
=
info
.
get
(
consts
.
ANGLE_KEY
,
0
)
try
:
last_img
=
img_process
(
section_img_path
,
section_position
,
section_angle
)
except
Exception
as
e
:
for
field
in
failed_field
:
field_img_path_dict
[
field
]
=
base_img_path
else
:
pre
,
suf
=
os
.
path
.
splitext
(
section_img_path
)
for
field
in
failed_field
:
try
:
res_field
=
compare_logic
[
field
][
0
]
is_valid
,
coord_tuple
=
field_build_coordinates
(
info
.
get
(
res_field
,
{}))
if
is_valid
:
save_path
=
'{0}_{1}{2}'
.
format
(
pre
,
field
,
suf
)
field_img
=
last_img
[
coord_tuple
[
0
]:
coord_tuple
[
1
],
coord_tuple
[
2
]:
coord_tuple
[
3
],
:]
cv2
.
imwrite
(
save_path
,
field_img
)
field_img_path_dict
[
field
]
=
save_path
else
:
field_img_path_dict
[
field
]
=
base_img_path
except
Exception
as
e
:
field_img_path_dict
[
field
]
=
base_img_path
return
result_field_list
,
no_ocr_result
,
field_img_path_dict
def
se_contract_compare
(
license_en
,
ocr_res_dict
,
strip_list
,
is_gsyh
):
ocr_field
,
compare_logic
,
_
=
consts
.
SE_COMPARE_FIELD
[
license_en
]
ocr_res_str
=
ocr_res_dict
.
get
(
ocr_field
)
...
...
@@ -2308,50 +2559,75 @@ def se_contract_compare(license_en, ocr_res_dict, strip_list, is_gsyh):
for
name
,
value
in
strip_list
:
# 购置税校验
if
name
==
consts
.
SE_AFC_CON_FIELD
[
21
]:
if
len
(
value
)
==
3
:
reason
=
[]
gzs_verify
=
value
[
1
]
>=
value
[
2
]
if
gzs_verify
:
if
value
[
0
]
==
consts
.
GZS_STATUS
[
0
]:
reason
.
append
(
consts
.
GZS_REASON_1
)
result
=
consts
.
RESULT_N
else
:
result
=
consts
.
RESULT_Y
else
:
if
value
[
0
]
==
consts
.
GZS_STATUS
[
0
]:
reason
.
append
(
consts
.
GZS_REASON_1
)
result
=
consts
.
RESULT_N
reason
.
append
(
consts
.
GZS_REASON_2
)
else
:
result
=
consts
.
RESULT_N
reason
=
consts
.
GZS_REASON_1
ocr_str
=
empty_str
# if name == consts.SE_AFC_CON_FIELD[21]:
# if len(value) == 3:
# reason = []
# gzs_verify = value[1] >= value[2]
# if gzs_verify:
# if value[0] == consts.GZS_STATUS[0]:
# reason.append(consts.GZS_REASON_1)
# result = consts.RESULT_N
# else:
# result = consts.RESULT_Y
# else:
# if value[0] == consts.GZS_STATUS[0]:
# reason.append(consts.GZS_REASON_1)
# result = consts.RESULT_N
# reason.append(consts.GZS_REASON_2)
# else:
# result = consts.RESULT_N
# reason = consts.GZS_REASON_1
# ocr_str = empty_str
# else:
if
name
==
consts
.
SE_HIL_CON_1_FIELD
[
9
]
or
name
==
consts
.
SE_HIL_CON_1_FIELD
[
15
]
or
\
name
==
consts
.
SE_AFC_CON_FIELD
[
21
]
or
name
==
consts
.
SE_AFC_CON_FIELD
[
24
]:
ocr_str_or_list
=
''
else
:
ocr_str_or_list
=
ocr_res
.
get
(
compare_logic
[
name
][
0
])
if
ocr_str_or_list
is
None
and
license_en
==
consts
.
AFC_CONTRACT_EN
\
and
is_gsyh
is
True
and
name
in
consts
.
CON_BANK_FIELD
:
result
=
consts
.
RESULT_Y
ocr_str
=
empty_str
reason
=
compare_logic
[
name
][
3
]
elif
isinstance
(
ocr_str_or_list
,
str
)
or
isinstance
(
ocr_str_or_list
,
list
):
if
is_gsyh
is
True
and
name
in
consts
.
CON_BANK_FIELD
:
update_args
=
{
'is_gsyh'
:
is_gsyh
}
for
k
,
v
in
compare_logic
[
name
][
2
]
.
items
():
update_args
[
k
]
=
v
else
:
update_args
=
compare_logic
[
name
][
2
]
if
isinstance
(
ocr_str_or_list
,
list
):
ocr_str
=
json
.
dumps
(
ocr_str_or_list
,
ensure_ascii
=
False
)
else
:
ocr_str_or_list
=
ocr_str_or_list
.
strip
()
ocr_str
=
ocr_str_or_list
result
=
getattr
(
cp
,
compare_logic
[
name
][
1
])(
value
,
ocr_str_or_list
,
**
update_args
)
reason
=
compare_logic
[
name
][
3
]
else
:
# 招商银行特殊
# if ocr_str_or_list is None and license_en == consts.AFC_CONTRACT_EN \
# and is_gsyh is True and name in consts.CON_BANK_FIELD:
# result = consts.RESULT_Y
# ocr_str = empty_str
# reason = compare_logic[name][3]
# 见证人日期
if
name
==
consts
.
SE_AFC_CON_FIELD
[
19
]:
if
not
isinstance
(
ocr_str_or_list
,
str
)
or
len
(
ocr_str_or_list
)
==
0
:
result
=
consts
.
RESULT_N
ocr_str
=
empty_str
reason
=
compare_logic
[
name
][
3
]
else
:
is_find_date
=
False
all_date_list
=
[
ocr_str_or_list
]
for
date_name
in
consts
.
AFC_HT_DATE_FIELDS
:
all_date_list
.
append
(
ocr_res
.
get
(
compare_logic
[
date_name
][
0
],
''
))
if
not
is_find_date
and
ocr_str_or_list
==
ocr_res
.
get
(
compare_logic
[
date_name
][
0
],
''
):
is_find_date
=
True
result
=
consts
.
RESULT_Y
if
is_find_date
else
consts
.
RESULT_N
ocr_str
=
json
.
dumps
(
all_date_list
,
ensure_ascii
=
False
)
reason
=
compare_logic
[
name
][
3
]
elif
isinstance
(
ocr_str_or_list
,
str
)
or
isinstance
(
ocr_str_or_list
,
list
):
# if is_gsyh is True and name in consts.CON_BANK_FIELD:
# update_args = {'is_gsyh': is_gsyh}
# for k, v in compare_logic[name][2].items():
# update_args[k] = v
# else:
# update_args = compare_logic[name][2]
if
isinstance
(
ocr_str_or_list
,
list
):
# no-asp 合同编号-每页(no-asp)
if
name
==
consts
.
SE_AFC_CON_FIELD
[
23
]:
ocr_str_or_list
.
pop
()
ocr_str
=
json
.
dumps
(
ocr_str_or_list
,
ensure_ascii
=
False
)
else
:
ocr_str_or_list
=
ocr_str_or_list
.
strip
()
ocr_str
=
ocr_str_or_list
result
=
getattr
(
cp
,
compare_logic
[
name
][
1
])(
value
,
ocr_str_or_list
,
**
compare_logic
[
name
][
2
])
reason
=
compare_logic
[
name
][
3
]
else
:
result
=
consts
.
RESULT_N
ocr_str
=
empty_str
reason
=
compare_logic
[
name
][
3
]
# img_path = empty_str
if
name
not
in
compare_logic
:
...
...
@@ -2513,7 +2789,7 @@ def se_mvc34_compare(license_en, ocr_res_dict, field_list):
return
result_field_list
,
field_img_path_dict
def
se_compare_process
(
compare_info
,
ocr_res_dict
,
is_gsyh
,
is_auto
):
def
se_compare_process
(
compare_info
,
ocr_res_dict
,
is_gsyh
,
is_auto
,
id_res_list
):
# individualCusInfo
# corporateCusInfo
# vehicleInfo
...
...
@@ -2546,7 +2822,13 @@ def se_compare_process(compare_info, ocr_res_dict, is_gsyh, is_auto):
else
:
strip_list
.
append
((
a
,
b
))
failure_field
=
[]
result_field_list
,
no_ocr_result
,
field_img_path_dict
=
se_compare_license
(
license_en
,
ocr_res_dict
,
strip_list
)
# 身份证先SE正反面,后CA正反面
if
license_en
==
consts
.
ID_EN
:
result_field_list
,
no_ocr_result
,
field_img_path_dict
=
se_compare_license_id
(
license_en
,
id_res_list
,
strip_list
)
else
:
result_field_list
,
no_ocr_result
,
field_img_path_dict
=
se_compare_license
(
license_en
,
ocr_res_dict
,
strip_list
)
for
name
,
value
,
result
,
ocr_str
,
img_path
,
error_type
,
cn_reason
in
result_field_list
:
if
license_en
not
in
consts
.
SKIP_CARD
or
not
no_ocr_result
:
total_fields
+=
1
...
...
@@ -2665,13 +2947,15 @@ def se_result_detect(ocr_res_dict):
return
detect_list
def
se_compare_auto
(
application_id
,
application_entity
,
ocr_res_id
,
last_obj
,
ocr_res_dict
,
auto_obj
):
def
se_compare_auto
(
application_id
,
application_entity
,
ocr_res_id
,
last_obj
,
ocr_res_dict
,
auto_obj
,
ignore_bank
,
id_res_list
):
try
:
# 比对逻辑
# detect_list = se_result_detect(ocr_res_dict)
compare_info
,
aa_type
,
is_gsyh
=
get_se_cms_compare_info_auto
(
last_obj
,
application_entity
)
compare_result
,
total_fields
,
failed_count
,
successful_at_this_level
,
failure_reason_str
,
cn_failure_reason_str
,
bs_failure_reason_str
,
_
=
se_compare_process
(
compare_info
,
ocr_res_dict
,
is_gsyh
,
True
)
last_obj
,
application_entity
,
ignore_bank
=
ignore_bank
)
compare_result
,
total_fields
,
failed_count
,
successful_at_this_level
,
failure_reason_str
,
\
cn_failure_reason_str
,
bs_failure_reason_str
,
_
=
se_compare_process
(
compare_info
,
ocr_res_dict
,
is_gsyh
,
True
,
id_res_list
)
compare_log
.
info
(
'{0} [Auto SE] [compare success] [entity={1}] [id={2}] [ocr_res_id={3}] [result={4}]'
.
format
(
log_base
,
application_entity
,
application_id
,
ocr_res_id
,
compare_result
))
except
Exception
as
e
:
...
...
@@ -2709,14 +2993,17 @@ def se_compare_auto(application_id, application_entity, ocr_res_id, last_obj, oc
return
successful_at_this_level
def
se_compare
(
application_id
,
application_entity
,
ocr_res_id
,
last_obj
,
ocr_res_dict
,
is_cms
,
auto_result
):
def
se_compare
(
application_id
,
application_entity
,
ocr_res_id
,
last_obj
,
ocr_res_dict
,
is_cms
,
auto_result
,
ignore_bank
,
id_res_list
):
try
:
# 比对逻辑
start_time
=
datetime
.
now
()
detect_list
=
se_result_detect
(
ocr_res_dict
)
compare_info
,
application_version
,
is_gsyh
=
get_se_cms_compare_info
(
last_obj
,
application_entity
,
detect_list
)
compare_result
,
total_fields
,
failed_count
,
successful_at_this_level
,
failure_reason_str
,
cn_failure_reason_str
,
bs_failure_reason_str
,
rpa_failure_reason
=
se_compare_process
(
compare_info
,
ocr_res_dict
,
is_gsyh
,
False
)
last_obj
,
application_entity
,
detect_list
,
ignore_bank
=
ignore_bank
)
compare_result
,
total_fields
,
failed_count
,
successful_at_this_level
,
failure_reason_str
,
\
cn_failure_reason_str
,
bs_failure_reason_str
,
rpa_failure_reason
=
se_compare_process
(
compare_info
,
ocr_res_dict
,
is_gsyh
,
False
,
id_res_list
)
compare_log
.
info
(
'{0} [SE] [compare success] [entity={1}] [id={2}] [ocr_res_id={3}] [result={4}]'
.
format
(
log_base
,
application_entity
,
application_id
,
ocr_res_id
,
compare_result
))
except
Exception
as
e
:
...
...
@@ -2858,7 +3145,12 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True
if
is_ca
:
ca_compare
(
application_id
,
application_entity
,
ocr_res_id
,
last_obj
,
ocr_res_dict
)
else
:
id_res_list
=
[]
for
field_name
in
consts
.
CA_ADD_COMPARE_FIELDS
:
if
field_name
==
consts
.
IC_OCR_FIELD
:
id_res_list
.
append
(
ocr_res_dict
.
get
(
field_name
))
id_res_list
.
append
(
ca_ocr_res_dict
.
get
(
field_name
)
if
isinstance
(
ca_ocr_res_dict
,
dict
)
else
None
)
if
isinstance
(
ca_ocr_res_dict
,
dict
)
and
isinstance
(
ca_ocr_res_dict
.
get
(
field_name
),
str
):
tmp_ca_result
=
json
.
loads
(
ca_ocr_res_dict
.
get
(
field_name
))
if
isinstance
(
ocr_res_dict
.
get
(
field_name
),
str
):
...
...
@@ -2868,12 +3160,14 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True
# auto settlement
auto_class
=
HILAutoSettlement
if
application_entity
==
consts
.
HIL_PREFIX
else
AFCAutoSettlement
auto_obj
=
auto_class
.
objects
.
filter
(
application_id
=
application_id
,
on_off
=
True
)
.
first
()
bank_class
=
HILbankVerification
if
application_entity
==
consts
.
HIL_PREFIX
else
AFCbankVerification
ignore_bank
=
bank_class
.
objects
.
filter
(
application_id
=
application_id
,
on_off
=
True
)
.
exists
()
if
auto_obj
is
not
None
:
auto_result
=
se_compare_auto
(
application_id
,
application_entity
,
ocr_res_id
,
last_obj
,
ocr_res_dict
,
auto_obj
)
auto_result
=
se_compare_auto
(
application_id
,
application_entity
,
ocr_res_id
,
last_obj
,
ocr_res_dict
,
auto_obj
,
ignore_bank
,
id_res_list
)
else
:
auto_result
=
None
full_result
=
se_compare
(
application_id
,
application_entity
,
ocr_res_id
,
last_obj
,
ocr_res_dict
,
is_cms
,
auto_result
)
full_result
=
se_compare
(
application_id
,
application_entity
,
ocr_res_id
,
last_obj
,
ocr_res_dict
,
is_cms
,
auto_result
,
ignore_bank
,
id_res_list
)
if
auto_obj
is
not
None
:
try
:
...
...
src/common/tools/comparison.py
View file @
f80b830
...
...
@@ -173,6 +173,11 @@ class Comparison:
return
self
.
RESULT_Y
return
self
.
RESULT_N
else
:
# if kwargs.get('pop_last', False):
# for item in ocr_str_or_list[:-1]:
# if item != input_str_or_list:
# return self.RESULT_N
# else:
for
item
in
ocr_str_or_list
:
if
item
!=
input_str_or_list
:
return
self
.
RESULT_N
...
...
@@ -582,6 +587,27 @@ class Comparison:
else
:
return
self
.
RESULT_N
def
se_self_compare_gzs
(
self
,
input_list
,
ocr_str
,
**
kwargs
):
if
isinstance
(
input_list
,
list
)
and
len
(
input_list
)
==
2
:
try
:
if
isinstance
(
input_list
[
0
],
float
)
and
isinstance
(
input_list
[
1
],
float
)
\
and
input_list
[
0
]
>=
input_list
[
1
]:
return
self
.
RESULT_Y
except
Exception
as
e
:
return
self
.
RESULT_N
return
self
.
RESULT_N
def
se_self_compare_other_asp
(
self
,
input_str
,
ocr_str
,
**
kwargs
):
return
self
.
RESULT_N
def
se_jypz_date_compare
(
self
,
input_str
,
ocr_date_list
,
**
kwargs
):
ocr_date_set
=
set
(
ocr_date_list
)
if
len
(
ocr_date_set
)
>
1
:
return
self
.
RESULT_N
if
not
any
(
ocr_date_set
):
return
self
.
RESULT_N
return
self
.
se_date_compare_2
(
input_str
,
ocr_date_set
.
pop
(),
three_month
=
True
)
cp
=
Comparison
()
...
...
src/common/tools/mssql_script18.py
0 → 100644
View file @
f80b830
import
pyodbc
hil_sql
=
"""
create table hil_bank_verification
(
id bigint identity primary key,
application_id nvarchar(64) not null,
on_off bit default 1 not null,
update_time datetime not null,
create_time datetime not null
);
create index hil_bank_verification_application_id_index
on hil_bank_verification (application_id);
"""
afc_sql
=
"""
create table afc_bank_verification
(
id bigint identity primary key,
application_id nvarchar(64) not null,
on_off bit default 1 not null,
update_time datetime not null,
create_time datetime not null
);
create index afc_bank_verification_application_id_index
on afc_bank_verification (application_id);
"""
hil_cnxn
=
pyodbc
.
connect
(
'DRIVER={ODBC Driver 17 for SQL Server};'
,
autocommit
=
True
)
hil_cursor
=
hil_cnxn
.
cursor
()
hil_cursor
.
execute
(
hil_sql
)
hil_cursor
.
close
()
hil_cnxn
.
close
()
afc_cnxn
=
pyodbc
.
connect
(
'DRIVER={ODBC Driver 17 for SQL Server};'
,
autocommit
=
True
)
afc_cursor
=
afc_cnxn
.
cursor
()
afc_cursor
.
execute
(
afc_sql
)
afc_cursor
.
close
()
afc_cnxn
.
close
()
src/common/tools/pdf_to_img.py
View file @
f80b830
import
os
import
re
import
json
import
cv2
import
shutil
...
...
@@ -48,8 +49,9 @@ class PDFBuild:
class
PDFHandler
:
def
__init__
(
self
,
path
,
img_dir_path
,
document_name
=
None
):
def
__init__
(
self
,
path
,
img_dir_path
,
document_name
=
None
,
pwd_list
=
[]
):
self
.
path
=
path
self
.
pwd_list
=
self
.
get_pwd_list
(
document_name
,
pwd_list
)
self
.
img_dir_path
=
img_dir_path
self
.
img_path_list
=
[]
self
.
img_count
=
0
...
...
@@ -75,6 +77,12 @@ class PDFHandler:
self
.
page_count
=
None
self
.
metadata
=
None
@staticmethod
def
get_pwd_list
(
doc_name
,
pwd_list
):
pwd_list_from_doc_name
=
re
.
findall
(
r'\d{6}'
,
doc_name
)
pwd_list_from_doc_name
.
extend
(
pwd_list
)
return
pwd_list_from_doc_name
def
get_suffix
(
self
,
file_name
):
if
file_name
is
None
:
return
None
...
...
@@ -370,6 +378,12 @@ class PDFHandler:
self
.
img_path_list
.
append
(
img_save_path
)
else
:
with
fitz
.
Document
(
self
.
path
)
as
pdf
:
# 解密
for
pwd
in
self
.
pwd_list
:
if
not
pdf
.
isEncrypted
:
break
pdf
.
authenticate
(
pwd
)
self
.
metadata
=
pdf
.
metadata
self
.
page_count
=
pdf
.
pageCount
if
isinstance
(
max_img_count
,
int
)
and
pdf
.
pageCount
>=
max_img_count
:
...
...
Write
Preview
Styling with
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment