Compare commits

...

2 Commits

Author SHA1 Message Date
胡尧
6c8677e9e6 修改服务地址 2025-06-05 09:40:18 +08:00
胡尧
e8a968c5a7 修改工单获取前置三元检测方法 2025-05-15 08:45:55 +08:00
4 changed files with 234 additions and 134 deletions

View File

@@ -20,6 +20,7 @@
'data/sf_work_individuation_page.xml',
'data/agv_scheduling_data.xml',
'data/product_data.xml',
'data/automation_folder_data.xml',
'security/group_security.xml',
'security/ir.model.access.csv',
'wizard/workpiece_delivery_views.xml',

View File

@@ -2,16 +2,18 @@
import logging
import json
from datetime import datetime
import base64
from odoo.addons.sf_manufacturing.models.agv_scheduling import RepeatTaskException
from odoo import http
from odoo.http import request
from odoo.exceptions import MissingError
from odoo.addons.sf_base.decorators.api_log import api_log
class Manufacturing_Connect(http.Controller):
@http.route('/AutoDeviceApi/GetWoInfo', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
@http.route('/AutoDeviceApi/GetWoInfo', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
cors="*")
@api_log('获取工单', requester='中控系统')
def get_Work_Info(self, **kw):
@@ -54,7 +56,7 @@ class Manufacturing_Connect(http.Controller):
logging.info('get_Work_Info error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/GetShiftPlan', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
@http.route('/AutoDeviceApi/GetShiftPlan', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
cors="*")
@api_log('获取日计划', requester='中控系统')
def get_ShiftPlan(self, **kw):
@@ -108,7 +110,7 @@ class Manufacturing_Connect(http.Controller):
logging.info('get_ShiftPlan error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/QcCheck', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
@http.route('/AutoDeviceApi/QcCheck', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
cors="*")
@api_log('工件预调(前置三元检测)', requester='中控系统')
def get_qcCheck(self, **kw):
@@ -704,3 +706,59 @@ class Manufacturing_Connect(http.Controller):
res = {'Succeed': False, 'ErrorCode': 202, 'Error': str(e)}
logging.info('AGVDownProduct error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/api/upload_three_check_data', type='http', auth='public', methods=['POST'], csrf=False, cros='*')
def upload_three_check_data(self):
res = {'Succeed': True, 'ErrorCode': 200, 'Messages': '上传成功'}
uploaded_files = request.httprequest.files.getlist('file')
if uploaded_files:
try:
for uploaded_file in uploaded_files:
file_content = uploaded_file.read()
file_name = uploaded_file.filename
production_name = '/'.join(file_name.split('_')[:-1])
processing_panel = file_name.split('_')[-1].split('.')[0]
# 找到对应的工单
production_id = request.env['mrp.production'].sudo().search([('name', '=', production_name)])
wo = production_id.workorder_ids.filtered(lambda wo: wo.processing_panel == processing_panel and wo.routing_type == '装夹预调')
if not wo:
raise MissingError('工单不存在')
folder_id = request.env.ref('sf_manufacturing.documents_pre_three_element_detection_folder')
document = request.env['documents.document'].sudo().search([('res_model', '=', 'mrp.workorder'), ('res_id', '=', wo.id)])
if document and document.attachment_id:
attachment = request.env['ir.attachment'].sudo().create({
'name': file_name,
'type': 'binary',
'datas': base64.b64encode(file_content),
'res_model': 'mrp.workorder',
'res_id': wo.id,
})
document.write({'attachment_id': attachment.id})
else:
# Create ir.attachment record
attachment = request.env['ir.attachment'].sudo().create({
'name': file_name,
'type': 'binary',
'datas': base64.b64encode(file_content),
'res_model': 'mrp.workorder',
'res_id': wo.id,
})
# 创建 documents.document 记录
request.env['documents.document'].sudo().create({
'name': file_name,
'attachment_id': attachment.id,
'folder_id': folder_id.id,
'res_model': 'mrp.workorder',
'res_id': wo.id,
})
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': str(e)}
return json.JSONEncoder().encode(res)

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!-- 创建自动化文件夹 -->
<record id="documents_automation_folder" model="documents.folder">
<field name="name">自动化</field>
<field name="description">存放自动化生产流程相关文件</field>
<field name="sequence">20</field>
</record>
<record id="documents_pre_three_element_detection_folder" model="documents.folder">
<field name="name">前置三元检测报告</field>
<field name="parent_folder_id" ref="documents_automation_folder"/>
<field name="sequence">1</field>
</record>
</data>
</odoo>

View File

@@ -6,6 +6,7 @@ import urllib.parse
from datetime import date
from datetime import datetime, timedelta
import requests
import tempfile
import os
import math
from lxml import etree
@@ -771,45 +772,59 @@ class ResMrpWorkOrder(models.Model):
# 获取三次元检测点数据
def get_three_check_datas(self):
ftp_resconfig = self.env['res.config.settings'].get_values()
ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']),
ftp_resconfig['ftp_user'],
ftp_resconfig['ftp_password'])
# ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']),
# ftp_resconfig['ftp_user'],
# ftp_resconfig['ftp_password'])
local_dir_path = '/ftp/before'
os.makedirs(local_dir_path, exist_ok=True)
# local_dir_path = '/ftp/before'
# os.makedirs(local_dir_path, exist_ok=True)
local_filename = self.save_name + '.xls'
local_file_path = os.path.join(local_dir_path, local_filename)
logging.info('local_file_path:%s' % local_file_path)
# remote_path = '/home/ftp/ftp_root/ThreeTest/XT/Before/' + local_filename
remote_path = '/ThreeTest/XT/Before/' + local_filename
logging.info('remote_path:%s' % remote_path)
is_get_detection_file = self.env['ir.config_parameter'].sudo().get_param('is_get_detection_file')
if not is_get_detection_file:
# local_file_path = os.path.join(local_dir_path, local_filename)
# logging.info('local_file_path:%s' % local_file_path)
# # remote_path = '/home/ftp/ftp_root/ThreeTest/XT/Before/' + local_filename
# remote_path = '/ThreeTest/XT/Before/' + local_filename
# logging.info('remote_path:%s' % remote_path)
# is_get_detection_file = self.env['ir.config_parameter'].sudo().get_param('is_get_detection_file')
# if not is_get_detection_file:
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
paload_data = {
"filename": local_filename
"filename": local_filename,
"sf_host": base_url
}
if not ftp_resconfig['get_check_file_path']:
raise UserError('请先配置获取检测报告地址')
url = ftp_resconfig['get_check_file_path'] + '/get/check/report'
response = requests.post(url, json=paload_data)
logging.info('response:%s' % response.json())
if response.json().get('detail'):
raise UserError(response.json().get('detail'))
# logging.info('response:%s' % response.json())
# if response.json().get('detail'):
# raise UserError(response.json().get('detail'))
if not ftp.file_exists(remote_path):
raise UserError(f"文件不存在: {remote_path}")
# if not ftp.file_exists(remote_path):
# raise UserError(f"文件不存在: {remote_path}")
with open(local_file_path, 'wb') as local_file:
ftp.ftp.retrbinary('RETR ' + remote_path, local_file.write)
logging.info('下载文件成功')
# 解析本地文件
# file_path = 'WH_MO_00099.xls' # 使用下载的实际文件路径
parser = etree.XMLParser(recover=True) # Using recover to handle errors
tree = etree.parse(local_file_path, parser)
# with open(local_file_path, 'wb') as local_file:
# ftp.ftp.retrbinary('RETR ' + remote_path, local_file.write)
# logging.info('下载文件成功')
document = self.env['documents.document'].sudo().search([('res_model', '=', 'mrp.workorder'), ('res_id', '=', self.id)])
if not document:
raise UserError(f"未获取到检测数据")
binary_data = base64.b64decode(document.attachment_id.datas)
# 创建临时文件保存响应内容
with tempfile.NamedTemporaryFile(delete=False, suffix='.xls') as temp_file:
temp_file.write(binary_data)
temp_file_path = temp_file.name
try:
# 使用临时文件进行解析
parser = etree.XMLParser(recover=True)
tree = etree.parse(temp_file_path, parser)
logging.info('tree:%s' % tree)
root = tree.getroot()
logging.info('root:%s' % root)
# 准备一个外部字典来存储以PT为键的坐标字典
pt_coordinates = {}
# 遍历每个工作表和行
@@ -911,6 +926,16 @@ class ResMrpWorkOrder(models.Model):
return True
except Exception as e:
logging.error('解析文件失败: %s' % str(e))
raise UserError(f'解析文件失败: {str(e)}')
finally:
# 清理临时文件
try:
os.unlink(temp_file_path)
except Exception as e:
logging.warning(f'清理临时文件失败: {str(e)}')
# ftp.download_file('three_check_datas.xls', '/home/ftpuser/three_check_datas.xls')
# ftp.close()
# data = xlrd.open_workbook('/home/ftpuser/three_check_datas.xls')