diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 405fd1d5..b3d4f6ea 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -3,6 +3,7 @@ import base64 import logging import re import requests +from itertools import groupby from odoo import api, fields, models, _ from odoo.exceptions import UserError from odoo.addons.sf_base.commons.common import Common @@ -154,7 +155,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])]) @@ -167,8 +168,9 @@ class MrpProduction(models.Model): programme_way = 'manual operation' try: res = { - 'production_no': cnc.name, + 'production_no': production_names, 'machine_tool_code': '', + 'product_name': cnc.product_id.name, 'model_code': cnc.product_id.model_code, 'material_code': self.env['sf.production.materials'].search( [('id', '=', cnc.product_id.materials_id.id)]).materials_no, @@ -267,16 +269,18 @@ 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_first = None + # 根据product_id对self进行分组 + grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.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 in self: if not production.bom_id or not production.product_id: continue workorders_values = [] - # 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) exploded_boms, dummy = production.bom_id.explode(production.product_id, @@ -300,15 +304,20 @@ class MrpProduction(models.Model): 'state': 'pending', }] if production.product_id.categ_id.type == '成品': - production.fetchCNC() - # 第二期同一个产品多个制造订单对应一个编程单和模型库 - # if programming_no is None: - # production.fetchCNC(production_names) - # programming_no = production.programming_no - # else: - # if production.product_id == product_first: - # if not production.programming_no: - # production.write({'programming_no': programming_no, 'programming_state': '编程中'}) + 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') + logging.info('production_programming1:%s' % production_programming.programming_no) + if not production_programming.programming_no: + production.fetchCNC(', '.join(product_id_to_production_names[production.product_id.id])) + else: + logging.info('production_programming2:%s' % production_programming.programming_no) + production.write({'programming_no': production_programming.programming_no, + 'programming_state': '编程中'}) # 根据加工面板的面数及对应的工序模板生成工单 i = 0 processing_panel_len = len(production.product_id.model_processing_panel.split(',')) @@ -414,6 +423,7 @@ class MrpProduction(models.Model): self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production) else: self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production) + 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 aa084eaf..a4c5eaf4 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -959,17 +959,18 @@ class CNCprocessing(models.Model): # mrs下发编程单创建CNC加工 def cnc_processing_create(self, cnc_workorder, ret, program_path, program_path_tmp): - # 注释代码为第二期同一产品多个编程单需求 - # cnc_processing = None + 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']), - ('routing_type', '=', 'CNC加工')]) + # 暂时不注释,批次插入不需要单个workorder + workorder = self.env['mrp.workorder'].search( + [('production_id.name', '=', cnc_workorder.name), + ('processing_panel', '=', obj['processing_panel']), + ('routing_type', '=', 'CNC加工')]) logging.info('workorder:%s' % workorder.id) if obj['program_name'] in program_path: logging.info('obj:%s' % obj['program_name']) cnc_processing = self.env['sf.cnc.processing'].create({ - 'workorder_id': workorder.id, + # 'workorder_id': workorder.id, 'sequence_number': obj['sequence_number'], 'program_name': obj['program_name'], 'cutting_tool_name': obj['cutting_tool_name'], @@ -985,23 +986,10 @@ class CNCprocessing(models.Model): 'program_path': program_path.replace('/tmp', '/home/ftp/ftp_root/NC') }) cnc_processing.get_cnc_processing_file(program_path_tmp, cnc_processing, program_path) - # cnc_workorder.state = 'done' - cnc_workorder.work_state = '已编程' - cnc_workorder.programming_state = '已编程' - workpiece_delivery = self.env['sf.workpiece.delivery'].search( - [('production_id', '=', cnc_workorder.id)]) - if workpiece_delivery: - for item in workpiece_delivery: - 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() + return cnc_processing def _json_cnc_processing(self, obj): - cnc_processing_str = [0, 0, { + cnc_processing_str = (0, 0, { 'sequence_number': obj['sequence_number'], 'program_name': obj['program_name'], 'cutting_tool_name': obj['cutting_tool_name'], @@ -1014,7 +1002,7 @@ class CNCprocessing(models.Model): '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进行匹配 @@ -1442,10 +1430,12 @@ class CMMprogram(models.Model): program_path = fields.Char('程序文件路径') 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']), - ('processing_panel', '=', obj['processing_panel']), - ('routing_type', '=', 'CNC加工')]) + 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({ @@ -1465,6 +1455,7 @@ class CMMprogram(models.Model): 'program_path': program_path.replace('/tmp', '') }) 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): diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index 44a65200..4b45014a 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -26,14 +26,17 @@ class Sf_Mrs_Connect(http.Controller): logging.info('下发编程单:%s' % ret) # 查询状态为进行中且类型为获取CNC加工程序的工单 cnc_production = request.env['mrp.production'].with_user( - request.env.ref("base.user_admin")).search([('name', '=', ret['production_order_no'])]) + request.env.ref("base.user_admin")).search([('name', '=', ret['production_order_no'].split(',')[0])]) + # cnc_program = request.env['mrp.production'].with_user( + # request.env.ref("base.user_admin")).search( + # [('programming_no', '=', cnc_production.programming_no), ('id', '!=', cnc_production.id)]) + 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( @@ -46,16 +49,32 @@ class Sf_Mrs_Connect(http.Controller): 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) logging.info('cnc程序路径 :%s' % program_path) if f.endswith(".doc"): # 插入cmm程序数据 - request.env['sf.cmm.program'].with_user( + cmm_program = 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: + cnc_processing_arr.append(cnc_processing._json_cnc_processing(cnc_processing)) + if cnc_program and cnc_processing_arr: + logging.info('cnc_processing_arr:%s' % cnc_processing_arr) + cnc_program.write({'programming_state': '已编程', 'work_state': '已编程'}) + cnc_program.workorder_ids.filtered(lambda b: b.routing_type == 'CNC加工').write( + {'cnc_ids': cnc_processing_arr}) + 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: + for item in workpiece_delivery: + item.is_cnc_program_down = True + if item.workorder_id.state == 'waiting': + item.workorder_id.state = 'ready' return json.JSONEncoder().encode(res) else: res = {'status': 0, 'message': '该制造订单暂未开始'}