e-contract part 1
Showing
15 changed files
with
251 additions
and
9 deletions
... | @@ -1773,3 +1773,21 @@ APPLICANT_TYPE_MAP = { | ... | @@ -1773,3 +1773,21 @@ APPLICANT_TYPE_MAP = { |
1773 | } | 1773 | } |
1774 | 1774 | ||
1775 | APPLICANT_TYPE_ORDER = ['Borrower', 'Co-Borrower', 'Guarantor', 'Mortgager'] | 1775 | APPLICANT_TYPE_ORDER = ['Borrower', 'Co-Borrower', 'Guarantor', 'Mortgager'] |
1776 | |||
1777 | FILE_NAME_PREFIX_MAP = { | ||
1778 | AFC_PREFIX: [ | ||
1779 | ((CONTRACT_CLASSIFY, 0), '{0}_电子签署-汽车抵押贷款合同'), | ||
1780 | ((HMH_CLASSIFY, 0), '{0}_电子签署-抵押登记豁免函'), | ||
1781 | ], | ||
1782 | HIL_PREFIX: [ | ||
1783 | ((HIL_CONTRACT_1_CLASSIFY, HIL_CONTRACT_3_CLASSIFY), '{0}_电子签署-售后回租合同'), | ||
1784 | ((HIL_CONTRACT_2_CLASSIFY, 0), '{0}_电子签署-汽车租赁抵押合同'), | ||
1785 | ((HMH_CLASSIFY, 0), '{0}_电子签署-抵押登记豁免函'), | ||
1786 | ] | ||
1787 | } | ||
1788 | |||
1789 | HIL_CONTRACT_TYPE_MAP = { | ||
1790 | str(HIL_CONTRACT_1_CLASSIFY): 0, | ||
1791 | str(HIL_CONTRACT_2_CLASSIFY): 2, | ||
1792 | str(HIL_CONTRACT_3_CLASSIFY): 1, | ||
1793 | } | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -789,3 +789,24 @@ class HILCACompareResultRecord(models.Model): | ... | @@ -789,3 +789,24 @@ class HILCACompareResultRecord(models.Model): |
789 | db_table = 'hil_ca_compare_result_record' | 789 | db_table = 'hil_ca_compare_result_record' |
790 | 790 | ||
791 | 791 | ||
792 | class HILContract(models.Model): | ||
793 | id = models.AutoField(primary_key=True, verbose_name="id") # 主键 | ||
794 | application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引 | ||
795 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') | ||
796 | |||
797 | class Meta: | ||
798 | managed = False | ||
799 | db_table = 'hil_contract' | ||
800 | |||
801 | |||
802 | class AFCContract(models.Model): | ||
803 | id = models.AutoField(primary_key=True, verbose_name="id") # 主键 | ||
804 | application_id = models.CharField(max_length=64, verbose_name="申请id") # 索引 | ||
805 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') | ||
806 | |||
807 | class Meta: | ||
808 | managed = False | ||
809 | db_table = 'afc_contract' | ||
810 | situ_db_label = 'afc' | ||
811 | |||
812 | ... | ... |
1 | import os | ||
1 | import base64 | 2 | import base64 |
2 | import requests | 3 | import requests |
3 | from common.redis_cache import redis_handler as rh | 4 | from common.redis_cache import redis_handler as rh |
... | @@ -44,7 +45,6 @@ class ECM: | ... | @@ -44,7 +45,6 @@ class ECM: |
44 | "b_coborrower_id", "b_coborrower_name", "b_guarantor_id", "b_guarantor_name", | 45 | "b_coborrower_id", "b_coborrower_name", "b_guarantor_id", "b_guarantor_name", |
45 | "b_frontend_partner", "b_dealer_code", "b_dealer_name", "b_input_date", "b_comment", | 46 | "b_frontend_partner", "b_dealer_code", "b_dealer_name", "b_input_date", "b_comment", |
46 | "b_contract_no", "b_location"] | 47 | "b_contract_no", "b_location"] |
47 | self.contract_prefix = '电子' | ||
48 | 48 | ||
49 | def update_oauth_token(self): | 49 | def update_oauth_token(self): |
50 | response = requests.post(self.oauth_url, headers=self.oauth_headers, data=self.oauth_payload, verify=False) | 50 | response = requests.post(self.oauth_url, headers=self.oauth_headers, data=self.oauth_payload, verify=False) |
... | @@ -69,9 +69,9 @@ class ECM: | ... | @@ -69,9 +69,9 @@ class ECM: |
69 | def get_headers(self): | 69 | def get_headers(self): |
70 | return {'Authorization': '{0} {1}'.format(self.token_type, self.get_oauth_token())} | 70 | return {'Authorization': '{0} {1}'.format(self.token_type, self.get_oauth_token())} |
71 | 71 | ||
72 | def search(self, application_id, business_type): | 72 | def search(self, application_id, business_type, prefix): |
73 | sql = "select * from {0} where b_application_no='{1}' and object_name like '{2}%'".format( | 73 | sql = "select * from {0} where b_application_no='{1}' and object_name like '{2}%'".format( |
74 | self.settlement_type, application_id, self.contract_prefix) | 74 | self.settlement_type, application_id, prefix) |
75 | search_args = { | 75 | search_args = { |
76 | "userName": self.username, | 76 | "userName": self.username, |
77 | "password": self.pwd, | 77 | "password": self.pwd, |
... | @@ -96,7 +96,6 @@ class ECM: | ... | @@ -96,7 +96,6 @@ class ECM: |
96 | result.append((object_name, object_id)) | 96 | result.append((object_name, object_id)) |
97 | return result | 97 | return result |
98 | 98 | ||
99 | |||
100 | def download(self, save_path, object_id, document_scheme, business_type): | 99 | def download(self, save_path, object_id, document_scheme, business_type): |
101 | doc_type, _, _ = self.doc_type_map.get(document_scheme) | 100 | doc_type, _, _ = self.doc_type_map.get(document_scheme) |
102 | download_json = { | 101 | download_json = { | ... | ... |
... | @@ -36,12 +36,14 @@ from .models import ( | ... | @@ -36,12 +36,14 @@ from .models import ( |
36 | AFCSECompareResultRecord, | 36 | AFCSECompareResultRecord, |
37 | HILCACompareResultRecord, | 37 | HILCACompareResultRecord, |
38 | HILSECompareResultRecord, | 38 | HILSECompareResultRecord, |
39 | HILContract, | ||
40 | AFCContract, | ||
39 | ) | 41 | ) |
40 | from .named_enum import ErrorType | 42 | from .named_enum import ErrorType |
41 | from .mixins import DocHandler | 43 | from .mixins import DocHandler |
42 | from . import consts | 44 | from . import consts |
43 | from apps.account.authentication import OAuth2AuthenticationWithUser | 45 | from apps.account.authentication import OAuth2AuthenticationWithUser |
44 | from celery_compare.tasks import compare | 46 | from celery_compare.tasks import compare, forwarding_station |
45 | 47 | ||
46 | 48 | ||
47 | class CustomDate(fields.Date): | 49 | class CustomDate(fields.Date): |
... | @@ -1164,5 +1166,11 @@ class SEContractView(GenericView): | ... | @@ -1164,5 +1166,11 @@ class SEContractView(GenericView): |
1164 | # pos上传e-contract信息接口 SE | 1166 | # pos上传e-contract信息接口 SE |
1165 | @use_args(se_contract_args, location='data') | 1167 | @use_args(se_contract_args, location='data') |
1166 | def post(self, request, args): | 1168 | def post(self, request, args): |
1167 | self.running_log.info('e-contract in') | 1169 | contract_info = args.get('content', {}) |
1170 | application_id = contract_info.get('applicationId', '') | ||
1171 | entity = contract_info.get('applicationEntity', '') | ||
1172 | table_class = HILContract if entity == consts.HIL_PREFIX else AFCContract | ||
1173 | table_class.objects.create(application_id=application_id) | ||
1174 | forwarding_station.apply_async((application_id, entity), queue='queue_compare', countdown=conf.DELAY_SECONDS) | ||
1175 | self.running_log.info('[e-contract] [application_id={0}] [entity={1}]'.format(application_id, entity)) | ||
1168 | return response.ok() | 1176 | return response.ok() | ... | ... |
... | @@ -27,10 +27,13 @@ from apps.doc.models import ( | ... | @@ -27,10 +27,13 @@ from apps.doc.models import ( |
27 | AFCCACompareResult, | 27 | AFCCACompareResult, |
28 | HILSECompareResult, | 28 | HILSECompareResult, |
29 | HILCACompareResult, | 29 | HILCACompareResult, |
30 | AFCDoc, | ||
31 | HILDoc | ||
30 | ) | 32 | ) |
31 | from apps.doc import consts | 33 | from apps.doc import consts |
32 | from apps.doc.ocr.gcap import gcap | 34 | from apps.doc.ocr.gcap import gcap |
33 | from apps.doc.ocr.cms import cms | 35 | from apps.doc.ocr.cms import cms |
36 | from apps.doc.ocr.ecm import ECM, rh | ||
34 | from apps.doc.exceptions import GCAPException | 37 | from apps.doc.exceptions import GCAPException |
35 | from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType | 38 | from apps.doc.named_enum import RequestTeam, RequestTrigger, ProcessName, ErrorType |
36 | from common.tools.comparison import cp | 39 | from common.tools.comparison import cp |
... | @@ -38,9 +41,11 @@ from common.tools.des import decode_des | ... | @@ -38,9 +41,11 @@ from common.tools.des import decode_des |
38 | 41 | ||
39 | compare_log = logging.getLogger('compare') | 42 | compare_log = logging.getLogger('compare') |
40 | log_base = '[Compare]' | 43 | log_base = '[Compare]' |
44 | e_log_base = '[e-contract]' | ||
41 | empty_str = '' | 45 | empty_str = '' |
42 | empty_error_type = 1000 | 46 | empty_error_type = 1000 |
43 | des_key = conf.CMS_DES_KEY | 47 | des_key = conf.CMS_DES_KEY |
48 | ecm = ECM() | ||
44 | 49 | ||
45 | 50 | ||
46 | def rotate_bound(image, angle): | 51 | def rotate_bound(image, angle): |
... | @@ -1867,4 +1872,32 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True | ... | @@ -1867,4 +1872,32 @@ def compare(application_id, application_entity, uniq_seq, ocr_res_id, is_ca=True |
1867 | se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res_dict, is_cms) | 1872 | se_compare(application_id, application_entity, ocr_res_id, last_obj, ocr_res_dict, is_cms) |
1868 | 1873 | ||
1869 | 1874 | ||
1870 | 1875 | @app.task | |
1876 | def forwarding_station(application_id, entity): | ||
1877 | compare_log.info('{0} [forward start] [application_id={1}] [entity={2}]'.format(e_log_base, application_id, entity)) | ||
1878 | doc_class = HILDoc if entity in consts.HIL_SET else AFCDoc | ||
1879 | entity_prefix = consts.HIL_PREFIX if entity in consts.HIL_SET else consts.AFC_PREFIX | ||
1880 | for (classify_1, classify_2), prefix in consts.FILE_NAME_PREFIX_MAP.get(entity): | ||
1881 | try: | ||
1882 | file_list = ecm.search(application_id, entity, prefix.format(application_id)) # TODO 获取最新文件 | ||
1883 | except Exception as e: | ||
1884 | compare_log.error('{0} [search failed] [application_id={1}] [entity={2}] [error={3}]'.format( | ||
1885 | e_log_base, application_id, entity, traceback.format_exc())) | ||
1886 | else: | ||
1887 | compare_log.info('{0} [search end] [application_id={1}] [entity={2}] [file_list={3}]'.format( | ||
1888 | e_log_base, application_id, entity, file_list)) | ||
1889 | for object_name, object_id in file_list: | ||
1890 | doc = doc_class.objects.create( | ||
1891 | metadata_version_id=object_id, | ||
1892 | application_id=application_id, | ||
1893 | document_name=object_name, | ||
1894 | document_scheme='SETTLEMENT', | ||
1895 | data_source='POS', | ||
1896 | upload_finish_time=datetime.now(), | ||
1897 | ) | ||
1898 | task = consts.SPLIT_STR.join([entity_prefix, str(doc.id), str(classify_1), str(classify_2)]) | ||
1899 | enqueue_res = rh.enqueue([task], False) | ||
1900 | compare_log.info('{0} [upload success] [res={1}] [application_id={2}] [entity={3}] [object_name={4}] ' | ||
1901 | '[object_id={5}] [doc_id={6}]'.format(e_log_base, enqueue_res, application_id, entity, | ||
1902 | object_name, object_id, doc.id)) | ||
1903 | compare_log.info('{0} [forward end] [application_id={1}] [entity={2}]'.format(e_log_base, application_id, entity)) | ... | ... |
1 | # -*- coding: utf-8 -*- | ||
2 | # @Author : lk | ||
3 | # @Email : 9428.al@gmail.com | ||
4 | # @Created Date : 2021-06-29 17:43:46 | ||
5 | # @Last Modified : 2021-09-07 14:11:25 | ||
6 | # @Description : | ||
7 | |||
8 | from .get_char import Finder | ||
9 | |||
10 | |||
11 | def predict(pdf_info): | ||
12 | # 输入是整个 PDF 中的信息 | ||
13 | f = Finder(pdf_info) | ||
14 | results = f.get_info() | ||
15 | |||
16 | return results | ||
17 | |||
18 |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
1 | # -*- coding: utf-8 -*- | ||
2 | # @Author : lk | ||
3 | # @Email : 9428.al@gmail.com | ||
4 | # @Created Date : 2021-06-29 17:43:46 | ||
5 | # @Last Modified : 2021-11-03 16:07:36 | ||
6 | # @Description : | ||
7 | |||
8 | from .get_char import Finder | ||
9 | |||
10 | |||
11 | def predict(pdf_info, file_cls): | ||
12 | """Summary | ||
13 | |||
14 | Args: | ||
15 | pdf_info (TYPE): Description | ||
16 | file_cls (TYPE): file_cls = 0: 售后回租合同; file_cls = 1: 车辆处置协议; file_cls = 2: 车辆租赁抵押合同 | ||
17 | |||
18 | Returns: | ||
19 | TYPE: Description | ||
20 | """ | ||
21 | |||
22 | # 0: 售后回租合同 | ||
23 | pdf_info_0 = [] | ||
24 | for pno in pdf_info: | ||
25 | for block in pdf_info[f'{pno}']['blocks']: | ||
26 | if block['type'] != 0: | ||
27 | continue | ||
28 | for line in block['lines']: | ||
29 | for span in line['spans']: | ||
30 | bbox, text = span['bbox'], span['text'] | ||
31 | if '售后回租合同_' in text: | ||
32 | pdf_info_0.append(pdf_info[pno]) | ||
33 | |||
34 | # 1: 车辆处置协议 | ||
35 | pdf_info_1 = [] | ||
36 | for pno in pdf_info: | ||
37 | for block in pdf_info[f'{pno}']['blocks']: | ||
38 | if block['type'] != 0: | ||
39 | continue | ||
40 | for line in block['lines']: | ||
41 | for span in line['spans']: | ||
42 | bbox, text = span['bbox'], span['text'] | ||
43 | if '售后回租合同附件一' in text: | ||
44 | pdf_info_1.append(pdf_info[pno]) | ||
45 | |||
46 | # 2: 车辆租赁抵押合同 | ||
47 | pdf_info_2 = [] | ||
48 | for pno in pdf_info: | ||
49 | for block in pdf_info[f'{pno}']['blocks']: | ||
50 | if block['type'] != 0: | ||
51 | continue | ||
52 | for line in block['lines']: | ||
53 | for span in line['spans']: | ||
54 | bbox, text = span['bbox'], span['text'] | ||
55 | if '车辆租赁抵押合同_' in text: | ||
56 | pdf_info_2.append(pdf_info[pno]) | ||
57 | |||
58 | is_clczxy = False | ||
59 | # 如果 pdf_info_1 == 4 页,则说明此时输入包含了车辆处置协议 | ||
60 | if len(pdf_info_1) == 4 and file_cls == 1 and len(pdf_info_0) != 0: | ||
61 | is_clczxy = True | ||
62 | pdf_info = dict() | ||
63 | for pno, page_info in enumerate(pdf_info_1): | ||
64 | pdf_info[str(pno)] = page_info | ||
65 | |||
66 | f = Finder(pdf_info) | ||
67 | if file_cls == 0: | ||
68 | results = f.get_info() | ||
69 | if file_cls == 1: | ||
70 | # 提取信息 ———— 车辆处置协议 | ||
71 | results = f.get_info_1() | ||
72 | if file_cls == 2: | ||
73 | # 提取信息 ———— 车辆租赁抵押合同 | ||
74 | results = f.get_info_2() | ||
75 | |||
76 | if is_clczxy == True: | ||
77 | for key in results: | ||
78 | if results[key]['page'] is not None: | ||
79 | results[key]['page'] = str(int(results[key]['page'])+6) | ||
80 | |||
81 | for key in results: | ||
82 | if results[key]['page'] is not None: | ||
83 | results[key]['page'] = 'page_' + str(int(results[key]['page'])+1) | ||
84 | return results |
src/common/tools/mssql_script10.py
0 → 100644
1 | import pyodbc | ||
2 | |||
3 | afc_sql = """ | ||
4 | create table afc_contract | ||
5 | ( | ||
6 | id bigint identity primary key, | ||
7 | application_id nvarchar(64) not null, | ||
8 | create_time datetime not null | ||
9 | ); | ||
10 | |||
11 | create index afc_contract_application_id_index | ||
12 | on afc_contract (application_id); | ||
13 | """ | ||
14 | |||
15 | hil_sql = """ | ||
16 | create table hil_contract | ||
17 | ( | ||
18 | id bigint identity primary key, | ||
19 | application_id nvarchar(64) not null, | ||
20 | create_time datetime not null | ||
21 | ); | ||
22 | |||
23 | create index hil_contract_application_id_index | ||
24 | on hil_contract (application_id); | ||
25 | """ | ||
26 | |||
27 | hil_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True) | ||
28 | |||
29 | hil_cursor = hil_cnxn.cursor() | ||
30 | hil_cursor.execute(hil_sql) | ||
31 | |||
32 | hil_cursor.close() | ||
33 | hil_cnxn.close() | ||
34 | |||
35 | afc_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};', autocommit=True) | ||
36 | |||
37 | afc_cursor = afc_cnxn.cursor() | ||
38 | afc_cursor.execute(afc_sql) | ||
39 | |||
40 | afc_cursor.close() | ||
41 | afc_cnxn.close() |
1 | import os | 1 | import os |
2 | import json | ||
2 | import cv2 | 3 | import cv2 |
3 | import shutil | 4 | import shutil |
4 | import fitz | 5 | import fitz |
... | @@ -35,6 +36,8 @@ class PDFHandler: | ... | @@ -35,6 +36,8 @@ class PDFHandler: |
35 | self.suffix = self.get_suffix(document_name) | 36 | self.suffix = self.get_suffix(document_name) |
36 | self.is_ebank = False | 37 | self.is_ebank = False |
37 | self.page_text_list = [] | 38 | self.page_text_list = [] |
39 | self.pdf_info = {} | ||
40 | self.img_path_pno_list = [] | ||
38 | 41 | ||
39 | def get_suffix(self, file_name): | 42 | def get_suffix(self, file_name): |
40 | if file_name is None: | 43 | if file_name is None: |
... | @@ -296,6 +299,17 @@ class PDFHandler: | ... | @@ -296,6 +299,17 @@ class PDFHandler: |
296 | self.is_ebank = True | 299 | self.is_ebank = True |
297 | self.page_text_list = page_text_list | 300 | self.page_text_list = page_text_list |
298 | 301 | ||
302 | def e_contract_process(self): | ||
303 | with fitz.Document(self.path) as pdf: | ||
304 | for pno in range(pdf.pageCount): | ||
305 | page = pdf.loadPage(pno) | ||
306 | self.pdf_info[str(pno)] = json.loads(page.getText('json')) | ||
307 | |||
308 | pix = page.getPixmap() | ||
309 | img_save_path = self.get_img_save_path(page.number) | ||
310 | self.img_path_pno_list.append((img_save_path, 'page_{0}'.format(str(pno+1)))) | ||
311 | pix.writePNG(img_save_path) | ||
312 | |||
299 | def extract_image(self, max_img_count=None): | 313 | def extract_image(self, max_img_count=None): |
300 | self.img_path_list = [] | 314 | self.img_path_list = [] |
301 | self.xref_set = set() | 315 | self.xref_set = set() | ... | ... |
... | @@ -12,4 +12,6 @@ EDMS_DOWNLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/Dow | ... | @@ -12,4 +12,6 @@ EDMS_DOWNLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/Dow |
12 | EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/UploadHandler.ashx | 12 | EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/UploadHandler.ashx |
13 | DEALER_CODE = ocr_situ_group | 13 | DEALER_CODE = ocr_situ_group |
14 | 14 | ||
15 | BASE_URL = https://staging-bmw-ocr.situdata.com | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
15 | BASE_URL = https://staging-bmw-ocr.situdata.com | ||
16 | |||
17 | DELAY_SECONDS = 60 | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -12,4 +12,6 @@ EDMS_DOWNLOAD_URL = http://sccn0637.bmwgroup.net/FH/FileHold/DocumentRepository/ | ... | @@ -12,4 +12,6 @@ EDMS_DOWNLOAD_URL = http://sccn0637.bmwgroup.net/FH/FileHold/DocumentRepository/ |
12 | EDMS_UPLOAD_URL = http://sccn0637.bmwgroup.net/FH/FileHold/DocumentRepository/UploadHandler.ashx | 12 | EDMS_UPLOAD_URL = http://sccn0637.bmwgroup.net/FH/FileHold/DocumentRepository/UploadHandler.ashx |
13 | DEALER_CODE = ocr_situ_group | 13 | DEALER_CODE = ocr_situ_group |
14 | 14 | ||
15 | BASE_URL = https://li19dkocruat01vm.bmwgroup.net | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
15 | BASE_URL = https://li19dkocruat01vm.bmwgroup.net | ||
16 | |||
17 | DELAY_SECONDS = 60 | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment