From 25dddb5b3b6a16214a965d29661cea4a6a3f9680 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Tue, 18 Jun 2024 17:35:41 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=B6=E9=80=A0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=EF=BC=9A=E7=94=9F=E6=88=90=E5=88=B6=E9=80=A0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=9A=84=E5=90=8C=E6=97=B6=E4=B8=8D=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=B7=A5=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 95d877b3..5793b806 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -208,7 +208,30 @@ class StockRule(models.Model): ''' 创建工单 ''' - productions._create_workorder() + # # productions._create_workorder() + # 根据product_id对self进行分组 + grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.productions.product_id.id)} + # 初始化一个字典来存储每个product_id对应的生产订单名称列表 + product_id_to_production_names = {} + # 对于每个product_id,获取其所有生产订单的名称 + for product_id, productions in grouped_product_ids.items(): + # 为同一个product_id创建一个生产订单名称列表 + product_id_to_production_names[product_id] = [production.name for production in productions] + for production_item in productions: + if production_item.product_id.id in product_id_to_production_names: + # # 同一个产品多个制造订单对应一个编程单和模型库 + # # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递 + if not production_item.programming_no: + production_programming = self.search( + [('product_id.id', '=', production_item.product_id.id), + ('origin', '=', production_item.origin)], + limit=1, order='id asc') + if not production_programming.programming_no: + production_item.fetchCNC( + ', '.join(product_id_to_production_names[production_item.product_id.id])) + else: + production_item.write({'programming_no': production_programming.programming_no, + 'programming_state': '编程中'}) productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ ( From c035ab8156fe7cb3385d1763b33f7a166228a503 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 19 Jun 2024 15:32:03 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=B3=A8=E9=87=8AOCC=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 4 ++-- sf_manufacturing/models/stock.py | 5 +++-- sf_sale/models/quick_easy_order.py | 4 ++-- sf_sale/models/quick_easy_order_old.py | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index cea53c64..71522528 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_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 5793b806..a454fb51 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import base64 import qrcode +from itertools import groupby from collections import defaultdict, namedtuple import logging import io @@ -208,8 +209,8 @@ class StockRule(models.Model): ''' 创建工单 ''' - # # productions._create_workorder() - # 根据product_id对self进行分组 + # productions._create_workorder() + 根据product_id对self进行分组 grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.productions.product_id.id)} # 初始化一个字典来存储每个product_id对应的生产订单名称列表 product_id_to_production_names = {} diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index e3bf3002..11acc06f 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 3ae65db3..92f6cda2 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 From b3907123085ed24d50d595d8f46e3876c7dbffb8 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 19 Jun 2024 15:39:28 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BC=96=E7=A8=8B?= =?UTF-8?q?=E5=8D=95=E4=B8=8B=E5=8F=91=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_mrs_connect/controllers/controllers.py | 43 ++++++++++++----------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index 78a0c05a..08021b5f 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -47,28 +47,31 @@ class Sf_Mrs_Connect(http.Controller): # if ret['glb_file']: # cnc_production.glb_file = base64.b64encode(ret['glb_file']) # 拉取所有加工面的程序文件 - if is_delete_file is True: - program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', 'R') - files_r = os.listdir(program_path_tmp_r) - if files_r: - for file_name in files_r: - file_path = os.path.join(program_path_tmp_r, file_name) - os.remove(file_path) - 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) + # for r in ret['processing_panel'].split(','): + # if is_delete_file is True: + # program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r) + # files_r = os.listdir(program_path_tmp_r) + # if files_r: + # for file_name in files_r: + # file_path = os.path.join(program_path_tmp_r, file_name) + # os.remove(file_path) + # 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" - files = os.listdir(program_path_tmp) cnc_processing_arr = [] - for f in files: - program_path = os.path.join(program_path_tmp, f) + cmm_program_arr = [] + for panel in ret['processing_panel'].split(','): + program_path_tmp = os.path.join('/tmp', ret['folder_name'], 'return', panel) + # program_path_tmp = "C://Users//43484//Desktop//机企猫工作文档//其他//model_analysis" + files = os.listdir(program_path_tmp) + cnc_processing_arr = [] + for f in files: + program_path = os.path.join(program_path_tmp, f) logging.info('cnc程序路径 :%s' % program_path) if f.endswith(".doc"): # 插入cmm程序数据 From 67b48814f6b5d146a88e11fab639352871556fa4 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 19 Jun 2024 17:35:13 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=B6=E9=80=A0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E5=92=8C=E7=94=9F=E6=88=90=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_machine_connect/views/default_delivery.xml | 1 - sf_manufacturing/models/mrp_production.py | 27 +--- sf_manufacturing/models/mrp_workorder.py | 120 +++++------------- sf_manufacturing/models/stock.py | 30 ++--- sf_manufacturing/views/mrp_workorder_view.xml | 13 +- sf_mrs_connect/controllers/controllers.py | 48 ++++--- 6 files changed, 87 insertions(+), 152 deletions(-) diff --git a/sf_machine_connect/views/default_delivery.xml b/sf_machine_connect/views/default_delivery.xml index b0890981..0238c736 100644 --- a/sf_machine_connect/views/default_delivery.xml +++ b/sf_machine_connect/views/default_delivery.xml @@ -9,7 +9,6 @@ - diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 32124b28..7c5c37bc 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -292,7 +292,7 @@ class MrpProduction(models.Model): # 则根据设备找到工作中心;否则采用前面描述的工作中心分配机制; # 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心; - def _create_workorder3(self): + def _create_workorder3(self, item): # 根据product_id对self进行分组 grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.product_id.id)} # 初始化一个字典来存储每个product_id对应的生产订单名称列表 @@ -328,19 +328,6 @@ class MrpProduction(models.Model): 'state': 'pending', }] if production.product_id.categ_id.type == '成品': - if production.product_id.id in product_id_to_production_names: - # # 同一个产品多个制造订单对应一个编程单和模型库 - # # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递 - if not production.programming_no: - production_programming = self.search( - [('product_id.id', '=', production.product_id.id), ('origin', '=', production.origin)], - limit=1, order='id asc') - if not production_programming.programming_no: - production.fetchCNC(', '.join(product_id_to_production_names[production.product_id.id])) - else: - production.write({'programming_no': production_programming.programming_no, - 'programming_state': '编程中'}) - # # 根据加工面板的面数及对应的工序模板生成工单 i = 0 processing_panel_len = len(production.product_id.model_processing_panel.split(',')) @@ -353,10 +340,10 @@ class MrpProduction(models.Model): for route in product_routing_workcenter: if route.is_repeat is True: workorders_values.append( - self.env['mrp.workorder'].json_workorder_str(k, production, route)) - if i == processing_panel_len and route.routing_type == '解除装夹': - workorders_values.append( - self.env['mrp.workorder'].json_workorder_str(k, production, route)) + self.env['mrp.workorder'].json_workorder_str(k, production, route, item)) + # if i == processing_panel_len and route.routing_type == '解除装夹': + # workorders_values.append( + # self.env['mrp.workorder'].json_workorder_str(k, production, route)) # 表面工艺工序 # 获取表面工艺id if production.product_id.model_process_parameters_ids: @@ -546,8 +533,8 @@ class MrpProduction(models.Model): # work.button_finish() # 创建工单并进行排序 - def _create_workorder(self): - self._create_workorder3() + def _create_workorder(self, item): + self._create_workorder3(item) self._reset_work_order_sequence() return True diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 401788af..cd704eb0 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -472,7 +472,7 @@ class ResMrpWorkOrder(models.Model): raise UserError(_("该工单暂未完成,无法进行工件配送")) # 拼接工单对象属性值 - def json_workorder_str(self, k, production, route): + def json_workorder_str(self, k, production, route, item): # 计算预计时长duration_expected if route.routing_type == '切割': duration_expected = self.env['mrp.routing.workcenter'].sudo().search( @@ -514,6 +514,10 @@ class ResMrpWorkOrder(models.Model): 'date_planned_finished': datetime.now() + timedelta(days=1), 'duration_expected': duration_expected, 'duration': 0, + 'cnc_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cnc.processing']._json_cnc_processing( + k, item), + 'cmc_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cmm.program']._json_cmm_program(k, + item), 'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list( production) }] @@ -1094,7 +1098,7 @@ class CNCprocessing(models.Model): _rec_name = 'program_name' _order = 'sequence_number,id' - cnc_id = fields.Many2one('ir.attachment') + # cnc_id = fields.Many2one('ir.attachment') sequence_number = fields.Integer('序号') program_name = fields.Char('程序名') functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型') @@ -1144,24 +1148,26 @@ class CNCprocessing(models.Model): cnc_workorder.write({'programming_state': '已编程', 'work_state': '已编程'}) return cnc_processing - 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'], - 'program_path': obj['program_path'], - 'cnc_id': obj['cnc_id'].id, - 'remark': obj['remark'] - }) - return cnc_processing_str + def _json_cnc_processing(self, panel, ret): + cnc_processing = [] + for item in ret['programming_list']: + if item['processing_panel'] == panel: + cnc_processing.append(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'], + 'program_path': obj['program_path'], + 'remark': obj['remark'] + }) + return cnc_processing # 根据程序名和加工面匹配到ftp里对应的Nc程序名,可优化为根据cnc_processing.program_path进行匹配 def get_cnc_processing_file(self, serverdir, cnc_processing, program_path): @@ -1602,80 +1608,22 @@ class CMMprogram(models.Model): _name = 'sf.cmm.program' _description = "CMM程序" - cmm_id = fields.Many2one('ir.attachment') sequence_number = fields.Integer('序号') program_name = fields.Char('程序名') - cutting_tool_name = fields.Char('刀具名称') - cutting_tool_no = fields.Char('刀号') - processing_type = fields.Char('加工类型') - margin_x_y = fields.Char('余量_X/Y') - margin_z = fields.Char('余量_Z') - depth_of_processing_z = fields.Char('加工深度(Z)') - cutting_tool_extension_length = fields.Char('刀具伸出长度') - cutting_tool_handle_type = fields.Char('刀柄型号') - estimated_processing_time = fields.Char('预计加工时间') remark = fields.Text('备注') workorder_id = fields.Many2one('mrp.workorder', string="工单") production_id = fields.Many2one('mrp.production', string="制造订单") program_path = fields.Char('程序文件路径') + program_create_date = fields.Datetime('程序创建日期') - def cmm_program_create(self, ret, program_path, program_path_tmp): - cmm_program = None - for obj in ret['programming_list']: - workorder = self.env['mrp.workorder'].search( - [('production_id.name', '=', ret['production_order_no'].split(',')[0]), - ('processing_panel', '=', obj['processing_panel']), - ('routing_type', '=', 'CNC加工')]) - if obj['program_name'] in program_path: - logging.info('obj:%s' % obj['program_name']) - cmm_program = self.sudo().create({ - 'workorder_id': workorder.id, + def _json_cmm_program(self, panel, ret): + cmm_program = [] + for item in ret['programming_list']: + if item['processing_panel'] == panel: + cmm_program.append(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'], - 'program_path': program_path.replace('/tmp', '') + 'program_path': obj['program_path'], + 'program_create_date': obj['program_create_date'] }) - cmm_program.get_cmm_program_file(program_path_tmp, cmm_program, program_path) return cmm_program - - # 根据程序名和加工面匹配到ftp里对应的cmm程序名 - def get_cmm_program_file(self, serverdir, cmm_program, program_path): - logging.info('cmm-serverdir:%s' % serverdir) - for root, dirs, files in os.walk(serverdir): - for f in files: - if f in program_path: - cmm_program_file_path = os.path.join(serverdir, root, f) - self.write_file_cmm(cmm_program_file_path, cmm_program) - - # 创建附件(nc文件) - def attachment_create(self, name, data): - attachment = self.env['ir.attachment'].create({ - 'datas': base64.b64encode(data), - 'type': 'binary', - 'public': True, - 'description': '程序文件', - 'name': name - }) - return attachment - - # 将cmm文件存到attach的datas里 - def write_file_cmm(self, cmm_file_path, cnc): - cmm_file_name = cmm_file_path.split('/') - logging.info('cmm_file_name:%s' % cmm_file_name[-1]) - if os.path.exists(cmm_file_path): - with open(cmm_file_path, 'rb') as file: - data_bytes = file.read() - attachment = self.attachment_create(cnc.program_name + cmm_file_name[-1], data_bytes) - cnc.write({'cmm_id': attachment.id}) - file.close() - else: - return False diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index a454fb51..6d6d8158 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -210,7 +210,7 @@ class StockRule(models.Model): 创建工单 ''' # productions._create_workorder() - 根据product_id对self进行分组 + # 根据product_id对self进行分组 grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.productions.product_id.id)} # 初始化一个字典来存储每个product_id对应的生产订单名称列表 product_id_to_production_names = {} @@ -219,20 +219,20 @@ class StockRule(models.Model): # 为同一个product_id创建一个生产订单名称列表 product_id_to_production_names[product_id] = [production.name for production in productions] for production_item in productions: - if production_item.product_id.id in product_id_to_production_names: - # # 同一个产品多个制造订单对应一个编程单和模型库 - # # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递 - if not production_item.programming_no: - production_programming = self.search( - [('product_id.id', '=', production_item.product_id.id), - ('origin', '=', production_item.origin)], - limit=1, order='id asc') - if not production_programming.programming_no: - production_item.fetchCNC( - ', '.join(product_id_to_production_names[production_item.product_id.id])) - else: - production_item.write({'programming_no': production_programming.programming_no, - 'programming_state': '编程中'}) + # if production_item.product_id.id in product_id_to_production_names: + # # 同一个产品多个制造订单对应一个编程单和模型库 + # # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递 + if not production_item.programming_no: + production_programming = self.env['mrp.production'].search( + [('product_id.id', '=', production_item.product_id.id), + ('origin', '=', production_item.origin)], + limit=1, order='id asc') + if not production_programming.programming_no: + production_item.fetchCNC( + ', '.join(product_id_to_production_names[production_item.product_id.id])) + else: + production_item.write({'programming_no': production_programming.programming_no, + 'programming_state': '编程中'}) productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ ( diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index a5d902bf..7e6673ab 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -504,7 +504,6 @@ - @@ -527,16 +526,8 @@ - - - - - - - - - - + + diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index 08021b5f..0208b779 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -24,6 +24,7 @@ class Sf_Mrs_Connect(http.Controller): ret = json.loads(datas) ret = json.loads(ret['result']) logging.info('下发编程单:%s' % ret) + all_production = None is_delete_file = False # 查询状态为进行中且类型为获取CNC加工程序的工单 cnc_production = request.env['mrp.production'].with_user( @@ -83,26 +84,35 @@ class Sf_Mrs_Connect(http.Controller): logging.info('cnc_processing111:%s' % cnc_processing) if cnc_processing: cnc_processing_arr.append(cnc_processing._json_cnc_processing(cnc_processing)) + if (cnc_program and cnc_processing_arr) or (not cnc_program and cnc_processing_arr): - cnc_production.workorder_ids.filtered(lambda g: g.routing_type == '装夹预调').write( - {'processing_drawing': cnc_production.workorder_ids.filtered( - lambda g1: g1.routing_type == 'CNC加工').cnc_worksheet}) - if cnc_program and cnc_processing_arr: - cnc_program.write({'programming_state': '已编程', 'work_state': '已编程'}) - cnc_program.workorder_ids.filtered(lambda d: d.routing_type == '装夹预调').write( - {'processing_drawing': cnc_production.workorder_ids.filtered( - lambda d1: d1.routing_type == 'CNC加工').cnc_worksheet}) - cnc_program.workorder_ids.filtered(lambda b: b.routing_type == 'CNC加工').write( - {'cnc_ids': cnc_processing_arr, 'cnc_worksheet': cnc_production.workorder_ids.filtered( - lambda b1: b1.routing_type == 'CNC加工').cnc_worksheet}) - cnc_program |= cnc_production - if not cnc_program and cnc_processing_arr: - cnc_program = cnc_production - cnc_program_ids = [item.id for item in cnc_program] - workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( - [('production_id', 'in', cnc_program_ids)]) - if workpiece_delivery: - workpiece_delivery.write({'is_cnc_program_down': True}) + productions = request.env['mrp.production'].with_user( + request.env.ref("base.user_admin")).search( + [('programming_no', '=', cnc_production.programming_no)]) + if productions: + if not productions.workorder_ids: + productions.product_id.model_processing_panel = ret['processing_panel'] + productions._create_workorder(ret) + # cnc_workorder = productions.workorder_ids.filtered(lambda g: g.routing_type == '装夹预调') + # cnc_production.workorder_ids.filtered(lambda g: g.routing_type == '装夹预调').write( + # {'processing_drawing': cnc_production.workorder_ids.filtered( + # lambda g1: g1.routing_type == 'CNC加工').cnc_worksheet}) + # if cnc_program and cnc_processing_arr: + # cnc_program.write({'programming_state': '已编程', 'work_state': '已编程'}) + # cnc_program.workorder_ids.filtered(lambda d: d.routing_type == '装夹预调').write( + # {'processing_drawing': cnc_production.workorder_ids.filtered( + # lambda d1: d1.routing_type == 'CNC加工').cnc_worksheet}) + # cnc_program.workorder_ids.filtered(lambda b: b.routing_type == 'CNC加工').write( + # {'cnc_ids': cnc_processing_arr, 'cnc_worksheet': cnc_production.workorder_ids.filtered( + # lambda b1: b1.routing_type == 'CNC加工').cnc_worksheet}) + # cnc_program |= cnc_production + # if not cnc_program and cnc_processing_arr: + # cnc_program = cnc_production + # cnc_program_ids = [item.id for item in cnc_program] + # workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( + # [('production_id', 'in', cnc_program_ids)]) + # if workpiece_delivery: + # workpiece_delivery.write({'is_cnc_program_down': True}) return json.JSONEncoder().encode(res) else: res = {'status': 0, 'message': '该制造订单暂未开始'} From 612906e01da2f50126d62c9aed345a0cc017696a Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 21 Jun 2024 16:00:04 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E5=A4=9A=E9=9D=A2=E7=94=9F=E6=88=90=E5=B7=A5=E5=8D=95=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 46 ++++++ sf_manufacturing/models/mrp_workorder.py | 58 +++---- sf_manufacturing/models/stock.py | 46 ------ sf_manufacturing/security/ir.model.access.csv | 3 +- sf_mrs_connect/controllers/controllers.py | 146 +++++++----------- sf_plan/models/custom_plan.py | 45 +++--- 6 files changed, 161 insertions(+), 183 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 7c5c37bc..aa1ffae0 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -391,6 +391,52 @@ class MrpProduction(models.Model): workorders_values.append( self.env['mrp.workorder'].json_workorder_str('', production, route)) production.workorder_ids = workorders_values + # for production_item in productions: + process_parameter_workorder = self.env['mrp.workorder'].search( + [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id), + ('is_subcontract', '=', True)]) + if process_parameter_workorder: + is_pick = False + consecutive_workorders = [] + m = 0 + sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id) + for i in range(len(sorted_workorders) - 1): + if m == 0: + is_pick = False + if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \ + sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \ + sorted_workorders[i].id == sorted_workorders[i + 1].id - 1: + if sorted_workorders[i] not in consecutive_workorders: + consecutive_workorders.append(sorted_workorders[i]) + consecutive_workorders.append(sorted_workorders[i + 1]) + m += 1 + continue + else: + if m == len(consecutive_workorders) - 1 and m != 0: + self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, + production_item) + if sorted_workorders[i] in consecutive_workorders: + is_pick = True + consecutive_workorders = [] + m = 0 + # 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单 + if is_pick is False: + self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], + production_item) + if m == len(consecutive_workorders) - 1 and m != 0: + self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, + production_item) + if sorted_workorders[i] in consecutive_workorders: + is_pick = True + consecutive_workorders = [] + m = 0 + if m == len(consecutive_workorders) - 1 and m != 0: + self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production_item) + if is_pick is False and m == 0: + if len(sorted_workorders) == 1: + self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production_item) + else: + self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production_item) for workorder in production.workorder_ids: workorder.duration_expected = workorder._get_duration_expected() diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index cd704eb0..248e49ce 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -505,7 +505,7 @@ class ResMrpWorkOrder(models.Model): 'processing_panel': k, 'quality_point_ids': route.route_workcenter_id.quality_point_ids, 'routing_type': route.routing_type, - 'work_state': '待发起', + # 'work_state': '待发起', 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids, route.routing_type, production.product_id), @@ -516,7 +516,7 @@ class ResMrpWorkOrder(models.Model): 'duration': 0, 'cnc_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cnc.processing']._json_cnc_processing( k, item), - 'cmc_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cmm.program']._json_cmm_program(k, + 'cmm_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cmm.program']._json_cmm_program(k, item), 'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list( production) @@ -1098,7 +1098,7 @@ class CNCprocessing(models.Model): _rec_name = 'program_name' _order = 'sequence_number,id' - # cnc_id = fields.Many2one('ir.attachment') + cnc_id = fields.Many2one('ir.attachment') sequence_number = fields.Integer('序号') program_name = fields.Char('程序名') functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型') @@ -1116,6 +1116,7 @@ class CNCprocessing(models.Model): production_id = fields.Many2one('mrp.production', string="制造订单") button_state = fields.Boolean(string='是否已经下发') program_path = fields.Char('程序文件路径') + program_create_date = fields.Datetime('程序创建日期') # mrs下发编程单创建CNC加工 def cnc_processing_create(self, cnc_workorder, ret, program_path, program_path_tmp): @@ -1151,22 +1152,23 @@ class CNCprocessing(models.Model): def _json_cnc_processing(self, panel, ret): cnc_processing = [] for item in ret['programming_list']: - if item['processing_panel'] == panel: - cnc_processing.append(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'], - 'program_path': obj['program_path'], - 'remark': obj['remark'] - }) + if item['processing_panel'] == panel and item['ftp_path'].find('.dmi') == -1: + cnc_processing.append((0, 0, { + 'sequence_number': item['sequence_number'], + 'program_name': item['program_name'], + 'cutting_tool_name': item['cutting_tool_name'], + 'cutting_tool_no': item['cutting_tool_no'], + 'processing_type': item['processing_type'], + 'margin_x_y': item['margin_x_y'], + 'margin_z': item['margin_z'], + 'depth_of_processing_z': item['depth_of_processing_z'], + 'cutting_tool_extension_length': item['cutting_tool_extension_length'], + 'cutting_tool_handle_type': item['cutting_tool_handle_type'], + 'estimated_processing_time': item['estimated_processing_time'], + 'program_path': item['ftp_path'], + 'program_create_date': datetime.strptime(item['program_create_date'], '%Y-%m-%d %H:%M:%S'), + 'remark': item['remark'] + })) return cnc_processing # 根据程序名和加工面匹配到ftp里对应的Nc程序名,可优化为根据cnc_processing.program_path进行匹配 @@ -1197,14 +1199,14 @@ class CNCprocessing(models.Model): }) return attachment - # 将FTP的nc文件下载到临时目录 + # 将FTP的多面的程序单文件下载到临时目录 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) 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']) - download_state = ftp.download_file_tree(remotepath, serverdir) + download_state = ftp.download_program_file(remotepath, serverdir) logging.info('download_state:%s' % download_state) return download_state @@ -1619,11 +1621,11 @@ class CMMprogram(models.Model): def _json_cmm_program(self, panel, ret): cmm_program = [] for item in ret['programming_list']: - if item['processing_panel'] == panel: - cmm_program.append(0, 0, { - 'sequence_number': obj['sequence_number'], - 'program_name': obj['program_name'], - 'program_path': obj['program_path'], - 'program_create_date': obj['program_create_date'] - }) + if item['processing_panel'] == panel and item['ftp_path'].find('.dmi') != -1: + cmm_program.append((0, 0, { + 'sequence_number': 1, + 'program_name': item['program_name'], + 'program_path': item['ftp_path'], + 'program_create_date': datetime.strptime(item['program_create_date'], '%Y-%m-%d %H:%M:%S'), + })) return cmm_program diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 6d6d8158..6d83c011 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -238,52 +238,6 @@ class StockRule(models.Model): ( p.move_dest_ids.procure_method != 'make_to_order' and not p.move_raw_ids and not p.workorder_ids)).action_confirm() - for production_item in productions: - process_parameter_workorder = self.env['mrp.workorder'].search( - [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_item.id), - ('is_subcontract', '=', True)]) - if process_parameter_workorder: - is_pick = False - consecutive_workorders = [] - m = 0 - sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id) - for i in range(len(sorted_workorders) - 1): - if m == 0: - is_pick = False - if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \ - sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \ - sorted_workorders[i].id == sorted_workorders[i + 1].id - 1: - if sorted_workorders[i] not in consecutive_workorders: - consecutive_workorders.append(sorted_workorders[i]) - consecutive_workorders.append(sorted_workorders[i + 1]) - m += 1 - continue - else: - if m == len(consecutive_workorders) - 1 and m != 0: - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, - production_item) - if sorted_workorders[i] in consecutive_workorders: - is_pick = True - consecutive_workorders = [] - m = 0 - # 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单 - if is_pick is False: - self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], - production_item) - if m == len(consecutive_workorders) - 1 and m != 0: - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, - production_item) - if sorted_workorders[i] in consecutive_workorders: - is_pick = True - consecutive_workorders = [] - m = 0 - if m == len(consecutive_workorders) - 1 and m != 0: - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production_item) - if is_pick is False and m == 0: - if len(sorted_workorders) == 1: - self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production_item) - else: - self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production_item) for production in productions: ''' diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv index 3b75f102..72c211ea 100644 --- a/sf_manufacturing/security/ir.model.access.csv +++ b/sf_manufacturing/security/ir.model.access.csv @@ -1,8 +1,9 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_sf_cnc_processing_group_sf_mrp_user,sf_cnc_processing,model_sf_cnc_processing,sf_base.group_sf_mrp_user,1,0,0,0 access_sf_cnc_processing_manager,sf_cnc_processing,model_sf_cnc_processing,sf_base.group_sf_mrp_manager,1,1,1,0 -access_sf_cmm_program_group_sf_mrp_user_group_sf_mrp_user,sf_cmm_program_group_sf_mrp_user,model_sf_cmm_program,sf_base.group_sf_mrp_user,1,0,0,0 +access_sf_cmm_program_group_sf_mrp_user,sf_cmm_program_group_sf_mrp_user,model_sf_cmm_program,sf_base.group_sf_mrp_user,1,0,0,0 access_sf_cmm_program_group_sf_mrp_manager,sf_cmm_program_group_sf_mrp_manager,model_sf_cmm_program,sf_base.group_sf_mrp_manager,1,0,0,0 +access_sf_cmm_program_admin,sf_cmm_program_admin,model_sf_cmm_program,base.group_system,1,1,1,0 access_sf_model_type_group_sf_mrp_user,sf_model_type,model_sf_model_type,sf_base.group_sf_mrp_user,1,0,0,0 access_sf_model_type_admin,sf_model_type_admin,model_sf_model_type,base.group_system,1,1,1,0 access_sf_model_type_manager,sf_model_type,model_sf_model_type,sf_base.group_sf_mrp_manager,1,1,1,0 diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index 0208b779..35e9a32c 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -24,95 +24,69 @@ class Sf_Mrs_Connect(http.Controller): ret = json.loads(datas) ret = json.loads(ret['result']) logging.info('下发编程单:%s' % ret) - all_production = None is_delete_file = False - # 查询状态为进行中且类型为获取CNC加工程序的工单 - cnc_production = request.env['mrp.production'].with_user( - request.env.ref("base.user_admin")).search([('name', '=', ret['production_order_no'].split(',')[0])]) - cnc_program = request.env['mrp.production'].with_user( + productions = request.env['mrp.production'].with_user( request.env.ref("base.user_admin")).search( - [('programming_no', '=', cnc_production.programming_no), ('id', '!=', cnc_production.id)]) - if cnc_production.workorder_ids.filtered(lambda a: a.routing_type == 'CNC加工').cnc_ids: - is_delete_file = True - cnc_production.workorder_ids.filtered( - lambda a1: a1.routing_type == 'CNC加工').cnc_ids.sudo().unlink() - request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(cnc_production) - if cnc_program.workorder_ids.filtered(lambda c: c.routing_type == 'CNC加工').cnc_ids: - cnc_program.workorder_ids.filtered( - lambda c1: c1.routing_type == 'CNC加工').cnc_ids.sudo().unlink() - request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(cnc_program) - # 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']) + [('programming_no', '=', ret['programming_no'])]) + if productions: # 拉取所有加工面的程序文件 - # for r in ret['processing_panel'].split(','): - # if is_delete_file is True: - # program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r) - # files_r = os.listdir(program_path_tmp_r) - # if files_r: - # for file_name in files_r: - # file_path = os.path.join(program_path_tmp_r, file_name) - # os.remove(file_path) - # 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工单') - cnc_processing_arr = [] - cmm_program_arr = [] - for panel in ret['processing_panel'].split(','): - program_path_tmp = os.path.join('/tmp', ret['folder_name'], 'return', panel) - # program_path_tmp = "C://Users//43484//Desktop//机企猫工作文档//其他//model_analysis" - files = os.listdir(program_path_tmp) - cnc_processing_arr = [] - for f in files: - program_path = os.path.join(program_path_tmp, f) - logging.info('cnc程序路径 :%s' % program_path) - if f.endswith(".doc"): - # 插入cmm程序数据 - cmm_program = request.env['sf.cmm.program'].with_user( - request.env.ref("base.user_admin")).cmm_program_create(ret, program_path, program_path_tmp) - 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) - logging.info('cnc_processing111:%s' % cnc_processing) - if cnc_processing: - cnc_processing_arr.append(cnc_processing._json_cnc_processing(cnc_processing)) - - if (cnc_program and cnc_processing_arr) or (not cnc_program and cnc_processing_arr): - productions = request.env['mrp.production'].with_user( - request.env.ref("base.user_admin")).search( - [('programming_no', '=', cnc_production.programming_no)]) - if productions: - if not productions.workorder_ids: - productions.product_id.model_processing_panel = ret['processing_panel'] - productions._create_workorder(ret) - # cnc_workorder = productions.workorder_ids.filtered(lambda g: g.routing_type == '装夹预调') - # cnc_production.workorder_ids.filtered(lambda g: g.routing_type == '装夹预调').write( - # {'processing_drawing': cnc_production.workorder_ids.filtered( - # lambda g1: g1.routing_type == 'CNC加工').cnc_worksheet}) - # if cnc_program and cnc_processing_arr: - # cnc_program.write({'programming_state': '已编程', 'work_state': '已编程'}) - # cnc_program.workorder_ids.filtered(lambda d: d.routing_type == '装夹预调').write( - # {'processing_drawing': cnc_production.workorder_ids.filtered( - # lambda d1: d1.routing_type == 'CNC加工').cnc_worksheet}) - # cnc_program.workorder_ids.filtered(lambda b: b.routing_type == 'CNC加工').write( - # {'cnc_ids': cnc_processing_arr, 'cnc_worksheet': cnc_production.workorder_ids.filtered( - # lambda b1: b1.routing_type == 'CNC加工').cnc_worksheet}) - # cnc_program |= cnc_production - # if not cnc_program and cnc_processing_arr: - # cnc_program = cnc_production - # cnc_program_ids = [item.id for item in cnc_program] - # workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( - # [('production_id', 'in', cnc_program_ids)]) - # if workpiece_delivery: - # workpiece_delivery.write({'is_cnc_program_down': True}) + for r in ret['processing_panel'].split(','): + if is_delete_file is True: + program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r) + files_r = os.listdir(program_path_tmp_r) + if files_r: + for file_name in files_r: + file_path = os.path.join(program_path_tmp_r, file_name) + os.remove(file_path) + 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) + for production in productions: + if not production.workorder_ids: + production.product_id.model_processing_panel = ret['processing_panel'] + production._create_workorder(ret) + else: + for panel in ret['processing_panel'].split(','): + # 查询状态为进行中且工序类型为CNC加工的工单 + cnc_workorder = production.workorder_ids.filtered( + lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done', + 'cancel'] and ac.processing_panel == panel) + if cnc_workorder: + if is_delete_file is True: + cnc_workorder.cmm_ids.sudo().unlink() + cnc_workorder.cnc_ids.sudo().unlink() + request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan( + production) + program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel) + logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel) + files_panel = os.listdir(program_path_tmp_panel) + if files_panel: + for file in files_panel: + file_extension = os.path.splitext(file)[1] + logging.info('file_extension:%s' % file_extension) + if file_extension.lower() == '.pdf': + panel_file_path = os.path.join(program_path_tmp_panel, file) + logging.info('panel_file_path:%s' % panel_file_path) + cnc_workorder.write( + {'cnc_ids': cnc_workorder.cnc_ids.sudo()._json_cnc_processing(panel, ret), + 'cmm_ids': cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel, ret), + 'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())}) + pre_workorder = production.workorder_ids.filtered( + lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done', + 'cancel'] and ap.processing_panel == panel) + if pre_workorder: + pre_workorder.write( + {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())}) + productions.write({'programming_state': '已编程', 'work_state': '已编程'}) + cnc_program_ids = [item.id for item in productions] + workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( + [('production_id', 'in', cnc_program_ids)]) + if workpiece_delivery: + workpiece_delivery.write({'is_cnc_program_down': True}) return json.JSONEncoder().encode(res) else: res = {'status': 0, 'message': '该制造订单暂未开始'} diff --git a/sf_plan/models/custom_plan.py b/sf_plan/models/custom_plan.py index fd1e231a..fcfb8020 100644 --- a/sf_plan/models/custom_plan.py +++ b/sf_plan/models/custom_plan.py @@ -200,22 +200,23 @@ class sf_production_plan(models.Model): raise ValidationError("未选择生产线") else: workorder_id_list = record.production_id.workorder_ids.ids - if record.production_id.workorder_ids: - for item in record.production_id.workorder_ids: - if item.name == 'CNC加工': - item.date_planned_finished = datetime.now() + timedelta(days=100) - # item.date_planned_start = record.date_planned_start - item.date_planned_start = self.date_planned_start if self.date_planned_start else datetime.now() - record.sudo().production_id.plan_start_processing_time = item.date_planned_start - item.date_planned_finished = item.date_planned_start + timedelta( - minutes=record.env['mrp.routing.workcenter'].sudo().search( - [('name', '=', 'CNC加工')]).time_cycle) - item.duration_expected = record.env['mrp.routing.workcenter'].sudo().search( - [('name', '=', 'CNC加工')]).time_cycle - record.calculate_plan_time_before(item, workorder_id_list) - record.calculate_plan_time_after(item, workorder_id_list) - record.date_planned_start, record.date_planned_finished = \ - item.date_planned_start, item.date_planned_finished + if record.production_id: + if record.production_id.workorder_ids: + for item in record.production_id.workorder_ids: + if item.name == 'CNC加工': + item.date_planned_finished = datetime.now() + timedelta(days=100) + # item.date_planned_start = record.date_planned_start + item.date_planned_start = self.date_planned_start if self.date_planned_start else datetime.now() + record.sudo().production_id.plan_start_processing_time = item.date_planned_start + item.date_planned_finished = item.date_planned_start + timedelta( + minutes=record.env['mrp.routing.workcenter'].sudo().search( + [('name', '=', 'CNC加工')]).time_cycle) + item.duration_expected = record.env['mrp.routing.workcenter'].sudo().search( + [('name', '=', 'CNC加工')]).time_cycle + record.calculate_plan_time_before(item, workorder_id_list) + record.calculate_plan_time_after(item, workorder_id_list) + record.date_planned_start, record.date_planned_finished = \ + item.date_planned_start, item.date_planned_finished record.state = 'done' # record.production_id.schedule_state = '已排' record.sudo().production_id.schedule_state = '已排' @@ -231,12 +232,12 @@ class sf_production_plan(models.Model): # record.production_id.date_planned_start = record.date_planned_start # record.production_id.date_planned_finished = record.date_planned_finished record.sudo().production_id.production_line_id = record.production_line_id.id - record.sudo().production_id.workorder_ids.filtered( - lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write( - {'production_line_id': record.production_line_id.id, - 'plan_start_processing_time': record.date_planned_start}) - else: - raise ValidationError("未找到工单") + if record.production_id.workorder_ids: + record.sudo().production_id.workorder_ids.filtered( + lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write( + {'production_line_id': record.production_line_id.id, + 'plan_start_processing_time': record.date_planned_start}) + # record.date_planned_finished = record.date_planned_start + timedelta(days=3) # record.state = 'done' return { From 66b66a935fc9fdc140d2ea1cbc488ac89ebde88c Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 21 Jun 2024 17:15:05 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=92=8C=E4=B8=8B=E5=8F=91=E7=BC=96=E7=A8=8B?= =?UTF-8?q?=E5=8D=95=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_machine_connect/views/compensation.xml | 38 +++++++++---------- sf_manufacturing/security/ir.model.access.csv | 2 +- sf_manufacturing/views/mrp_workorder_view.xml | 19 ++++++---- sf_mrs_connect/controllers/controllers.py | 32 ++++++++-------- 4 files changed, 47 insertions(+), 44 deletions(-) diff --git a/sf_machine_connect/views/compensation.xml b/sf_machine_connect/views/compensation.xml index f79c539e..016f3821 100644 --- a/sf_machine_connect/views/compensation.xml +++ b/sf_machine_connect/views/compensation.xml @@ -5,10 +5,10 @@ mrp.workorder - -