1.优化同一个产品多个制造订单的编程单合并到一张编程单和一个模型库至cloud
This commit is contained in:
@@ -3,6 +3,7 @@ import base64
|
|||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import requests
|
import requests
|
||||||
|
from itertools import groupby
|
||||||
from odoo import api, fields, models, _
|
from odoo import api, fields, models, _
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
from odoo.addons.sf_base.commons.common import Common
|
from odoo.addons.sf_base.commons.common import Common
|
||||||
@@ -154,7 +155,7 @@ class MrpProduction(models.Model):
|
|||||||
production.maintenance_count = len(production.request_ids)
|
production.maintenance_count = len(production.request_ids)
|
||||||
|
|
||||||
# cnc程序获取
|
# cnc程序获取
|
||||||
def fetchCNC(self):
|
def fetchCNC(self, production_names):
|
||||||
cnc = self.env['mrp.production'].search([('id', '=', self.id)])
|
cnc = self.env['mrp.production'].search([('id', '=', self.id)])
|
||||||
quick_order = self.env['quick.easy.order'].search(
|
quick_order = self.env['quick.easy.order'].search(
|
||||||
[('name', '=', cnc.product_id.default_code.rsplit('-', 1)[0])])
|
[('name', '=', cnc.product_id.default_code.rsplit('-', 1)[0])])
|
||||||
@@ -167,8 +168,9 @@ class MrpProduction(models.Model):
|
|||||||
programme_way = 'manual operation'
|
programme_way = 'manual operation'
|
||||||
try:
|
try:
|
||||||
res = {
|
res = {
|
||||||
'production_no': cnc.name,
|
'production_no': production_names,
|
||||||
'machine_tool_code': '',
|
'machine_tool_code': '',
|
||||||
|
'product_name': cnc.product_id.name,
|
||||||
'model_code': cnc.product_id.model_code,
|
'model_code': cnc.product_id.model_code,
|
||||||
'material_code': self.env['sf.production.materials'].search(
|
'material_code': self.env['sf.production.materials'].search(
|
||||||
[('id', '=', cnc.product_id.materials_id.id)]).materials_no,
|
[('id', '=', cnc.product_id.materials_id.id)]).materials_no,
|
||||||
@@ -267,16 +269,18 @@ class MrpProduction(models.Model):
|
|||||||
# 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心;
|
# 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心;
|
||||||
|
|
||||||
def _create_workorder3(self):
|
def _create_workorder3(self):
|
||||||
# production_names = [production.name for production in self if production.product_id.categ_id.type == '成品']
|
# 根据product_id对self进行分组
|
||||||
# programming_no = None
|
grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.product_id.id)}
|
||||||
# product_first = None
|
# 初始化一个字典来存储每个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:
|
for production in self:
|
||||||
if not production.bom_id or not production.product_id:
|
if not production.bom_id or not production.product_id:
|
||||||
continue
|
continue
|
||||||
workorders_values = []
|
workorders_values = []
|
||||||
# if product_first is None:
|
|
||||||
# product_first = production.product_id
|
|
||||||
|
|
||||||
product_qty = production.product_uom_id._compute_quantity(production.product_qty,
|
product_qty = production.product_uom_id._compute_quantity(production.product_qty,
|
||||||
production.bom_id.product_uom_id)
|
production.bom_id.product_uom_id)
|
||||||
exploded_boms, dummy = production.bom_id.explode(production.product_id,
|
exploded_boms, dummy = production.bom_id.explode(production.product_id,
|
||||||
@@ -300,15 +304,20 @@ class MrpProduction(models.Model):
|
|||||||
'state': 'pending',
|
'state': 'pending',
|
||||||
}]
|
}]
|
||||||
if production.product_id.categ_id.type == '成品':
|
if production.product_id.categ_id.type == '成品':
|
||||||
production.fetchCNC()
|
if production.product_id.id in product_id_to_production_names:
|
||||||
# 第二期同一个产品多个制造订单对应一个编程单和模型库
|
# 同一个产品多个制造订单对应一个编程单和模型库
|
||||||
# if programming_no is None:
|
# 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递
|
||||||
# production.fetchCNC(production_names)
|
if not production.programming_no:
|
||||||
# programming_no = production.programming_no
|
production_programming = self.search(
|
||||||
# else:
|
[('product_id.id', '=', production.product_id.id), ('origin', '=', production.origin)],
|
||||||
# if production.product_id == product_first:
|
limit=1, order='id asc')
|
||||||
# if not production.programming_no:
|
logging.info('production_programming1:%s' % production_programming.programming_no)
|
||||||
# production.write({'programming_no': programming_no, 'programming_state': '编程中'})
|
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
|
i = 0
|
||||||
processing_panel_len = len(production.product_id.model_processing_panel.split(','))
|
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)
|
self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production)
|
||||||
else:
|
else:
|
||||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production)
|
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production)
|
||||||
|
|
||||||
for workorder in production.workorder_ids:
|
for workorder in production.workorder_ids:
|
||||||
workorder.duration_expected = workorder._get_duration_expected()
|
workorder.duration_expected = workorder._get_duration_expected()
|
||||||
|
|
||||||
|
|||||||
@@ -959,17 +959,18 @@ class CNCprocessing(models.Model):
|
|||||||
|
|
||||||
# mrs下发编程单创建CNC加工
|
# mrs下发编程单创建CNC加工
|
||||||
def cnc_processing_create(self, cnc_workorder, ret, program_path, program_path_tmp):
|
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']:
|
for obj in ret['programming_list']:
|
||||||
workorder = self.env['mrp.workorder'].search([('production_id.name', '=', ret['production_order_no']),
|
# 暂时不注释,批次插入不需要单个workorder
|
||||||
|
workorder = self.env['mrp.workorder'].search(
|
||||||
|
[('production_id.name', '=', cnc_workorder.name),
|
||||||
('processing_panel', '=', obj['processing_panel']),
|
('processing_panel', '=', obj['processing_panel']),
|
||||||
('routing_type', '=', 'CNC加工')])
|
('routing_type', '=', 'CNC加工')])
|
||||||
logging.info('workorder:%s' % workorder.id)
|
logging.info('workorder:%s' % workorder.id)
|
||||||
if obj['program_name'] in program_path:
|
if obj['program_name'] in program_path:
|
||||||
logging.info('obj:%s' % obj['program_name'])
|
logging.info('obj:%s' % obj['program_name'])
|
||||||
cnc_processing = self.env['sf.cnc.processing'].create({
|
cnc_processing = self.env['sf.cnc.processing'].create({
|
||||||
'workorder_id': workorder.id,
|
# 'workorder_id': workorder.id,
|
||||||
'sequence_number': obj['sequence_number'],
|
'sequence_number': obj['sequence_number'],
|
||||||
'program_name': obj['program_name'],
|
'program_name': obj['program_name'],
|
||||||
'cutting_tool_name': obj['cutting_tool_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')
|
'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_processing.get_cnc_processing_file(program_path_tmp, cnc_processing, program_path)
|
||||||
# cnc_workorder.state = 'done'
|
return cnc_processing
|
||||||
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()
|
|
||||||
|
|
||||||
def _json_cnc_processing(self, obj):
|
def _json_cnc_processing(self, obj):
|
||||||
cnc_processing_str = [0, 0, {
|
cnc_processing_str = (0, 0, {
|
||||||
'sequence_number': obj['sequence_number'],
|
'sequence_number': obj['sequence_number'],
|
||||||
'program_name': obj['program_name'],
|
'program_name': obj['program_name'],
|
||||||
'cutting_tool_name': obj['cutting_tool_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'],
|
'cutting_tool_handle_type': obj['cutting_tool_handle_type'],
|
||||||
'estimated_processing_time': obj['estimated_processing_time'],
|
'estimated_processing_time': obj['estimated_processing_time'],
|
||||||
'remark': obj['remark']
|
'remark': obj['remark']
|
||||||
}]
|
})
|
||||||
return cnc_processing_str
|
return cnc_processing_str
|
||||||
|
|
||||||
# 根据程序名和加工面匹配到ftp里对应的Nc程序名,可优化为根据cnc_processing.program_path进行匹配
|
# 根据程序名和加工面匹配到ftp里对应的Nc程序名,可优化为根据cnc_processing.program_path进行匹配
|
||||||
@@ -1442,8 +1430,10 @@ class CMMprogram(models.Model):
|
|||||||
program_path = fields.Char('程序文件路径')
|
program_path = fields.Char('程序文件路径')
|
||||||
|
|
||||||
def cmm_program_create(self, ret, program_path, program_path_tmp):
|
def cmm_program_create(self, ret, program_path, program_path_tmp):
|
||||||
|
cmm_program = None
|
||||||
for obj in ret['programming_list']:
|
for obj in ret['programming_list']:
|
||||||
workorder = self.env['mrp.workorder'].search([('production_id.name', '=', ret['production_order_no']),
|
workorder = self.env['mrp.workorder'].search(
|
||||||
|
[('production_id.name', '=', ret['production_order_no'].split(',')[0]),
|
||||||
('processing_panel', '=', obj['processing_panel']),
|
('processing_panel', '=', obj['processing_panel']),
|
||||||
('routing_type', '=', 'CNC加工')])
|
('routing_type', '=', 'CNC加工')])
|
||||||
if obj['program_name'] in program_path:
|
if obj['program_name'] in program_path:
|
||||||
@@ -1465,6 +1455,7 @@ class CMMprogram(models.Model):
|
|||||||
'program_path': program_path.replace('/tmp', '')
|
'program_path': program_path.replace('/tmp', '')
|
||||||
})
|
})
|
||||||
cmm_program.get_cmm_program_file(program_path_tmp, cmm_program, program_path)
|
cmm_program.get_cmm_program_file(program_path_tmp, cmm_program, program_path)
|
||||||
|
return cmm_program
|
||||||
|
|
||||||
# 根据程序名和加工面匹配到ftp里对应的cmm程序名
|
# 根据程序名和加工面匹配到ftp里对应的cmm程序名
|
||||||
def get_cmm_program_file(self, serverdir, cmm_program, program_path):
|
def get_cmm_program_file(self, serverdir, cmm_program, program_path):
|
||||||
|
|||||||
@@ -26,14 +26,17 @@ class Sf_Mrs_Connect(http.Controller):
|
|||||||
logging.info('下发编程单:%s' % ret)
|
logging.info('下发编程单:%s' % ret)
|
||||||
# 查询状态为进行中且类型为获取CNC加工程序的工单
|
# 查询状态为进行中且类型为获取CNC加工程序的工单
|
||||||
cnc_production = request.env['mrp.production'].with_user(
|
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)
|
logging.info('制造订单号:%s' % cnc_production.name)
|
||||||
if cnc_production:
|
if cnc_production:
|
||||||
# if ret['glb_file']:
|
# if ret['glb_file']:
|
||||||
# cnc_production.glb_file = base64.b64encode(ret['glb_file'])
|
# cnc_production.glb_file = base64.b64encode(ret['glb_file'])
|
||||||
# 拉取所有加工面的程序文件
|
# 拉取所有加工面的程序文件
|
||||||
# i = 1
|
|
||||||
|
|
||||||
for r in ret['processing_panel']:
|
for r in ret['processing_panel']:
|
||||||
download_state = request.env['sf.cnc.processing'].with_user(
|
download_state = request.env['sf.cnc.processing'].with_user(
|
||||||
request.env.ref("base.user_admin")).download_file_tmp(
|
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 = os.path.join('/tmp', ret['folder_name'], 'return', r)
|
||||||
# program_path_tmp = "C://Users//43484//Desktop//机企猫工作文档//其他//model_analysis"
|
# program_path_tmp = "C://Users//43484//Desktop//机企猫工作文档//其他//model_analysis"
|
||||||
files = os.listdir(program_path_tmp)
|
files = os.listdir(program_path_tmp)
|
||||||
|
cnc_processing_arr = []
|
||||||
for f in files:
|
for f in files:
|
||||||
program_path = os.path.join(program_path_tmp, f)
|
program_path = os.path.join(program_path_tmp, f)
|
||||||
logging.info('cnc程序路径 :%s' % program_path)
|
logging.info('cnc程序路径 :%s' % program_path)
|
||||||
if f.endswith(".doc"):
|
if f.endswith(".doc"):
|
||||||
# 插入cmm程序数据
|
# 插入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.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,
|
request.env.ref("base.user_admin")).cnc_processing_create(cnc_production, ret, program_path,
|
||||||
program_path_tmp)
|
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)
|
return json.JSONEncoder().encode(res)
|
||||||
else:
|
else:
|
||||||
res = {'status': 0, 'message': '该制造订单暂未开始'}
|
res = {'status': 0, 'message': '该制造订单暂未开始'}
|
||||||
|
|||||||
Reference in New Issue
Block a user