提交 c9b5f580 authored 作者: 贺阳's avatar 贺阳

提取时间的提示和规则作为系统参数

上级 57446825
...@@ -49,5 +49,26 @@ ...@@ -49,5 +49,26 @@
<field name="key">time_warning_hours</field> <field name="key">time_warning_hours</field>
<field name="value">24</field> <field name="value">24</field>
</record> </record>
<record id="push_time_reg" model="ir.config_parameter">
<field name="key">push_time_reg</field>
<field name="value">[
# 有空格的情况
r'DATE[/\s]*TIME[/\s]*OF[/\s]*RELEASE[^\n]*?(\d{2}:\d{2})\s+(\d{2}-[A-Z]{3}-\d{4})',
# 无空格的情况,紧跟在RELEASE后面就是时间数字
r'DATETIMEOFRELEASE(\d{2})(\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
# 增加容错,RELEASE可能被识别为其他形式
r'[Rr][Ee][Ll][Ee][Aa][Ss][Ee].*?(\d{2}:\d{2})\s+(\d{2}-[A-Z]{3}-\d{4})',
# 更宽松的无空格匹配
r'[Dd][Aa][Tt][Ee].*?[Tt][Ii][Mm][Ee].*?[Oo][Ff].*?[Rr][Ee][Ll][Ee][Aa][Ss][Ee](\d{2})(\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
# OCR可能将:识别为数字,如"DATETIMEOFRELEASE163420-SEP-2025"
r'DATETIMEOFRELEASE(\d)(\d)(\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
# OCR可能将:识别为多个空格,如"DATETIMEOFRELEASE 163420-SEP-2025"
r'DATETIMEOFRELEASE\s+(\d)(\d)(\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
# OCR可能将:识别为多个空格,如"DATETIMEOFRELEASE 1623420-SEP-2025"把:识别成了2 1333113-NOV-2025,把:识别成了3
r'DATETIMEOFRELEASE\s+(\d)(\d)[2,3](\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
r'DATETIMEQFRELEASE\s+(\d)(\d)[2,3](\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
]</field>
</record>
</data> </data>
</odoo> </odoo>
\ No newline at end of file
...@@ -1833,34 +1833,13 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -1833,34 +1833,13 @@ class BatchGetPodInfoWizard(models.TransientModel):
if not file_data: if not file_data:
logging.info(f"提单 {bl.bl_no} 没有文件数据") logging.info(f"提单 {bl.bl_no} 没有文件数据")
continue continue
try:
# 如果已识别过OCR文本,则复用 ship_packages.append({
ocr_texts = file_info.get('ocr_texts') 'bl_id': bl.id,
# 解析PDF提取时间 'id': valid_package_ids, # 只包含满足条件的小包ID
extracted_times = self._extract_time_from_pdf(file_data, bl.bl_no, ocr_texts=ocr_texts) 'tally_time': str(file_info.get('tally_time'))
if extracted_times: })
# 取最早的时间作为节点操作时间
earliest_time = min(extracted_times)
_logger.info(
f"提取到最早时间: {earliest_time},将作为节点操作时间,满足条件的小包数量: {len(valid_package_ids)},小包ID: {valid_package_ids}")
ship_packages.append({
'bl_id': bl.id,
'id': valid_package_ids, # 只包含满足条件的小包ID
'tally_time': str(earliest_time)
})
else:
_logger.warning(f"提单 {bl.bl_no} 没有提取到时间信息")
error_bl.append(bl)
except Exception as e:
_logger.error(f"获取提单对应的节点以及时间失败,提单号: {bl.bl_no}, 错误: {str(e)}")
error_bl.append(bl)
if error_bl:
_logger.warning(f"提单 {', '.join([bl.bl_no for bl in error_bl])} 没有提取到时间信息")
if not self._context.get('is_skip_raise_error'):
raise ValidationError(
_('%s bill of loading cannot get node operation time,please manually upload push tk') % (
', '.join([bl.bl_no for bl in error_bl]))) # xx提单号没有获取到节点操作时间,请手动上传推送提单到TK
return ship_packages, pod_node.id return ship_packages, pod_node.id
def _sync_match_node(self, ship_packages, pod_node_id): def _sync_match_node(self, ship_packages, pod_node_id):
...@@ -1915,22 +1894,27 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -1915,22 +1894,27 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 匹配两种情况: # 匹配两种情况:
# 1. 有空格: "DATE/TIME OF RELEASE 16:02 20-SEP-2025" # 1. 有空格: "DATE/TIME OF RELEASE 16:02 20-SEP-2025"
# 2. 无空格: "DATETIMEOFRELEASE160220-SEP-2025" # 2. 无空格: "DATETIMEOFRELEASE160220-SEP-2025"
release_time_patterns = [ release_time_patterns = self.env['ir.config_parameter'].sudo().get_param('push_time_reg')
# 有空格的情况 if release_time_patterns:
r'DATE[/\s]*TIME[/\s]*OF[/\s]*RELEASE[^\n]*?(\d{2}:\d{2})\s+(\d{2}-[A-Z]{3}-\d{4})', release_time_patterns = eval(release_time_patterns)
# 无空格的情况,紧跟在RELEASE后面就是时间数字 else:
r'DATETIMEOFRELEASE(\d{2})(\d{2})(\d{2})-([A-Z]{3})-(\d{4})', release_time_patterns = [
# 增加容错,RELEASE可能被识别为其他形式 # 有空格的情况
r'[Rr][Ee][Ll][Ee][Aa][Ss][Ee].*?(\d{2}:\d{2})\s+(\d{2}-[A-Z]{3}-\d{4})', r'DATE[/\s]*TIME[/\s]*OF[/\s]*RELEASE[^\n]*?(\d{2}:\d{2})\s+(\d{2}-[A-Z]{3}-\d{4})',
# 更宽松的无空格匹配 # 无空格的情况,紧跟在RELEASE后面就是时间数字
r'[Dd][Aa][Tt][Ee].*?[Tt][Ii][Mm][Ee].*?[Oo][Ff].*?[Rr][Ee][Ll][Ee][Aa][Ss][Ee](\d{2})(\d{2})(\d{2})-([A-Z]{3})-(\d{4})', r'DATETIMEOFRELEASE(\d{2})(\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
# OCR可能将:识别为数字,如"DATETIMEOFRELEASE163420-SEP-2025" # 增加容错,RELEASE可能被识别为其他形式
r'DATETIMEOFRELEASE(\d)(\d)(\d{2})(\d{2})-([A-Z]{3})-(\d{4})', r'[Rr][Ee][Ll][Ee][Aa][Ss][Ee].*?(\d{2}:\d{2})\s+(\d{2}-[A-Z]{3}-\d{4})',
# OCR可能将:识别为多个空格,如"DATETIMEOFRELEASE 163420-SEP-2025" # 更宽松的无空格匹配
r'DATETIMEOFRELEASE\s+(\d)(\d)(\d{2})(\d{2})-([A-Z]{3})-(\d{4})', r'[Dd][Aa][Tt][Ee].*?[Tt][Ii][Mm][Ee].*?[Oo][Ff].*?[Rr][Ee][Ll][Ee][Aa][Ss][Ee](\d{2})(\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
# OCR可能将:识别为多个空格,如"DATETIMEOFRELEASE 1623420-SEP-2025"把:识别成了2 # OCR可能将:识别为数字,如"DATETIMEOFRELEASE163420-SEP-2025"
r'DATETIMEOFRELEASE\s+(\d)(\d)2(\d{2})(\d{2})-([A-Z]{3})-(\d{4})', r'DATETIMEOFRELEASE(\d)(\d)(\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
] # OCR可能将:识别为多个空格,如"DATETIMEOFRELEASE 163420-SEP-2025"
r'DATETIMEOFRELEASE\s+(\d)(\d)(\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
# OCR可能将:识别为多个空格,如"DATETIMEOFRELEASE 1623420-SEP-2025"把:识别成了2 1333113-NOV-2025,把:识别成了3
r'DATETIMEOFRELEASE\s+(\d)(\d)[2,3](\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
r'DATETIMEQFRELEASE\s+(\d)(\d)[2,3](\d{2})(\d{2})-([A-Z]{3})-(\d{4})',
]
for idx, pattern in enumerate(release_time_patterns): for idx, pattern in enumerate(release_time_patterns):
release_time_match = re.search(pattern, text_content, re.IGNORECASE) release_time_match = re.search(pattern, text_content, re.IGNORECASE)
......
...@@ -20,7 +20,7 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -20,7 +20,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
:return: 满足条件的文件数组 :return: 满足条件的文件数组
""" """
valid_files = [] valid_files = []
error_bl = []
for file_info in processed_files: for file_info in processed_files:
if not file_info.get('bl'): if not file_info.get('bl'):
continue continue
...@@ -37,10 +37,12 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -37,10 +37,12 @@ class BatchGetPodInfoWizard(models.TransientModel):
) )
if not extracted_times: if not extracted_times:
_logger.warning(f"提单 {bl.bl_no} 未提取到时间信息,跳过节点推送") _logger.warning(f"提单 {bl.bl_no} 未提取到时间信息,跳过节点推送")
error_bl.append(bl)
continue continue
# 取最早时间作为提取时间(用户时区的本地时间) # 取最早时间作为提取时间(用户时区的本地时间)
extract_time_local = min(extracted_times) extract_time_local = min(extracted_times)
file_info['tally_time'] = extract_time_local
_logger.info(f"提单 {bl.bl_no} 最早提取时间(本地): {extract_time_local}") _logger.info(f"提单 {bl.bl_no} 最早提取时间(本地): {extract_time_local}")
# 将提取时间从用户时区转换为UTC(0时区) # 将提取时间从用户时区转换为UTC(0时区)
...@@ -93,6 +95,11 @@ class BatchGetPodInfoWizard(models.TransientModel): ...@@ -93,6 +95,11 @@ class BatchGetPodInfoWizard(models.TransientModel):
except Exception as e: except Exception as e:
_logger.error(f"验证提单 {bl.bl_no} 节点推送条件失败: {str(e)}") _logger.error(f"验证提单 {bl.bl_no} 节点推送条件失败: {str(e)}")
continue continue
if error_bl:
if not self._context.get('is_skip_raise_error'):
raise ValidationError(
_('提单 %s 没有提取到时间信息,请检查提单是否正确', ','.join([bl.bl_no for bl in error_bl]))
)
return valid_files return valid_files
def _check_packages_same_status(self, ship_packages): def _check_packages_same_status(self, ship_packages):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论