From 388b0b4e4c12c1f7164c3c285e38b40ca77478e6 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 9 May 2024 10:37:41 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=B6=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 3 ++ sf_manufacturing/models/mrp_workorder.py | 23 +++++++----- sf_manufacturing/models/product_template.py | 4 +- sf_mrs_connect/controllers/controllers.py | 41 ++++++++++++++------- sf_mrs_connect/models/ftp_operate.py | 18 +++++---- sf_sale/models/quick_easy_order.py | 4 +- sf_sale/models/quick_easy_order_old.py | 4 +- sf_tool_management/models/mrp_workorder.py | 2 +- 8 files changed, 62 insertions(+), 37 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index e2d6616a..8e95bf70 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -265,6 +265,7 @@ class MrpProduction(models.Model): def _create_workorder3(self): programming_no = None product_id_new = None + production_ids = [] for production in self: if not production.bom_id or not production.product_id: continue @@ -295,6 +296,8 @@ class MrpProduction(models.Model): 'state': 'pending', }] if production.product_id.categ_id.type == '成品': + if production_ids is None: + production_ids.append({production.name}) if programming_no is None: production.fetchCNC() programming_no = production.programming_no diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 590903d3..65789884 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -643,10 +643,13 @@ class ResMrpWorkOrder(models.Model): def _compute_state(self): for workorder in self: if workorder.routing_type == '装夹预调': - if not workorder.cnc_ids: + cnc_workorder = self.search( + [('production_id', '=', workorder.production_id.id), ('routing_type', '=', 'CNC加工')], + limit=1, order='id asc') + if not cnc_workorder: workorder.state = 'waiting' else: - for item in workorder.cnc_ids: + for item in cnc_workorder.cnc_ids: functional_cutting_tool = self.env['sf.functional.cutting.tool.entity'].search( [('tool_name_id.name', '=', item.cutting_tool_name)]) if not functional_cutting_tool: @@ -741,12 +744,12 @@ class ResMrpWorkOrder(models.Model): limit=1, order='id asc') if not cnc_workorder: raise UserError(_('该制造订单还未下发CNC程序,请稍后再试')) - else: - for item in cnc_workorder.cnc_ids: - functional_cutting_tool = self.env['sf.functional.cutting.tool.entity'].search( - [('tool_name_id.name', '=', item.cutting_tool_name)]) - if not functional_cutting_tool: - raise UserError(_('该制造订单的CNC程序为%s没有对应的功能刀具' % item.cutting_tool_name)) + # else: + # for item in cnc_workorder.cnc_ids: + # functional_cutting_tool = self.env['sf.functional.cutting.tool.entity'].search( + # [('tool_name_id.name', '=', item.cutting_tool_name)]) + # if not functional_cutting_tool: + # raise UserError(_('该制造订单的CNC程序为%s没有对应的功能刀具' % item.cutting_tool_name)) if self.routing_type == '解除装夹': ''' 记录开始时间 @@ -930,6 +933,7 @@ class CNCprocessing(models.Model): # mrs下发编程单创建CNC加工 def cnc_processing_create(self, cnc_workorder, ret, program_path, program_path_tmp): + cnc_processing = None for obj in ret['programming_list']: workorder = self.env['mrp.workorder'].search([('production_id.name', '=', ret['production_order_no']), ('processing_panel', '=', obj['processing_panel']), @@ -964,6 +968,7 @@ class CNCprocessing(models.Model): item.is_cnc_program_down = True if item.workorder_id.state == 'waiting': item.workorder_id.state = 'ready' + return cnc_processing # cnc_workorder.time_ids.date_end = datetime.now() # cnc_workorder.button_finish() @@ -999,7 +1004,7 @@ class CNCprocessing(models.Model): # 将FTP的nc文件下载到临时目录 def download_file_tmp(self, production_no, processing_panel): remotepath = os.path.join('/NC', production_no, 'return', processing_panel) - serverdir = os.path.join('/tmp', production_no, 'return', processing_panel) + serverdir = os.path.join('C:/Users/43484/Desktop/fsdownload/return', production_no, 'return', processing_panel) 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']) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 4d07ae1c..9b7516a5 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -7,8 +7,8 @@ import os from odoo import models, fields, api, _ from odoo.exceptions import ValidationError from odoo.modules import get_resource_path -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file class ResProductMo(models.Model): diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index 44a65200..e50ee130 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -9,7 +9,7 @@ from odoo.http import request class Sf_Mrs_Connect(http.Controller): - @http.route('/api/cnc_processing/create', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + @http.route('/api/cnc_processing/create', type='json', auth='none', methods=['GET', 'POST'], csrf=False, cors="*") def get_cnc_processing_create(self, **kw): """ @@ -27,25 +27,28 @@ class Sf_Mrs_Connect(http.Controller): # 查询状态为进行中且类型为获取CNC加工程序的工单 cnc_production = request.env['mrp.production'].with_user( request.env.ref("base.user_admin")).search([('name', '=', ret['production_order_no'])]) + cnc_program = request.env['mrp.production'].with_user( + request.env.ref("base.user_admin")).search([('programming_no', '=', cnc_production.programming_no)]) logging.info('制造订单号:%s' % cnc_production.name) if cnc_production: # if ret['glb_file']: # cnc_production.glb_file = base64.b64encode(ret['glb_file']) # 拉取所有加工面的程序文件 - # i = 1 - - for r in ret['processing_panel']: - download_state = request.env['sf.cnc.processing'].with_user( - request.env.ref("base.user_admin")).download_file_tmp( - ret['folder_name'], r) - if download_state == 0: - res['status'] = -2 - res['message'] = '制造订单号为%s的CNC程序文件从FTP拉取失败' % (cnc_production.name) - return json.JSONEncoder().encode(res) + i = 1 + # + # for r in ret['processing_panel']: + # download_state = request.env['sf.cnc.processing'].with_user( + # request.env.ref("base.user_admin")).download_file_tmp( + # ret['folder_name'], r) + # if download_state == 0: + # res['status'] = -2 + # res['message'] = '制造订单号为%s的CNC程序文件从FTP拉取失败' % (cnc_production.name) + # return json.JSONEncoder().encode(res) logging.info('创建cnc工单') - program_path_tmp = os.path.join('/tmp', ret['folder_name'], 'return', r) - # program_path_tmp = "C://Users//43484//Desktop//机企猫工作文档//其他//model_analysis" + # program_path_tmp = os.path.join('/tmp', ret['folder_name'], 'return', r) + program_path_tmp = "C://Users//43484//Desktop//机企猫工作文档//其他//model_analysis" files = os.listdir(program_path_tmp) + cnc_processing_arr = None for f in files: program_path = os.path.join(program_path_tmp, f) logging.info('cnc程序路径 :%s' % program_path) @@ -53,9 +56,19 @@ class Sf_Mrs_Connect(http.Controller): # 插入cmm程序数据 request.env['sf.cmm.program'].with_user( request.env.ref("base.user_admin")).cmm_program_create(ret, program_path, program_path_tmp) - request.env['sf.cnc.processing'].with_user( + cnc_processing = request.env['sf.cnc.processing'].with_user( request.env.ref("base.user_admin")).cnc_processing_create(cnc_production, ret, program_path, program_path_tmp) + if cnc_processing: + if cnc_processing_arr is None: + cnc_processing_arr = cnc_processing + else: + cnc_processing_arr |= cnc_processing + + if cnc_program and cnc_processing_arr: + cnc_program.workorder_ids.filtered(lambda b: b.routing_type == 'CNC加工').write( + {'cnc_ids': cnc_processing_arr}) + return json.JSONEncoder().encode(res) else: res = {'status': 0, 'message': '该制造订单暂未开始'} diff --git a/sf_mrs_connect/models/ftp_operate.py b/sf_mrs_connect/models/ftp_operate.py index 98e6d504..a1689825 100644 --- a/sf_mrs_connect/models/ftp_operate.py +++ b/sf_mrs_connect/models/ftp_operate.py @@ -40,13 +40,17 @@ class FtpController(): logging.info('目录:%s' % target_dir) target_dir1 = target_dir.split('/') logging.info('目录1:%s' % target_dir1[1]) - self.ftp.cwd(target_dir1[1]) # 切换工作路径 - logging.info('目录2:%s' % target_dir1[2]) - self.ftp.cwd(target_dir1[2]) # 切换工作路径 - logging.info('目录3:%s' % target_dir1[3]) - self.ftp.cwd(target_dir1[3]) # 切换工作路径 - logging.info('目录4:%s' % target_dir1[4]) - self.ftp.cwd(target_dir1[4]) # 切换工作路径 + self.ftp.cwd('NC') + self.ftp.cwd('XT_WH_MO_00164') + self.ftp.cwd('return') + self.ftp.cwd('R') + # self.ftp.cwd(target_dir1[1]) # 切换工作路径 + # logging.info('目录2:%s' % target_dir1[2]) + # self.ftp.cwd(target_dir1[2]) # 切换工作路径 + # logging.info('目录3:%s' % target_dir1[3]) + # self.ftp.cwd(target_dir1[3]) # 切换工作路径 + # logging.info('目录4:%s' % target_dir1[4]) + # self.ftp.cwd(target_dir1[4]) # 切换工作路径 remotenames = self.ftp.nlst() logging.info('FTP目录文件:%s' % remotenames) for file in remotenames: diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index 259655ee..775b901a 100644 --- a/sf_sale/models/quick_easy_order.py +++ b/sf_sale/models/quick_easy_order.py @@ -8,8 +8,8 @@ from datetime import datetime import requests from odoo import http from odoo.http import request -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file from odoo import models, fields, api from odoo.modules import get_resource_path from odoo.exceptions import ValidationError, UserError diff --git a/sf_sale/models/quick_easy_order_old.py b/sf_sale/models/quick_easy_order_old.py index 768c483c..241170a1 100644 --- a/sf_sale/models/quick_easy_order_old.py +++ b/sf_sale/models/quick_easy_order_old.py @@ -6,8 +6,8 @@ import os from datetime import datetime from stl import mesh # from OCC.Core.GProp import GProp_GProps -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file from odoo.addons.sf_base.commons.common import Common from odoo import models, fields, api from odoo.modules import get_resource_path diff --git a/sf_tool_management/models/mrp_workorder.py b/sf_tool_management/models/mrp_workorder.py index 44c4ef95..339d0f40 100644 --- a/sf_tool_management/models/mrp_workorder.py +++ b/sf_tool_management/models/mrp_workorder.py @@ -33,7 +33,7 @@ class CNCprocessing(models.Model): def create(self, vals): obj = super(CNCprocessing, self).create(vals) # 调用CAM工单程序用刀计划创建方法 - self.env['sf.cam.work.order.program.knife.plan'].create_cam_work_plan(obj) + # self.env['sf.cam.work.order.program.knife.plan'].create_cam_work_plan(obj) logging.info('成功调用CAM工单程序用刀计划创建方法!!!') return obj From 0ea3d6f0b360292844d676f0df2dc6f4deecdd6e Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 9 May 2024 11:04:07 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E4=BC=98=E5=8C=96agv=E6=8E=A5=E9=A9=B3?= =?UTF-8?q?=E7=AB=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/agv_setting.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sf_manufacturing/models/agv_setting.py b/sf_manufacturing/models/agv_setting.py index d0104bc3..8526627c 100644 --- a/sf_manufacturing/models/agv_setting.py +++ b/sf_manufacturing/models/agv_setting.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import requests import logging +import time from odoo import fields, models @@ -21,10 +22,15 @@ class AgvSetting(models.Model): config = self.env['res.config.settings'].get_values() # token = sf_sync_config['token'Ba F2CF5DCC-1A00-4234-9E95-65603F70CC8A] headers = {'Authorization': config['center_control_Authorization']} - center_control_url = config['center_control_url'] + "/AutoDeviceApi/GetAgvStationState" + center_control_url = config['center_control_url'] + "/AutoDeviceApi/GetAgvStationState?date=" + timestamp = int(time.time()) + center_control_url += str(timestamp) + logging.info('工件配送-请求中控地址:%s' % center_control_url) center_control_r = requests.get(center_control_url, params={}, headers=headers) ret = center_control_r.json() logging.info('工件配送-请求中控站点信息:%s' % ret) + self.env['center_control.interface.log'].sudo().create( + {'content': ret, 'name': 'AutoDeviceApi/GetAgvStationState?date=%s' % str(timestamp)}) if ret['Succeed'] is True: datas = ret['Datas'] for item in self: From 3d56e54fb22d3f3845f842ff4b581b21e2b15ce0 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 9 May 2024 18:29:30 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=B6=E9=80=A0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=9A=84=E8=8E=B7=E5=8F=96cnc=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 26 +++++++------- sf_manufacturing/models/mrp_workorder.py | 36 ++++++++++++++----- sf_manufacturing/security/ir.model.access.csv | 2 +- sf_manufacturing/views/mrp_workorder_view.xml | 24 ++++++------- sf_mrs_connect/controllers/controllers.py | 10 ++---- 5 files changed, 56 insertions(+), 42 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 8e95bf70..862397a9 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -154,7 +154,7 @@ class MrpProduction(models.Model): production.maintenance_count = len(production.request_ids) # cnc程序获取 - def fetchCNC(self): + def fetchCNC(self, production_names): cnc = self.env['mrp.production'].search([('id', '=', self.id)]) quick_order = self.env['quick.easy.order'].search( [('name', '=', cnc.product_id.default_code.rsplit('-', 1)[0])]) @@ -166,8 +166,8 @@ class MrpProduction(models.Model): if quick_order: programme_way = 'manual operation' try: - res = {'model_code': '' if not cnc.product_id.model_code else cnc.product_id.model_code, - 'production_no': cnc.name, + res = {'model_code': cnc.product_id.name, + 'production_no': production_names, 'machine_tool_code': "", 'material_code': self.env['sf.production.materials'].search( [('id', '=', cnc.product_id.materials_id.id)]).materials_no, @@ -185,7 +185,10 @@ class MrpProduction(models.Model): 'model_file': '' if not cnc.product_id.model_file else base64.b64encode( cnc.product_id.model_file).decode('utf-8') } - logging.info('res:%s' % res) + # 打印出除了 model_file 之外的所有键值对 + for key, value in res.items(): + if key != 'model_file': + logging.info('%s: %s' % (key, value)) configsettings = self.env['res.config.settings'].get_values() config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key']) url = '/api/intelligent_programming/create' @@ -263,15 +266,15 @@ class MrpProduction(models.Model): # 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心; def _create_workorder3(self): + production_names = [production.name for production in self if production.product_id.categ_id.type == '成品'] programming_no = None - product_id_new = None - production_ids = [] + product_first = None for production in self: if not production.bom_id or not production.product_id: continue workorders_values = [] - if product_id_new is None: - product_id_new = production.product_id + if product_first is None: + product_first = production.product_id product_qty = production.product_uom_id._compute_quantity(production.product_qty, production.bom_id.product_uom_id) @@ -296,16 +299,13 @@ class MrpProduction(models.Model): 'state': 'pending', }] if production.product_id.categ_id.type == '成品': - if production_ids is None: - production_ids.append({production.name}) if programming_no is None: - production.fetchCNC() + production.fetchCNC(production_names) programming_no = production.programming_no else: - if production.product_id == product_id_new: + if production.product_id == product_first: if not production.programming_no: production.write({'programming_no': programming_no, 'programming_state': '编程中'}) - # 根据加工面板的面数及对应的工序模板生成工单 i = 0 processing_panel_len = len(production.product_id.model_processing_panel.split(',')) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 73f6b940..c525f480 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -975,6 +975,23 @@ class CNCprocessing(models.Model): # cnc_workorder.time_ids.date_end = datetime.now() # cnc_workorder.button_finish() + def _json_cnc_processing(self, obj): + cnc_processing_str = [0, 0, { + 'sequence_number': obj['sequence_number'], + 'program_name': obj['program_name'], + 'cutting_tool_name': obj['cutting_tool_name'], + 'cutting_tool_no': obj['cutting_tool_no'], + 'processing_type': obj['processing_type'], + 'margin_x_y': obj['margin_x_y'], + 'margin_z': obj['margin_z'], + 'depth_of_processing_z': obj['depth_of_processing_z'], + 'cutting_tool_extension_length': obj['cutting_tool_extension_length'], + 'cutting_tool_handle_type': obj['cutting_tool_handle_type'], + 'estimated_processing_time': obj['estimated_processing_time'], + 'remark': obj['remark'] + }] + return cnc_processing_str + # 根据程序名和加工面匹配到ftp里对应的Nc程序名,可优化为根据cnc_processing.program_path进行匹配 def get_cnc_processing_file(self, serverdir, cnc_processing, program_path): logging.info('serverdir:%s' % serverdir) @@ -1228,8 +1245,8 @@ class WorkPieceDelivery(models.Model): same_route_id = item.route_id.id if item.route_id.id != same_route_id: is_not_route += 1 - else: - raise UserError('请选择【任务路线】再进行配送') + # else: + # raise UserError('请选择【任务路线】再进行配送') if production_type != item.type: raise UserError('请选择类型为%s的制造订单进行配送' % production_type) if down_status != item.status: @@ -1309,21 +1326,22 @@ class WorkPieceDelivery(models.Model): feeder_station_destination = None route_id = None for item in self: - delivery_Arr.append(item.name) + if route_id is None: + route_id = item.route_id.id + if feeder_station_start is None: + feeder_station_start = item.feeder_station_start_id.name + if feeder_station_destination is None: + feeder_station_destination = item.feeder_station_destination_id.name if item.type in ['上产线', '下产线']: - if route_id is None: - route_id = item.route_id.id - if feeder_station_start is None: - feeder_station_start = item.feeder_station_start_id.name - if feeder_station_destination is None: - feeder_station_destination = item.feeder_station_destination_id.name item.route_id = route_id + delivery_Arr.append(item.name) else: self = self.create( {'name': self.env['ir.sequence'].next_by_code('sf.workpiece.delivery'), 'route_id': self.route_id.id, 'feeder_station_start_id': self.feeder_station_start_id.id, 'feeder_station_destination_id': self.feeder_station_destination_id.id}) + delivery_Arr.append(self.name) delivery_str = ','.join(map(str, delivery_Arr)) if feeder_station_start is not None: positionCode_Arr.append({ diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv index 1798ba27..22cff848 100644 --- a/sf_manufacturing/security/ir.model.access.csv +++ b/sf_manufacturing/security/ir.model.access.csv @@ -30,7 +30,7 @@ access_mrp_workcenter_group_sf_mrp_user,mrp_workcenter,model_mrp_workcenter,sf_b access_mrp_workcenter_manager,mrp_workcenter,model_mrp_workcenter,sf_base.group_sf_mrp_manager,1,1,1,0 access_mrp_workcenter_productivity_group_sf_mrp_user,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_user,1,0,0,0 access_mrp_workcenter_productivity_manager,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_manager,1,1,1,0 -access_sf_workpiece_delivery_group_sf_order_user,sf_workpiece_delivery_group_sf_order_user,model_sf_workpiece_delivery,sf_base.group_sf_order_user,1,1,0,0 +access_sf_workpiece_delivery_group_sf_order_user,sf_workpiece_delivery_group_sf_order_user,model_sf_workpiece_delivery,sf_base.group_sf_order_user,1,1,1,0 access_sf_workpiece_delivery_group_sf_equipment_user,sf_workpiece_delivery_group_sf_equipment_user,model_sf_workpiece_delivery,sf_base.group_sf_equipment_user,1,1,0,0 access_sf_workpiece_delivery_manager,sf_workpiece_delivery,model_sf_workpiece_delivery,sf_base.group_sf_mrp_manager,1,1,0,0 diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 7fdf390d..8c9cb3db 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -144,8 +144,7 @@