e-contract part 1
Showing
15 changed files
with
249 additions
and
7 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() | ... | ... |
| ... | @@ -13,3 +13,5 @@ EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/Uploa | ... | @@ -13,3 +13,5 @@ EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/Uploa |
| 13 | DEALER_CODE = ocr_situ_group | 13 | DEALER_CODE = ocr_situ_group |
| 14 | 14 | ||
| 15 | BASE_URL = https://staging-bmw-ocr.situdata.com | 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 | ... | ... |
| ... | @@ -13,3 +13,5 @@ EDMS_UPLOAD_URL = http://sccn0637.bmwgroup.net/FH/FileHold/DocumentRepository/Up | ... | @@ -13,3 +13,5 @@ EDMS_UPLOAD_URL = http://sccn0637.bmwgroup.net/FH/FileHold/DocumentRepository/Up |
| 13 | DEALER_CODE = ocr_situ_group | 13 | DEALER_CODE = ocr_situ_group |
| 14 | 14 | ||
| 15 | BASE_URL = https://li19dkocruat01vm.bmwgroup.net | 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