提交 8a7e31ff authored 作者: 贺阳's avatar 贺阳

获取pod,如果是自动的,失败的直接跳过。如果是手动批量,失败的需要进行提示,成功的需要继续执行

上级 151bf0e8
......@@ -719,7 +719,7 @@ class CcBL(models.Model):
bl_objs=self.env['cc.bl'].search([('state', '=', 'ccing'), ('cc_attachment_ids.file_name', '=', '尾程交接POD(待大包数量和箱号)'), ('cc_attachment_ids.file', '=', False)])
logging.info('cron_get_pod bl_objs:%s' % len(bl_objs))
if len(bl_objs) > 0:
wizard_obj = self.env['batch.get.pod.info.wizard'].sudo().with_context(active_id=bl_objs.ids).create({
wizard_obj = self.env['batch.get.pod.info.wizard'].sudo().with_context(active_id=bl_objs.ids,is_skip_raise_error=True).create({
'sync_last_mile_pod': True,
'remove_specified_text': True,
'sync_match_node': True
......
......@@ -51,6 +51,10 @@ class BatchGetPodInfoWizard(models.TransientModel):
# default=False,
# help='Show red markers for deleted text positions' # 显示删除文字位置的红色标记
# )
show_error_message = fields.Text(
string='Show Error Message',
help='Show error message'
)
def confirm(self):
"""
......@@ -58,6 +62,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
"""
# 计算整个过程的耗时
start_time = time.time()
self.show_error_message = False
bl_objs = self.get_order()
_logger.info(f"%s提单开始执行批量获取POD信息操作" % len(bl_objs))
# 调用接口获取提单pdf文件
......@@ -71,10 +76,13 @@ class BatchGetPodInfoWizard(models.TransientModel):
if bl.id not in matched_bl_ids:
error_bl.append(bl)
if error_bl:
logging.info('%s个提单无法找到release note文件' % len(error_bl))
# 英文提示
raise ValidationError(_('%s bill of loading cannot find release note file') % (
', '.join([bl.bl_no for bl in error_bl]))) # xx提单无法找到release note文件
if not self._context.get('is_skip_raise_error'):
self.show_error_message = _('%s bill of loading cannot find release note file') % (
', '.join([bl.bl_no for bl in error_bl]))
# raise ValidationError(_('%s bill of loading cannot find release note file') % (
# ', '.join([bl.bl_no for bl in error_bl]))) # xx提单无法找到release note文件
if self.remove_specified_text:
# 临时启用调试模式,查看删除位置
processed_files = self._remove_specified_text(processed_files, debug_mode=False)
......@@ -95,6 +103,15 @@ class BatchGetPodInfoWizard(models.TransientModel):
self.get_date_sync_match_node(processed_files)
end_time = time.time()
_logger.info(f"批量获取POD信息操作完成,耗时: {end_time - start_time}秒")
if self.show_error_message and not self._context.get('is_skip_raise_error'):
return {
'type': 'ir.actions.act_window',
'res_model': 'batch.get.pod.info.wizard',
'view_mode': 'form',
'res_id': self.id,
'target': 'new',
'context': {'default_show_error_message': self.show_error_message,'active_id': bl_objs.ids}
}
# 写一个方法调接口获取提单pdf文件
def _get_pdf_file_arr(self):
......@@ -183,6 +200,8 @@ class BatchGetPodInfoWizard(models.TransientModel):
bl = file_info['bl']
file_name = file_info['file_name']
file_data = file_info['file_data']
if not file_data:
continue
# 如果有文件为空的就回写,否则就创建新的清关文件记录
fix_name = '尾程交接POD(待大包数量和箱号)'
clearance_file = self.env['cc.clearance.file'].search(
......@@ -747,77 +766,6 @@ class BatchGetPodInfoWizard(models.TransientModel):
return previous_row[-1]
def _save_and_return_download_link(self, file_info):
"""
用于测试的 Save processed PDF as attachment and return download action # 保存处理后的PDF作为附件并返回下载动作
:param file_info: 处理后的文件信息
:return: Odoo action to download the file
"""
try:
# 获取处理后的PDF数据
file_data = file_info.get('file_data', '')
file_name = file_info.get('file_name', 'processed.pdf')
if not file_data:
raise ValidationError(_('No processed file data available')) # 提示:没有处理后的文件数据
# 解码base64数据
if isinstance(file_data, str):
pdf_binary = base64.b64decode(file_data)
else:
pdf_binary = file_data
# 确保PDF数据有效
if not pdf_binary.startswith(b'%PDF-'):
# 尝试修复:如果是base64字符串被错误处理
if isinstance(file_data, str) and len(file_data) > 100:
_logger.info("尝试重新解码base64数据...")
try:
# 重新尝试base64解码
pdf_binary_fixed = base64.b64decode(file_data)
if pdf_binary_fixed.startswith(b'%PDF-'):
_logger.info("✅ 重新解码成功,PDF数据有效")
pdf_binary = pdf_binary_fixed
else:
_logger.error("❌ 重新解码后仍然不是有效的PDF")
raise ValidationError(_('Invalid PDF data for saving: not a valid PDF format'))
except Exception as e:
_logger.error(f"重新解码失败: {str(e)}")
raise ValidationError(_('Invalid PDF data for saving: not a valid PDF format'))
else:
raise ValidationError(_('Invalid PDF data for saving: not a valid PDF format'))
# 验证PDF可以打开
try:
import fitz
test_doc = fitz.open(stream=pdf_binary, filetype="pdf")
_logger.info(f"PDF验证成功,页数: {len(test_doc)}")
test_doc.close()
except Exception as e:
_logger.error(f"PDF验证失败: {str(e)}")
raise ValidationError(_('Invalid PDF data for saving: cannot open PDF - %s') % str(e))
# 创建附件记录
attachment = self.env['ir.attachment'].create({
'name': f'processed_{file_name}',
'type': 'binary',
'datas': base64.b64encode(pdf_binary),
'mimetype': 'application/pdf',
'res_model': 'batch.get.pod.info.wizard',
'res_id': self.id,
})
# 返回下载动作
return {
'type': 'ir.actions.act_url',
'url': f'/web/content/{attachment.id}?download=true',
'target': 'new',
}
except Exception as e:
_logger.error(f"保存PDF附件失败: {str(e)}")
raise ValidationError(_('Failed to save PDF attachment: %s') % str(e))
def get_date_sync_match_node(self, processed_files):
"""
Sync matched node based on POD file, extract time from red boxes # 根据POD文件同步匹配节点
......@@ -849,7 +797,7 @@ class BatchGetPodInfoWizard(models.TransientModel):
# 从PDF文件提取红色框的时间
file_data = file_info.get('file_data')
if not file_data:
_logger.warning(f"提单 {bl.bl_no} 没有文件数据")
logging.info(f"提单 {bl.bl_no} 没有文件数据")
continue
try:
# 如果已识别过OCR文本,则复用
......@@ -873,7 +821,9 @@ class BatchGetPodInfoWizard(models.TransientModel):
error_bl.append(bl)
if error_bl:
_logger.warning(f"提单 {', '.join([bl.bl_no for bl in error_bl])} 没有提取到时间信息")
raise ValidationError(
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
......
......@@ -29,6 +29,9 @@
<li><strong>Sync Push Match Node:</strong> Synchronize and push matched node information based on POD file, extract time from red boxes as node operation time</li> <!-- 同步推送匹配节点:根据POD文件获取对应的清关节点,提取红色框时间作为节点操作时间 -->
</ul>
</div>
<div class="alert alert-danger" role="alert" attrs="{'invisible': [('show_error_message', '=', False)]}">
<field name="show_error_message"/>
</div>
<footer>
<button string="Confirm" type="object" name="confirm" class="btn-primary"/>
<button string="Close" special="cancel"/>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论