add count summary
Showing
10 changed files
with
179 additions
and
79 deletions
| ... | @@ -858,17 +858,30 @@ FIELD_ORDER_MAP = { | ... | @@ -858,17 +858,30 @@ FIELD_ORDER_MAP = { |
| 858 | MVC_CLASSIFY_SE: ('转移登记日期', MVC_SE_FIELD_ORDER_3_4, MVC_SE_FIELD_ORDER_1_2) | 858 | MVC_CLASSIFY_SE: ('转移登记日期', MVC_SE_FIELD_ORDER_3_4, MVC_SE_FIELD_ORDER_1_2) |
| 859 | } | 859 | } |
| 860 | 860 | ||
| 861 | LICENSE_ORDER = ((MVI_CLASSIFY, (MVI_PID, MVI_CN_NAME, MVI_FIELD_ORDER, False, False)), | 861 | MODEL_FIELD_BS = 'bs_count' |
| 862 | (IC_CLASSIFY, (IC_PID, IC_CN_NAME, None, True, False)), | 862 | MODEL_FIELD_MVI = 'mvi_count' |
| 863 | (RP_CLASSIFY, (None, RP_CN_NAME, None, True, False)), | 863 | MODEL_FIELD_IC = 'ic_count' |
| 864 | (BC_CLASSIFY, (BC_PID, BC_CN_NAME, BC_FIELD_ORDER, False, False)), | 864 | MODEL_FIELD_RP = 'rp_count' |
| 865 | (BL_CLASSIFY, (BL_PID, BL_CN_NAME, BL_FIELD_ORDER, False, False)), | 865 | MODEL_FIELD_BC = 'bc_count' |
| 866 | (UCI_CLASSIFY, (UCI_PID, UCI_CN_NAME, UCI_FIELD_ORDER, False, False)), | 866 | MODEL_FIELD_BL = 'bl_count' |
| 867 | (EEP_CLASSIFY, (EEP_PID, EEP_CN_NAME, EEP_FIELD_ORDER, False, False)), | 867 | MODEL_FIELD_UCI = 'uci_count' |
| 868 | (DL_CLASSIFY, (DL_PID, DL_CN_NAME, None, True, False)), | 868 | MODEL_FIELD_EEP = 'eep_count' |
| 869 | (PP_CLASSIFY, (PP_PID, PP_CN_NAME, PP_FIELD_ORDER, False, False)), | 869 | MODEL_FIELD_DL = 'dl_count' |
| 870 | (MVC_CLASSIFY, (MVC_PID, MVC_CN_NAME, None, True, True)), | 870 | MODEL_FIELD_PP = 'pp_count' |
| 871 | (VAT_CLASSIFY, (VAT_PID, VAT_CN_NAME, VAT_FIELD_ORDER, False, False))) | 871 | MODEL_FIELD_MVC = 'mvc_count' |
| 872 | MODEL_FIELD_VAT = 'vat_count' | ||
| 873 | |||
| 874 | LICENSE_ORDER = ((MVI_CLASSIFY, (MVI_PID, MVI_CN_NAME, MVI_FIELD_ORDER, False, False, MODEL_FIELD_MVI)), | ||
| 875 | (IC_CLASSIFY, (IC_PID, IC_CN_NAME, None, True, False, MODEL_FIELD_IC)), | ||
| 876 | (RP_CLASSIFY, (None, RP_CN_NAME, None, True, False, MODEL_FIELD_RP)), | ||
| 877 | (BC_CLASSIFY, (BC_PID, BC_CN_NAME, BC_FIELD_ORDER, False, False, MODEL_FIELD_BC)), | ||
| 878 | (BL_CLASSIFY, (BL_PID, BL_CN_NAME, BL_FIELD_ORDER, False, False, MODEL_FIELD_BL)), | ||
| 879 | (UCI_CLASSIFY, (UCI_PID, UCI_CN_NAME, UCI_FIELD_ORDER, False, False, MODEL_FIELD_UCI)), | ||
| 880 | (EEP_CLASSIFY, (EEP_PID, EEP_CN_NAME, EEP_FIELD_ORDER, False, False, MODEL_FIELD_EEP)), | ||
| 881 | (DL_CLASSIFY, (DL_PID, DL_CN_NAME, None, True, False, MODEL_FIELD_DL)), | ||
| 882 | (PP_CLASSIFY, (PP_PID, PP_CN_NAME, PP_FIELD_ORDER, False, False, MODEL_FIELD_PP)), | ||
| 883 | (MVC_CLASSIFY, (MVC_PID, MVC_CN_NAME, None, True, True, MODEL_FIELD_MVC)), | ||
| 884 | (VAT_CLASSIFY, (VAT_PID, VAT_CN_NAME, VAT_FIELD_ORDER, False, False, MODEL_FIELD_VAT))) | ||
| 872 | 885 | ||
| 873 | LICENSE_CLASSIFY_MAPPING = dict(LICENSE_ORDER) | 886 | LICENSE_CLASSIFY_MAPPING = dict(LICENSE_ORDER) |
| 874 | 887 | ... | ... |
| ... | @@ -9,6 +9,7 @@ import difflib | ... | @@ -9,6 +9,7 @@ import difflib |
| 9 | import requests | 9 | import requests |
| 10 | from collections import Counter | 10 | from collections import Counter |
| 11 | from datetime import datetime, date | 11 | from datetime import datetime, date |
| 12 | from django.utils import timezone | ||
| 12 | from django.core.management import BaseCommand | 13 | from django.core.management import BaseCommand |
| 13 | from multiprocessing import Process, Queue, Manager, Lock | 14 | from multiprocessing import Process, Queue, Manager, Lock |
| 14 | 15 | ||
| ... | @@ -32,7 +33,12 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -32,7 +33,12 @@ class Command(BaseCommand, LoggerMixin): |
| 32 | # 处理文件开关 | 33 | # 处理文件开关 |
| 33 | self.switch = True | 34 | self.switch = True |
| 34 | # 睡眠时间 | 35 | # 睡眠时间 |
| 35 | self.sleep_time = int(conf.SLEEP_SECOND) | 36 | self.sleep_time_doc_get = float(conf.SLEEP_SECOND_DOC_GET) |
| 37 | self.sleep_time_img_put = float(conf.SLEEP_SECOND_IMG_PUT) | ||
| 38 | self.sleep_time_img_get = float(conf.SLEEP_SECOND_IMG_GET) | ||
| 39 | self.sleep_time_task_get = float(conf.SLEEP_SECOND_TASK_GET) | ||
| 40 | # 队列长度 | ||
| 41 | self.img_queue_size = int(conf.IMG_QUEUE_SIZE) | ||
| 36 | # 数据目录 | 42 | # 数据目录 |
| 37 | self.data_dir = conf.DATA_DIR | 43 | self.data_dir = conf.DATA_DIR |
| 38 | # ocr相关 | 44 | # ocr相关 |
| ... | @@ -73,7 +79,8 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -73,7 +79,8 @@ class Command(BaseCommand, LoggerMixin): |
| 73 | self.cronjob_log.warn('{0} [get_doc_info] [doc status error] [task_str={1}] [is_priority={2}] ' | 79 | self.cronjob_log.warn('{0} [get_doc_info] [doc status error] [task_str={1}] [is_priority={2}] ' |
| 74 | '[doc_status={3}]'.format(self.log_base, task_str, is_priority, doc.status)) | 80 | '[doc_status={3}]'.format(self.log_base, task_str, is_priority, doc.status)) |
| 75 | return None, None, None | 81 | return None, None, None |
| 76 | doc.status = DocStatus.PROCESSING.value # TODO update_time --> start_time | 82 | doc.status = DocStatus.PROCESSING.value |
| 83 | doc.start_time = timezone.now() | ||
| 77 | doc.save() | 84 | doc.save() |
| 78 | self.cronjob_log.info('{0} [get_doc_info] [success] [task_str={1}] [is_priority={2}]'.format( | 85 | self.cronjob_log.info('{0} [get_doc_info] [success] [task_str={1}] [is_priority={2}]'.format( |
| 79 | self.log_base, task_str, is_priority)) | 86 | self.log_base, task_str, is_priority)) |
| ... | @@ -360,7 +367,7 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -360,7 +367,7 @@ class Command(BaseCommand, LoggerMixin): |
| 360 | doc, business_type, task_str = self.get_doc_info() | 367 | doc, business_type, task_str = self.get_doc_info() |
| 361 | # 队列为空时的处理 | 368 | # 队列为空时的处理 |
| 362 | if doc is None: | 369 | if doc is None: |
| 363 | time.sleep(self.sleep_time) | 370 | time.sleep(self.sleep_time_doc_get) |
| 364 | continue | 371 | continue |
| 365 | 372 | ||
| 366 | try: | 373 | try: |
| ... | @@ -368,19 +375,26 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -368,19 +375,26 @@ class Command(BaseCommand, LoggerMixin): |
| 368 | doc_data_path = os.path.join(self.data_dir, business_type, str(doc.id)) | 375 | doc_data_path = os.path.join(self.data_dir, business_type, str(doc.id)) |
| 369 | os.makedirs(doc_data_path, exist_ok=True) | 376 | os.makedirs(doc_data_path, exist_ok=True) |
| 370 | pdf_path = os.path.join(doc_data_path, '{0}.pdf'.format(doc.id)) | 377 | pdf_path = os.path.join(doc_data_path, '{0}.pdf'.format(doc.id)) |
| 371 | img_save_path = os.path.join(doc_data_path, 'img') | ||
| 372 | self.pdf_download(doc, pdf_path) | 378 | self.pdf_download(doc, pdf_path) |
| 373 | 379 | ||
| 374 | # 3.PDF文件提取图片 | 380 | # 3.PDF文件提取图片 |
| 375 | self.cronjob_log.info('{0} [pdf to img start] [task={1}]'.format(self.log_base, task_str)) | 381 | self.cronjob_log.info('{0} [pdf to img start] [task={1}]'.format(self.log_base, task_str)) |
| 382 | start_time = time.time() | ||
| 383 | img_save_path = os.path.join(doc_data_path, 'img') | ||
| 376 | pdf_handler = PDFHandler(pdf_path, img_save_path) | 384 | pdf_handler = PDFHandler(pdf_path, img_save_path) |
| 377 | pdf_handler.extract_image() | 385 | pdf_handler.extract_image() |
| 378 | self.cronjob_log.info('{0} [pdf to img end] [task={1}]'.format(self.log_base, task_str)) | 386 | end_time = time.time() |
| 387 | speed_time = int(end_time - start_time) | ||
| 388 | self.cronjob_log.info('{0} [pdf to img end] [task={1}] [spend_time={2}]'.format( | ||
| 389 | self.log_base, task_str, speed_time)) | ||
| 379 | 390 | ||
| 380 | with lock: | 391 | with lock: |
| 381 | todo_count_dict[task_str] = len(pdf_handler.img_path_list) | 392 | todo_count_dict[task_str] = len(pdf_handler.img_path_list) |
| 382 | for img_path in pdf_handler.img_path_list: | 393 | for img_path in pdf_handler.img_path_list: |
| 383 | img_queue.put(img_path) # TODO 队列控制 | 394 | while img_queue.full(): |
| 395 | self.cronjob_log.info('{0} [pdf_2_img_2_queue] [img queue full]'.format(self.log_base)) | ||
| 396 | time.sleep(self.sleep_time_img_put) | ||
| 397 | img_queue.put(img_path) | ||
| 384 | except EDMSException as e: | 398 | except EDMSException as e: |
| 385 | doc.status = DocStatus.PROCESS_FAILED.value | 399 | doc.status = DocStatus.PROCESS_FAILED.value |
| 386 | doc.save() | 400 | doc.save() |
| ... | @@ -398,7 +412,7 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -398,7 +412,7 @@ class Command(BaseCommand, LoggerMixin): |
| 398 | img_path = img_queue.get(block=False) | 412 | img_path = img_queue.get(block=False) |
| 399 | except Exception as e: | 413 | except Exception as e: |
| 400 | # self.cronjob_log.info('{0} [img_2_ocr_1] [queue empty]'.format(self.log_base)) | 414 | # self.cronjob_log.info('{0} [img_2_ocr_1] [queue empty]'.format(self.log_base)) |
| 401 | time.sleep(0.5) | 415 | time.sleep(self.sleep_time_img_get) |
| 402 | continue | 416 | continue |
| 403 | else: | 417 | else: |
| 404 | self.cronjob_log.info('{0} [img_2_ocr_1] [get img] [img_path={1}]'.format(self.log_base, img_path)) | 418 | self.cronjob_log.info('{0} [img_2_ocr_1] [get img] [img_path={1}]'.format(self.log_base, img_path)) |
| ... | @@ -454,7 +468,7 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -454,7 +468,7 @@ class Command(BaseCommand, LoggerMixin): |
| 454 | task_str = finish_queue.get(block=False) | 468 | task_str = finish_queue.get(block=False) |
| 455 | except Exception as e: | 469 | except Exception as e: |
| 456 | # self.cronjob_log.info('{0} [res_2_wb] [queue empty]'.format(self.log_base)) | 470 | # self.cronjob_log.info('{0} [res_2_wb] [queue empty]'.format(self.log_base)) |
| 457 | time.sleep(1) | 471 | time.sleep(self.sleep_time_task_get) |
| 458 | continue | 472 | continue |
| 459 | else: | 473 | else: |
| 460 | self.cronjob_log.info('{0} [res_2_wb] [get task] [task={1}]'.format(self.log_base, task_str)) | 474 | self.cronjob_log.info('{0} [res_2_wb] [get task] [task={1}]'.format(self.log_base, task_str)) |
| ... | @@ -492,7 +506,7 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -492,7 +506,7 @@ class Command(BaseCommand, LoggerMixin): |
| 492 | elif classify in consts.LICENSE_CLASSIFY_SET_1: # 证件1 | 506 | elif classify in consts.LICENSE_CLASSIFY_SET_1: # 证件1 |
| 493 | self.license1_process(ocr_data, license_summary, classify, res_list, pno, ino) | 507 | self.license1_process(ocr_data, license_summary, classify, res_list, pno, ino) |
| 494 | elif classify in consts.LICENSE_CLASSIFY_SET_2: # 证件2 | 508 | elif classify in consts.LICENSE_CLASSIFY_SET_2: # 证件2 |
| 495 | pid, _, _, _, _ = consts.LICENSE_CLASSIFY_MAPPING.get(classify) | 509 | pid, _, _, _, _, _ = consts.LICENSE_CLASSIFY_MAPPING.get(classify) |
| 496 | with open(img_path, 'rb') as f: | 510 | with open(img_path, 'rb') as f: |
| 497 | base64_data = base64.b64encode(f.read()) | 511 | base64_data = base64.b64encode(f.read()) |
| 498 | # 获取解码后的base64值 | 512 | # 获取解码后的base64值 |
| ... | @@ -548,8 +562,8 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -548,8 +562,8 @@ class Command(BaseCommand, LoggerMixin): |
| 548 | 562 | ||
| 549 | with lock: | 563 | with lock: |
| 550 | del res_dict[task_str] | 564 | del res_dict[task_str] |
| 551 | self.cronjob_log.info('{0} [res_dict record] [res_dict={1}]'.format( | 565 | # self.cronjob_log.info('{0} [res_dict record] [res_dict={1}]'.format( |
| 552 | self.log_base, res_dict)) | 566 | # self.log_base, res_dict)) |
| 553 | 567 | ||
| 554 | self.cronjob_log.info('{0} [task={1}] [bs_summary={2}] [unknown_summary={3}] ' | 568 | self.cronjob_log.info('{0} [task={1}] [bs_summary={2}] [unknown_summary={3}] ' |
| 555 | '[license_summary={4}]'.format(self.log_base, task_str, bs_summary, | 569 | '[license_summary={4}]'.format(self.log_base, task_str, bs_summary, |
| ... | @@ -568,7 +582,7 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -568,7 +582,7 @@ class Command(BaseCommand, LoggerMixin): |
| 568 | excel_path = os.path.join(doc_data_path, '{0}.xlsx'.format(doc.id)) | 582 | excel_path = os.path.join(doc_data_path, '{0}.xlsx'.format(doc.id)) |
| 569 | img_save_path = os.path.join(doc_data_path, 'img') | 583 | img_save_path = os.path.join(doc_data_path, 'img') |
| 570 | # wb.save(src_excel_path) | 584 | # wb.save(src_excel_path) |
| 571 | wb.rebuild(merged_bs_summary, license_summary, res_list, doc.document_scheme) | 585 | count_list = wb.rebuild(merged_bs_summary, license_summary, res_list, doc.document_scheme) |
| 572 | wb.save(excel_path) | 586 | wb.save(excel_path) |
| 573 | except Exception as e: | 587 | except Exception as e: |
| 574 | with lock: | 588 | with lock: |
| ... | @@ -576,7 +590,7 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -576,7 +590,7 @@ class Command(BaseCommand, LoggerMixin): |
| 576 | del res_dict[task_str] | 590 | del res_dict[task_str] |
| 577 | doc, _ = self.get_doc_object(task_str) | 591 | doc, _ = self.get_doc_object(task_str) |
| 578 | doc.status = DocStatus.PROCESS_FAILED.value | 592 | doc.status = DocStatus.PROCESS_FAILED.value |
| 579 | doc.save() # TODO end_time | 593 | doc.save() |
| 580 | self.cronjob_log.error('{0} [process failed (res to wb)] [task={1}] [err={2}]'.format( | 594 | self.cronjob_log.error('{0} [process failed (res to wb)] [task={1}] [err={2}]'.format( |
| 581 | self.log_base, task_str, e)) | 595 | self.log_base, task_str, e)) |
| 582 | else: | 596 | else: |
| ... | @@ -595,7 +609,12 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -595,7 +609,12 @@ class Command(BaseCommand, LoggerMixin): |
| 595 | else: | 609 | else: |
| 596 | raise EDMSException(edms_exc) | 610 | raise EDMSException(edms_exc) |
| 597 | except Exception as e: | 611 | except Exception as e: |
| 598 | doc.status = DocStatus.UPLOAD_FAILED.value # TODO end_time | 612 | doc.status = DocStatus.UPLOAD_FAILED.value |
| 613 | doc.end_time = timezone.now() | ||
| 614 | doc.duration = (doc.start_time - doc.end_time).seconds | ||
| 615 | for field, count in count_list: | ||
| 616 | if hasattr(doc, field): | ||
| 617 | setattr(doc, field, count) | ||
| 599 | doc.save() | 618 | doc.save() |
| 600 | self.cronjob_log.error('{0} [process failed (edms upload)] [task={1}] [err={2}]'.format( | 619 | self.cronjob_log.error('{0} [process failed (edms upload)] [task={1}] [err={2}]'.format( |
| 601 | self.log_base, task_str, e)) | 620 | self.log_base, task_str, e)) |
| ... | @@ -603,7 +622,12 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -603,7 +622,12 @@ class Command(BaseCommand, LoggerMixin): |
| 603 | 622 | ||
| 604 | else: | 623 | else: |
| 605 | doc.status = DocStatus.COMPLETE.value | 624 | doc.status = DocStatus.COMPLETE.value |
| 606 | doc.save() # TODO end_time | 625 | doc.end_time = timezone.now() |
| 626 | doc.duration = (doc.start_time - doc.end_time).seconds | ||
| 627 | for field, count in count_list: | ||
| 628 | if hasattr(doc, field): | ||
| 629 | setattr(doc, field, count) | ||
| 630 | doc.save() | ||
| 607 | self.cronjob_log.info('{0} [process complete] [task={1}]'.format(self.log_base, task_str)) | 631 | self.cronjob_log.info('{0} [process complete] [task={1}]'.format(self.log_base, task_str)) |
| 608 | write_zip_file(img_save_path, os.path.join(doc_data_path, '{0}_img.zip'.format(doc.id))) | 632 | write_zip_file(img_save_path, os.path.join(doc_data_path, '{0}_img.zip'.format(doc.id))) |
| 609 | 633 | ||
| ... | @@ -617,7 +641,7 @@ class Command(BaseCommand, LoggerMixin): | ... | @@ -617,7 +641,7 @@ class Command(BaseCommand, LoggerMixin): |
| 617 | with Manager() as manager: | 641 | with Manager() as manager: |
| 618 | todo_count_dict = manager.dict() | 642 | todo_count_dict = manager.dict() |
| 619 | res_dict = manager.dict() | 643 | res_dict = manager.dict() |
| 620 | img_queue = Queue() | 644 | img_queue = Queue(self.img_queue_size) |
| 621 | finish_queue = Queue() | 645 | finish_queue = Queue() |
| 622 | 646 | ||
| 623 | process_list = [] | 647 | process_list = [] | ... | ... |
| ... | @@ -35,16 +35,31 @@ class HILDoc(models.Model): | ... | @@ -35,16 +35,31 @@ class HILDoc(models.Model): |
| 35 | retry_step = models.SmallIntegerField(null=True, verbose_name="重试环节") | 35 | retry_step = models.SmallIntegerField(null=True, verbose_name="重试环节") |
| 36 | retry_times = models.SmallIntegerField(default=0, verbose_name="重试次数") | 36 | retry_times = models.SmallIntegerField(default=0, verbose_name="重试次数") |
| 37 | is_retry = models.BooleanField(default=False, verbose_name="是否需要重试") | 37 | is_retry = models.BooleanField(default=False, verbose_name="是否需要重试") |
| 38 | main_applicant = models.CharField(max_length=16, verbose_name="主申请人") | 38 | # main_applicant = models.CharField(max_length=16, verbose_name="主申请人") |
| 39 | co_applicant = models.CharField(max_length=16, verbose_name="共同申请人") | 39 | # co_applicant = models.CharField(max_length=16, verbose_name="共同申请人") |
| 40 | guarantor_1 = models.CharField(max_length=16, verbose_name="担保人1") | 40 | # guarantor_1 = models.CharField(max_length=16, verbose_name="担保人1") |
| 41 | guarantor_2 = models.CharField(max_length=16, verbose_name="担保人2") | 41 | # guarantor_2 = models.CharField(max_length=16, verbose_name="担保人2") |
| 42 | document_name = models.CharField(max_length=255, verbose_name="文件名") | 42 | document_name = models.CharField(max_length=255, verbose_name="文件名") |
| 43 | document_scheme = models.CharField(max_length=64, verbose_name="文件方案") | 43 | document_scheme = models.CharField(max_length=64, verbose_name="文件方案") |
| 44 | data_source = models.CharField(max_length=64, verbose_name="数据源") | 44 | data_source = models.CharField(max_length=64, verbose_name="数据源") |
| 45 | upload_finish_time = models.DateTimeField(verbose_name="上传完成时间") # 索引 | 45 | upload_finish_time = models.DateTimeField(verbose_name="上传完成时间") # 索引 |
| 46 | update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间') | ||
| 47 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') # 索引 | 46 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') # 索引 |
| 47 | start_time = models.DateTimeField(null=True, verbose_name='开始时间') # 联合索引 | ||
| 48 | end_time = models.DateTimeField(null=True, verbose_name='结束时间') # 联合索引 | ||
| 49 | duration = models.IntegerField(null=True, verbose_name='处理时长') | ||
| 50 | |||
| 51 | bs_count = models.IntegerField(default=0, verbose_name='银行流水处理数目') | ||
| 52 | mvi_count = models.IntegerField(default=0, verbose_name='机动车销售统一发票处理数目') | ||
| 53 | ic_count = models.IntegerField(default=0, verbose_name='身份证处理数目') | ||
| 54 | rp_count = models.IntegerField(default=0, verbose_name='居住证处理数目') | ||
| 55 | bc_count = models.IntegerField(default=0, verbose_name='银行卡处理数目') | ||
| 56 | bl_count = models.IntegerField(default=0, verbose_name='营业执照处理数目') | ||
| 57 | uci_count = models.IntegerField(default=0, verbose_name='二手车发票处理数目') | ||
| 58 | eep_count = models.IntegerField(default=0, verbose_name='港澳台通行证处理数目') | ||
| 59 | dl_count = models.IntegerField(default=0, verbose_name='行驶证处理数目') | ||
| 60 | pp_count = models.IntegerField(default=0, verbose_name='护照处理数目') | ||
| 61 | mvc_count = models.IntegerField(default=0, verbose_name='机动车登记证书处理数目') | ||
| 62 | vat_count = models.IntegerField(default=0, verbose_name='增值税发票处理数目') | ||
| 48 | 63 | ||
| 49 | class Meta: | 64 | class Meta: |
| 50 | managed = False | 65 | managed = False |
| ... | @@ -59,16 +74,31 @@ class AFCDoc(models.Model): | ... | @@ -59,16 +74,31 @@ class AFCDoc(models.Model): |
| 59 | retry_step = models.SmallIntegerField(null=True, verbose_name="重试环节") | 74 | retry_step = models.SmallIntegerField(null=True, verbose_name="重试环节") |
| 60 | retry_times = models.SmallIntegerField(default=0, verbose_name="重试次数") | 75 | retry_times = models.SmallIntegerField(default=0, verbose_name="重试次数") |
| 61 | is_retry = models.BooleanField(default=False, verbose_name="是否需要重试") | 76 | is_retry = models.BooleanField(default=False, verbose_name="是否需要重试") |
| 62 | main_applicant = models.CharField(max_length=16, verbose_name="主申请人") | 77 | # main_applicant = models.CharField(max_length=16, verbose_name="主申请人") |
| 63 | co_applicant = models.CharField(max_length=16, verbose_name="共同申请人") | 78 | # co_applicant = models.CharField(max_length=16, verbose_name="共同申请人") |
| 64 | guarantor_1 = models.CharField(max_length=16, verbose_name="担保人1") | 79 | # guarantor_1 = models.CharField(max_length=16, verbose_name="担保人1") |
| 65 | guarantor_2 = models.CharField(max_length=16, verbose_name="担保人2") | 80 | # guarantor_2 = models.CharField(max_length=16, verbose_name="担保人2") |
| 66 | document_name = models.CharField(max_length=255, verbose_name="文件名") | 81 | document_name = models.CharField(max_length=255, verbose_name="文件名") |
| 67 | document_scheme = models.CharField(max_length=64, verbose_name="文件方案") | 82 | document_scheme = models.CharField(max_length=64, verbose_name="文件方案") |
| 68 | data_source = models.CharField(max_length=64, verbose_name="数据源") | 83 | data_source = models.CharField(max_length=64, verbose_name="数据源") |
| 69 | upload_finish_time = models.DateTimeField(verbose_name="上传完成时间") | 84 | upload_finish_time = models.DateTimeField(verbose_name="上传完成时间") |
| 70 | update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间') | ||
| 71 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') | 85 | create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') |
| 86 | start_time = models.DateTimeField(null=True, verbose_name='开始时间') | ||
| 87 | end_time = models.DateTimeField(null=True, verbose_name='结束时间') | ||
| 88 | duration = models.IntegerField(null=True, verbose_name='处理时长') | ||
| 89 | |||
| 90 | bs_count = models.IntegerField(default=0, verbose_name='银行流水处理数目') | ||
| 91 | mvi_count = models.IntegerField(default=0, verbose_name='机动车销售统一发票处理数目') | ||
| 92 | ic_count = models.IntegerField(default=0, verbose_name='身份证处理数目') | ||
| 93 | rp_count = models.IntegerField(default=0, verbose_name='居住证处理数目') | ||
| 94 | bc_count = models.IntegerField(default=0, verbose_name='银行卡处理数目') | ||
| 95 | bl_count = models.IntegerField(default=0, verbose_name='营业执照处理数目') | ||
| 96 | uci_count = models.IntegerField(default=0, verbose_name='二手车发票处理数目') | ||
| 97 | eep_count = models.IntegerField(default=0, verbose_name='港澳台通行证处理数目') | ||
| 98 | dl_count = models.IntegerField(default=0, verbose_name='行驶证处理数目') | ||
| 99 | pp_count = models.IntegerField(default=0, verbose_name='护照处理数目') | ||
| 100 | mvc_count = models.IntegerField(default=0, verbose_name='机动车登记证书处理数目') | ||
| 101 | vat_count = models.IntegerField(default=0, verbose_name='增值税发票处理数目') | ||
| 72 | 102 | ||
| 73 | class Meta: | 103 | class Meta: |
| 74 | managed = False | 104 | managed = False | ... | ... |
| ... | @@ -57,7 +57,7 @@ class EDMS: | ... | @@ -57,7 +57,7 @@ class EDMS: |
| 57 | r = requests.get(self.download_url, params=params, headers=headers, stream=True) | 57 | r = requests.get(self.download_url, params=params, headers=headers, stream=True) |
| 58 | with open(save_path, "wb") as f: | 58 | with open(save_path, "wb") as f: |
| 59 | # chunk是指定每次写入的大小,每次只写了512byte | 59 | # chunk是指定每次写入的大小,每次只写了512byte |
| 60 | for chunk in r.iter_content(chunk_size=512): | 60 | for chunk in r.iter_content(chunk_size=1024): |
| 61 | if chunk: | 61 | if chunk: |
| 62 | f.write(chunk) | 62 | f.write(chunk) |
| 63 | f.flush() | 63 | f.flush() | ... | ... |
| ... | @@ -321,7 +321,6 @@ class BSWorkbook(Workbook): | ... | @@ -321,7 +321,6 @@ class BSWorkbook(Workbook): |
| 321 | amount_fill_row = set() | 321 | amount_fill_row = set() |
| 322 | 322 | ||
| 323 | for rows in new_ws.iter_rows(min_row=2): | 323 | for rows in new_ws.iter_rows(min_row=2): |
| 324 | # TODO 删除空行 | ||
| 325 | summary_cell = None if summary_cell_idx is None else rows[summary_cell_idx] | 324 | summary_cell = None if summary_cell_idx is None else rows[summary_cell_idx] |
| 326 | date_cell = None if date_cell_idx is None else rows[date_cell_idx] | 325 | date_cell = None if date_cell_idx is None else rows[date_cell_idx] |
| 327 | amount_cell = None if amount_cell_idx is None else rows[amount_cell_idx] | 326 | amount_cell = None if amount_cell_idx is None else rows[amount_cell_idx] |
| ... | @@ -441,7 +440,8 @@ class BSWorkbook(Workbook): | ... | @@ -441,7 +440,8 @@ class BSWorkbook(Workbook): |
| 441 | sheet_header_info = {} | 440 | sheet_header_info = {} |
| 442 | header_info = {} | 441 | header_info = {} |
| 443 | max_column_list = [] | 442 | max_column_list = [] |
| 444 | for sheet in summary.get('sheet', []): | 443 | sheets_list = summary.get('sheet', []) |
| 444 | for sheet in sheets_list: | ||
| 445 | ws = self.get_sheet_by_name(sheet) | 445 | ws = self.get_sheet_by_name(sheet) |
| 446 | self.header_collect(ws, sheet_header_info, header_info, max_column_list, classify) | 446 | self.header_collect(ws, sheet_header_info, header_info, max_column_list, classify) |
| 447 | statistics_header_info = self.header_statistics(sheet_header_info, header_info, classify) | 447 | statistics_header_info = self.header_statistics(sheet_header_info, header_info, classify) |
| ... | @@ -454,7 +454,7 @@ class BSWorkbook(Workbook): | ... | @@ -454,7 +454,7 @@ class BSWorkbook(Workbook): |
| 454 | date_list = [] # 用于收集各表中日期 | 454 | date_list = [] # 用于收集各表中日期 |
| 455 | month_mapping = {} # 用于创建月份表 | 455 | month_mapping = {} # 用于创建月份表 |
| 456 | reverse_trend_list = [] # 用于判断倒序与正序 | 456 | reverse_trend_list = [] # 用于判断倒序与正序 |
| 457 | for sheet in summary.get('sheet', []): | 457 | for sheet in sheets_list: |
| 458 | ws = self.get_sheet_by_name(sheet) | 458 | ws = self.get_sheet_by_name(sheet) |
| 459 | date_col, min_row = self.get_data_col_min_row(sheet, sheet_header_info, header_info, classify) | 459 | date_col, min_row = self.get_data_col_min_row(sheet, sheet_header_info, header_info, classify) |
| 460 | self.sheet_split(ws, date_col, min_row, month_mapping, reverse_trend_list, date_list, date_statistics) | 460 | self.sheet_split(ws, date_col, min_row, month_mapping, reverse_trend_list, date_list, date_statistics) |
| ... | @@ -480,14 +480,15 @@ class BSWorkbook(Workbook): | ... | @@ -480,14 +480,15 @@ class BSWorkbook(Workbook): |
| 480 | self.build_month_sheet(ms, card, month_mapping, is_reverse, statistics_header_info, max_column) | 480 | self.build_month_sheet(ms, card, month_mapping, is_reverse, statistics_header_info, max_column) |
| 481 | 481 | ||
| 482 | # 4.删除原表 | 482 | # 4.删除原表 |
| 483 | for sheet in summary.get('sheet'): | 483 | for sheet in sheets_list: |
| 484 | self.remove(self.get_sheet_by_name(sheet)) | 484 | self.remove(self.get_sheet_by_name(sheet)) |
| 485 | 485 | ||
| 486 | def license_rebuild(self, license_summary, document_scheme): | 486 | def license_rebuild(self, license_summary, document_scheme, count_list): |
| 487 | for classify, (_, name, field_order, side_diff, scheme_diff) in consts.LICENSE_ORDER: | 487 | for classify, (_, name, field_order, side_diff, scheme_diff, field_str) in consts.LICENSE_ORDER: |
| 488 | license_list = license_summary.get(classify) | 488 | license_list = license_summary.get(classify) |
| 489 | if not license_list: | 489 | if not license_list: |
| 490 | continue | 490 | continue |
| 491 | count = 0 | ||
| 491 | ws = self.create_sheet(name) | 492 | ws = self.create_sheet(name) |
| 492 | if scheme_diff and document_scheme == consts.DOC_SCHEME_LIST[1]: | 493 | if scheme_diff and document_scheme == consts.DOC_SCHEME_LIST[1]: |
| 493 | classify = consts.MVC_CLASSIFY_SE | 494 | classify = consts.MVC_CLASSIFY_SE |
| ... | @@ -505,6 +506,8 @@ class BSWorkbook(Workbook): | ... | @@ -505,6 +506,8 @@ class BSWorkbook(Workbook): |
| 505 | else: | 506 | else: |
| 506 | ws.append((write_field, field_value)) | 507 | ws.append((write_field, field_value)) |
| 507 | ws.append((None, )) | 508 | ws.append((None, )) |
| 509 | count += 1 | ||
| 510 | count_list.append((field_str, count)) | ||
| 508 | 511 | ||
| 509 | def res_sheet(self, res_list): | 512 | def res_sheet(self, res_list): |
| 510 | if res_list: | 513 | if res_list: |
| ... | @@ -519,7 +522,9 @@ class BSWorkbook(Workbook): | ... | @@ -519,7 +522,9 @@ class BSWorkbook(Workbook): |
| 519 | self.remove(self.get_sheet_by_name('Sheet')) | 522 | self.remove(self.get_sheet_by_name('Sheet')) |
| 520 | 523 | ||
| 521 | def rebuild(self, bs_summary, license_summary, res_list, document_scheme): | 524 | def rebuild(self, bs_summary, license_summary, res_list, document_scheme): |
| 525 | count_list = [(consts.MODEL_FIELD_BS, len(self.sheetnames) - 1)] | ||
| 522 | self.bs_rebuild(bs_summary) | 526 | self.bs_rebuild(bs_summary) |
| 523 | self.license_rebuild(license_summary, document_scheme) | 527 | self.license_rebuild(license_summary, document_scheme, count_list) |
| 524 | self.res_sheet(res_list) | 528 | self.res_sheet(res_list) |
| 525 | self.remove_base_sheet() | 529 | self.remove_base_sheet() |
| 530 | return count_list | ... | ... |
| ... | @@ -128,10 +128,10 @@ class UploadDocView(GenericView, DocHandler): | ... | @@ -128,10 +128,10 @@ class UploadDocView(GenericView, DocHandler): |
| 128 | doc = doc_class.objects.create( | 128 | doc = doc_class.objects.create( |
| 129 | metadata_version_id=document.get('metadataVersionId'), | 129 | metadata_version_id=document.get('metadataVersionId'), |
| 130 | application_id=application_id, | 130 | application_id=application_id, |
| 131 | main_applicant=applicant_data.get('mainApplicantName'), | 131 | # main_applicant=applicant_data.get('mainApplicantName'), |
| 132 | co_applicant=applicant_data.get('coApplicantName'), | 132 | # co_applicant=applicant_data.get('coApplicantName'), |
| 133 | guarantor_1=applicant_data.get('guarantor1Name'), | 133 | # guarantor_1=applicant_data.get('guarantor1Name'), |
| 134 | guarantor_2=applicant_data.get('guarantor2Name'), | 134 | # guarantor_2=applicant_data.get('guarantor2Name'), |
| 135 | document_name=document.get('documentName'), | 135 | document_name=document.get('documentName'), |
| 136 | document_scheme=self.fix_scheme(document_scheme), | 136 | document_scheme=self.fix_scheme(document_scheme), |
| 137 | data_source=self.fix_data_source(data_source), | 137 | data_source=self.fix_data_source(data_source), |
| ... | @@ -299,10 +299,10 @@ class DocView(GenericView, DocHandler): | ... | @@ -299,10 +299,10 @@ class DocView(GenericView, DocHandler): |
| 299 | doc = doc_class.objects.create( | 299 | doc = doc_class.objects.create( |
| 300 | metadata_version_id=metadata_version_id, | 300 | metadata_version_id=metadata_version_id, |
| 301 | application_id=application_id, | 301 | application_id=application_id, |
| 302 | main_applicant='', | 302 | # main_applicant='', |
| 303 | co_applicant='', | 303 | # co_applicant='', |
| 304 | guarantor_1='', | 304 | # guarantor_1='', |
| 305 | guarantor_2='', | 305 | # guarantor_2='', |
| 306 | document_name=application_id, | 306 | document_name=application_id, |
| 307 | document_scheme=document_scheme, | 307 | document_scheme=document_scheme, |
| 308 | data_source=data_source, | 308 | data_source=data_source, | ... | ... |
| ... | @@ -9,13 +9,6 @@ cursor.execute("create database hil") | ... | @@ -9,13 +9,6 @@ cursor.execute("create database hil") |
| 9 | cursor.close() | 9 | cursor.close() |
| 10 | cnxn.close() | 10 | cnxn.close() |
| 11 | 11 | ||
| 12 | # retry_step = models.SmallIntegerField(null=True, verbose_name="重试环节") | ||
| 13 | # retry_times = models.SmallIntegerField(default=0, verbose_name="重试次数") | ||
| 14 | # is_retry = models.BooleanField(default=False, verbose_name="是否需要重试") | ||
| 15 | # retry_step tinyint, | ||
| 16 | # retry_times tinyint default 0 not null, | ||
| 17 | # is_retry bit default 0 not null, | ||
| 18 | |||
| 19 | hil_sql_1 = """ | 12 | hil_sql_1 = """ |
| 20 | create table auth_group | 13 | create table auth_group |
| 21 | ( | 14 | ( |
| ... | @@ -315,16 +308,26 @@ hil_sql_2 = """ | ... | @@ -315,16 +308,26 @@ hil_sql_2 = """ |
| 315 | retry_step tinyint, | 308 | retry_step tinyint, |
| 316 | retry_times tinyint default 0 not null, | 309 | retry_times tinyint default 0 not null, |
| 317 | is_retry bit default 0 not null, | 310 | is_retry bit default 0 not null, |
| 318 | main_applicant nvarchar(16) not null, | ||
| 319 | co_applicant nvarchar(16) not null, | ||
| 320 | guarantor_1 nvarchar(16) not null, | ||
| 321 | guarantor_2 nvarchar(16) not null, | ||
| 322 | document_name nvarchar(255) not null, | 311 | document_name nvarchar(255) not null, |
| 323 | document_scheme nvarchar(64) not null, | 312 | document_scheme nvarchar(64) not null, |
| 324 | data_source nvarchar(64) not null, | 313 | data_source nvarchar(64) not null, |
| 325 | upload_finish_time datetime, | 314 | upload_finish_time datetime, |
| 326 | update_time datetime not null, | 315 | create_time datetime not null, |
| 327 | create_time datetime not null | 316 | start_time datetime, |
| 317 | end_time datetime, | ||
| 318 | duration smallint, | ||
| 319 | bs_count smallint default 0 not null, | ||
| 320 | mvi_count smallint default 0 not null, | ||
| 321 | ic_count smallint default 0 not null, | ||
| 322 | rp_count smallint default 0 not null, | ||
| 323 | bc_count smallint default 0 not null, | ||
| 324 | bl_count smallint default 0 not null, | ||
| 325 | uci_count smallint default 0 not null, | ||
| 326 | eep_count smallint default 0 not null, | ||
| 327 | dl_count smallint default 0 not null, | ||
| 328 | pp_count smallint default 0 not null, | ||
| 329 | mvc_count smallint default 0 not null, | ||
| 330 | vat_count smallint default 0 not null | ||
| 328 | ); | 331 | ); |
| 329 | 332 | ||
| 330 | create index hil_doc_upload_finish_time_index | 333 | create index hil_doc_upload_finish_time_index |
| ... | @@ -335,6 +338,9 @@ hil_sql_2 = """ | ... | @@ -335,6 +338,9 @@ hil_sql_2 = """ |
| 335 | 338 | ||
| 336 | create index hil_doc_application_id_status_index | 339 | create index hil_doc_application_id_status_index |
| 337 | on hil_doc (application_id, status); | 340 | on hil_doc (application_id, status); |
| 341 | |||
| 342 | create index hil_doc_start_time_end_time_index | ||
| 343 | on hil_doc (start_time, end_time); | ||
| 338 | """ | 344 | """ |
| 339 | 345 | ||
| 340 | afc_sql = """ | 346 | afc_sql = """ |
| ... | @@ -414,16 +420,26 @@ afc_sql = """ | ... | @@ -414,16 +420,26 @@ afc_sql = """ |
| 414 | retry_step tinyint, | 420 | retry_step tinyint, |
| 415 | retry_times tinyint default 0 not null, | 421 | retry_times tinyint default 0 not null, |
| 416 | is_retry bit default 0 not null, | 422 | is_retry bit default 0 not null, |
| 417 | main_applicant nvarchar(16) not null, | ||
| 418 | co_applicant nvarchar(16) not null, | ||
| 419 | guarantor_1 nvarchar(16) not null, | ||
| 420 | guarantor_2 nvarchar(16) not null, | ||
| 421 | document_name nvarchar(255) not null, | 423 | document_name nvarchar(255) not null, |
| 422 | document_scheme nvarchar(64) not null, | 424 | document_scheme nvarchar(64) not null, |
| 423 | data_source nvarchar(64) not null, | 425 | data_source nvarchar(64) not null, |
| 424 | upload_finish_time datetime, | 426 | upload_finish_time datetime, |
| 425 | update_time datetime not null, | 427 | create_time datetime not null, |
| 426 | create_time datetime not null | 428 | start_time datetime, |
| 429 | end_time datetime, | ||
| 430 | duration smallint, | ||
| 431 | bs_count smallint default 0 not null, | ||
| 432 | mvi_count smallint default 0 not null, | ||
| 433 | ic_count smallint default 0 not null, | ||
| 434 | rp_count smallint default 0 not null, | ||
| 435 | bc_count smallint default 0 not null, | ||
| 436 | bl_count smallint default 0 not null, | ||
| 437 | uci_count smallint default 0 not null, | ||
| 438 | eep_count smallint default 0 not null, | ||
| 439 | dl_count smallint default 0 not null, | ||
| 440 | pp_count smallint default 0 not null, | ||
| 441 | mvc_count smallint default 0 not null, | ||
| 442 | vat_count smallint default 0 not null | ||
| 427 | ); | 443 | ); |
| 428 | 444 | ||
| 429 | create index afc_doc_upload_finish_time_index | 445 | create index afc_doc_upload_finish_time_index |
| ... | @@ -434,6 +450,9 @@ afc_sql = """ | ... | @@ -434,6 +450,9 @@ afc_sql = """ |
| 434 | 450 | ||
| 435 | create index afc_doc_application_id_status_index | 451 | create index afc_doc_application_id_status_index |
| 436 | on afc_doc (application_id, status); | 452 | on afc_doc (application_id, status); |
| 453 | |||
| 454 | create index afc_doc_start_time_end_time_index | ||
| 455 | on afc_doc (start_time, end_time); | ||
| 437 | """ | 456 | """ |
| 438 | 457 | ||
| 439 | hil_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=hil;UID=SA;PWD=pwd', autocommit=True) | 458 | hil_cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=hil;UID=SA;PWD=pwd', autocommit=True) | ... | ... |
| 1 | [settings] | 1 | [settings] |
| 2 | DEBUG = False | 2 | DEBUG = False |
| 3 | SLEEP_SECOND = 5 | 3 | SLEEP_SECOND_DOC_GET = 2 |
| 4 | MAX_SLEEP_SECOND = 60 | 4 | SLEEP_SECOND_IMG_PUT = 1 |
| 5 | SLEEP_SECOND_IMG_GET = 0.5 | ||
| 6 | SLEEP_SECOND_TASK_GET = 1 | ||
| 7 | IMG_QUEUE_SIZE = 500 | ||
| 5 | 8 | ||
| 6 | EDMS_DOWNLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/DownloadHandler.ashx | 9 | EDMS_DOWNLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/DownloadHandler.ashx |
| 7 | EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/UploadHandler.ashx\ | 10 | EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/UploadHandler.ashx |
| 8 | DEALER_CODE = ocr_situ_group | 11 | DEALER_CODE = ocr_situ_group |
| 9 | 12 | ... | ... |
| 1 | [settings] | 1 | [settings] |
| 2 | DEBUG = True | 2 | DEBUG = True |
| 3 | SLEEP_SECOND = 5 | 3 | SLEEP_SECOND_DOC_GET = 10 |
| 4 | MAX_SLEEP_SECOND = 60 | 4 | SLEEP_SECOND_IMG_PUT = 1 |
| 5 | SLEEP_SECOND_IMG_GET = 0.5 | ||
| 6 | SLEEP_SECOND_TASK_GET = 2 | ||
| 7 | IMG_QUEUE_SIZE = 500 | ||
| 5 | 8 | ||
| 6 | EDMS_DOWNLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/DownloadHandler.ashx | 9 | EDMS_DOWNLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/DownloadHandler.ashx |
| 7 | EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/UploadHandler.ashx | 10 | EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/UploadHandler.ashx | ... | ... |
| 1 | [settings] | 1 | [settings] |
| 2 | DEBUG = False | 2 | DEBUG = False |
| 3 | SLEEP_SECOND = 5 | 3 | SLEEP_SECOND_DOC_GET = 2 |
| 4 | MAX_SLEEP_SECOND = 60 | 4 | SLEEP_SECOND_IMG_PUT = 1 |
| 5 | SLEEP_SECOND_IMG_GET = 0.5 | ||
| 6 | SLEEP_SECOND_TASK_GET = 1 | ||
| 7 | IMG_QUEUE_SIZE = 500 | ||
| 5 | 8 | ||
| 6 | EDMS_DOWNLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/DownloadHandler.ashx | 9 | EDMS_DOWNLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/DownloadHandler.ashx |
| 7 | EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/UploadHandler.ashx | 10 | EDMS_UPLOAD_URL = https://edms-test.bmw.com/FH/FileHold/DocumentRepository/UploadHandler.ashx | ... | ... |
-
Please register or sign in to post a comment