Merge branch 'feature/优化工单(cnc和cmc)涉及多个加工面' into develop
This commit is contained in:
@@ -5,10 +5,10 @@
|
|||||||
<field name="model">mrp.workorder</field>
|
<field name="model">mrp.workorder</field>
|
||||||
<field name="inherit_id" ref="sf_manufacturing.view_mrp_production_workorder_tray_form_inherit_sf"/>
|
<field name="inherit_id" ref="sf_manufacturing.view_mrp_production_workorder_tray_form_inherit_sf"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//header" position="inside">
|
<!-- <xpath expr="//header" position="inside">-->
|
||||||
<button string="程序下载" name="cnc_file_download" type="object" class="oe_highlight" attrs='{"invisible": ["|",
|
<!-- <button string="程序下载" name="cnc_file_download" type="object" class="oe_highlight" attrs='{"invisible": ["|",-->
|
||||||
("user_permissions","=",False),("routing_type","!=","CNC加工")]}'/>
|
<!-- ("user_permissions","=",False),("routing_type","!=","CNC加工")]}'/>-->
|
||||||
</xpath>
|
<!-- </xpath>-->
|
||||||
<xpath expr="//page//field[@name='cnc_ids']" position="before">
|
<xpath expr="//page//field[@name='cnc_ids']" position="before">
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group>
|
||||||
@@ -19,21 +19,21 @@
|
|||||||
<div>
|
<div>
|
||||||
<field name="button_compensation_state" attrs='{"invisible": ["|",
|
<field name="button_compensation_state" attrs='{"invisible": ["|",
|
||||||
("state","!=","progress"),("user_permissions","=",False)]}'/>
|
("state","!=","progress"),("user_permissions","=",False)]}'/>
|
||||||
<button string="一键补偿" name="compensation" type="object" confirm="是否确认下发补偿"
|
<!-- <button string="一键补偿" name="compensation" type="object" confirm="是否确认下发补偿"-->
|
||||||
class="btn-primary" attrs='{"invisible": ["|",
|
<!-- class="btn-primary" attrs='{"invisible": ["|",-->
|
||||||
("state","!=","progress"),("user_permissions","=",False)]}'/>
|
<!-- ("state","!=","progress"),("user_permissions","=",False)]}'/>-->
|
||||||
<span> </span>
|
<!-- <span> </span>-->
|
||||||
<button string="一键下发" name="up_all" type="object" style="text-align: right;" confirm="是否确认一键下发"
|
<!-- <button string="一键下发" name="up_all" type="object" style="text-align: right;" confirm="是否确认一键下发"-->
|
||||||
class="btn-primary" context="{'default_workorder_id': id}" attrs='{"invisible": ["|",
|
<!-- class="btn-primary" context="{'default_workorder_id': id}" attrs='{"invisible": ["|",-->
|
||||||
("state","!=","progress"),("user_permissions","=",False)]}'/>
|
<!-- ("state","!=","progress"),("user_permissions","=",False)]}'/>-->
|
||||||
<span> </span>
|
<!-- <span> </span>-->
|
||||||
<button string="合并下发" id="action_up_select" name="%(sf_machine_connect.action_up_select)d"
|
<!-- <button string="合并下发" id="action_up_select" name="%(sf_machine_connect.action_up_select)d"-->
|
||||||
type="action" class="btn-primary" context="{'default_workorder_id': id}" attrs='{"invisible": ["|",
|
<!-- type="action" class="btn-primary" context="{'default_workorder_id': id}" attrs='{"invisible": ["|",-->
|
||||||
("state","!=","progress"),("user_permissions","=",False)]}'/>
|
<!-- ("state","!=","progress"),("user_permissions","=",False)]}'/>-->
|
||||||
<span> </span>
|
<!-- <span> </span>-->
|
||||||
<button string="一键合并下发" name="up_merge_all" type="object" style="text-align: right;" confirm="是否确认一键合并下发"
|
<!-- <button string="一键合并下发" name="up_merge_all" type="object" style="text-align: right;" confirm="是否确认一键合并下发"-->
|
||||||
class="btn-primary" context="{'default_workorder_id': id}" attrs='{"invisible": ["|",
|
<!-- class="btn-primary" context="{'default_workorder_id': id}" attrs='{"invisible": ["|",-->
|
||||||
("state","!=","progress"),("user_permissions","=",False)]}'/>
|
<!-- ("state","!=","progress"),("user_permissions","=",False)]}'/>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</group>
|
</group>
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
<tree>
|
<tree>
|
||||||
<field name="sequence_number"/>
|
<field name="sequence_number"/>
|
||||||
<field name="program_name"/>
|
<field name="program_name"/>
|
||||||
<field name="cnc_id" string="文件"/>
|
|
||||||
<field name="functional_tool_type_id"/>
|
<field name="functional_tool_type_id"/>
|
||||||
<field name="cutting_tool_name"/>
|
<field name="cutting_tool_name"/>
|
||||||
<field name="cutting_tool_no"/>
|
<field name="cutting_tool_no"/>
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ class MrpProduction(models.Model):
|
|||||||
# 则根据设备找到工作中心;否则采用前面描述的工作中心分配机制;
|
# 则根据设备找到工作中心;否则采用前面描述的工作中心分配机制;
|
||||||
# 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心;
|
# 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心;
|
||||||
|
|
||||||
def _create_workorder3(self):
|
def _create_workorder3(self, item):
|
||||||
# 根据product_id对self进行分组
|
# 根据product_id对self进行分组
|
||||||
grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.product_id.id)}
|
grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.product_id.id)}
|
||||||
# 初始化一个字典来存储每个product_id对应的生产订单名称列表
|
# 初始化一个字典来存储每个product_id对应的生产订单名称列表
|
||||||
@@ -328,19 +328,6 @@ class MrpProduction(models.Model):
|
|||||||
'state': 'pending',
|
'state': 'pending',
|
||||||
}]
|
}]
|
||||||
if production.product_id.categ_id.type == '成品':
|
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
|
i = 0
|
||||||
processing_panel_len = len(production.product_id.model_processing_panel.split(','))
|
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:
|
for route in product_routing_workcenter:
|
||||||
if route.is_repeat is True:
|
if route.is_repeat is True:
|
||||||
workorders_values.append(
|
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 == '解除装夹':
|
# if i == processing_panel_len and route.routing_type == '解除装夹':
|
||||||
workorders_values.append(
|
# workorders_values.append(
|
||||||
self.env['mrp.workorder'].json_workorder_str(k, production, route))
|
# self.env['mrp.workorder'].json_workorder_str(k, production, route))
|
||||||
# 表面工艺工序
|
# 表面工艺工序
|
||||||
# 获取表面工艺id
|
# 获取表面工艺id
|
||||||
if production.product_id.model_process_parameters_ids:
|
if production.product_id.model_process_parameters_ids:
|
||||||
@@ -404,6 +391,52 @@ class MrpProduction(models.Model):
|
|||||||
workorders_values.append(
|
workorders_values.append(
|
||||||
self.env['mrp.workorder'].json_workorder_str('', production, route))
|
self.env['mrp.workorder'].json_workorder_str('', production, route))
|
||||||
production.workorder_ids = workorders_values
|
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:
|
for workorder in production.workorder_ids:
|
||||||
workorder.duration_expected = workorder._get_duration_expected()
|
workorder.duration_expected = workorder._get_duration_expected()
|
||||||
|
|
||||||
@@ -546,8 +579,8 @@ class MrpProduction(models.Model):
|
|||||||
# work.button_finish()
|
# work.button_finish()
|
||||||
|
|
||||||
# 创建工单并进行排序
|
# 创建工单并进行排序
|
||||||
def _create_workorder(self):
|
def _create_workorder(self, item):
|
||||||
self._create_workorder3()
|
self._create_workorder3(item)
|
||||||
self._reset_work_order_sequence()
|
self._reset_work_order_sequence()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -474,7 +474,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
raise UserError(_("该工单暂未完成,无法进行工件配送"))
|
raise UserError(_("该工单暂未完成,无法进行工件配送"))
|
||||||
|
|
||||||
# 拼接工单对象属性值
|
# 拼接工单对象属性值
|
||||||
def json_workorder_str(self, k, production, route):
|
def json_workorder_str(self, k, production, route, item):
|
||||||
# 计算预计时长duration_expected
|
# 计算预计时长duration_expected
|
||||||
if route.routing_type == '切割':
|
if route.routing_type == '切割':
|
||||||
duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
|
duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
|
||||||
@@ -507,7 +507,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
'processing_panel': k,
|
'processing_panel': k,
|
||||||
'quality_point_ids': route.route_workcenter_id.quality_point_ids,
|
'quality_point_ids': route.route_workcenter_id.quality_point_ids,
|
||||||
'routing_type': route.routing_type,
|
'routing_type': route.routing_type,
|
||||||
'work_state': '待发起',
|
# 'work_state': '待发起',
|
||||||
'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids,
|
'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids,
|
||||||
route.routing_type,
|
route.routing_type,
|
||||||
production.product_id),
|
production.product_id),
|
||||||
@@ -516,6 +516,10 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
'date_planned_finished': datetime.now() + timedelta(days=1),
|
'date_planned_finished': datetime.now() + timedelta(days=1),
|
||||||
'duration_expected': duration_expected,
|
'duration_expected': duration_expected,
|
||||||
'duration': 0,
|
'duration': 0,
|
||||||
|
'cnc_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cnc.processing']._json_cnc_processing(
|
||||||
|
k, item),
|
||||||
|
'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(
|
'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list(
|
||||||
production)
|
production)
|
||||||
}]
|
}]
|
||||||
@@ -1119,6 +1123,7 @@ class CNCprocessing(models.Model):
|
|||||||
production_id = fields.Many2one('mrp.production', string="制造订单")
|
production_id = fields.Many2one('mrp.production', string="制造订单")
|
||||||
button_state = fields.Boolean(string='是否已经下发')
|
button_state = fields.Boolean(string='是否已经下发')
|
||||||
program_path = fields.Char('程序文件路径')
|
program_path = fields.Char('程序文件路径')
|
||||||
|
program_create_date = fields.Datetime('程序创建日期')
|
||||||
|
|
||||||
# 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):
|
||||||
@@ -1151,24 +1156,27 @@ class CNCprocessing(models.Model):
|
|||||||
cnc_workorder.write({'programming_state': '已编程', 'work_state': '已编程'})
|
cnc_workorder.write({'programming_state': '已编程', 'work_state': '已编程'})
|
||||||
return cnc_processing
|
return cnc_processing
|
||||||
|
|
||||||
def _json_cnc_processing(self, obj):
|
def _json_cnc_processing(self, panel, ret):
|
||||||
cnc_processing_str = (0, 0, {
|
cnc_processing = []
|
||||||
'sequence_number': obj['sequence_number'],
|
for item in ret['programming_list']:
|
||||||
'program_name': obj['program_name'],
|
if item['processing_panel'] == panel and item['ftp_path'].find('.dmi') == -1:
|
||||||
'cutting_tool_name': obj['cutting_tool_name'],
|
cnc_processing.append((0, 0, {
|
||||||
'cutting_tool_no': obj['cutting_tool_no'],
|
'sequence_number': item['sequence_number'],
|
||||||
'processing_type': obj['processing_type'],
|
'program_name': item['program_name'],
|
||||||
'margin_x_y': obj['margin_x_y'],
|
'cutting_tool_name': item['cutting_tool_name'],
|
||||||
'margin_z': obj['margin_z'],
|
'cutting_tool_no': item['cutting_tool_no'],
|
||||||
'depth_of_processing_z': obj['depth_of_processing_z'],
|
'processing_type': item['processing_type'],
|
||||||
'cutting_tool_extension_length': obj['cutting_tool_extension_length'],
|
'margin_x_y': item['margin_x_y'],
|
||||||
'cutting_tool_handle_type': obj['cutting_tool_handle_type'],
|
'margin_z': item['margin_z'],
|
||||||
'estimated_processing_time': obj['estimated_processing_time'],
|
'depth_of_processing_z': item['depth_of_processing_z'],
|
||||||
'program_path': obj['program_path'],
|
'cutting_tool_extension_length': item['cutting_tool_extension_length'],
|
||||||
'cnc_id': obj['cnc_id'].id,
|
'cutting_tool_handle_type': item['cutting_tool_handle_type'],
|
||||||
'remark': obj['remark']
|
'estimated_processing_time': item['estimated_processing_time'],
|
||||||
})
|
'program_path': item['ftp_path'],
|
||||||
return cnc_processing_str
|
'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进行匹配
|
# 根据程序名和加工面匹配到ftp里对应的Nc程序名,可优化为根据cnc_processing.program_path进行匹配
|
||||||
def get_cnc_processing_file(self, serverdir, cnc_processing, program_path):
|
def get_cnc_processing_file(self, serverdir, cnc_processing, program_path):
|
||||||
@@ -1198,14 +1206,14 @@ class CNCprocessing(models.Model):
|
|||||||
})
|
})
|
||||||
return attachment
|
return attachment
|
||||||
|
|
||||||
# 将FTP的nc文件下载到临时目录
|
# 将FTP的多面的程序单文件下载到临时目录
|
||||||
def download_file_tmp(self, production_no, processing_panel):
|
def download_file_tmp(self, production_no, processing_panel):
|
||||||
remotepath = os.path.join('/NC', production_no, 'return', 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('/tmp', production_no, 'return', processing_panel)
|
||||||
ftp_resconfig = self.env['res.config.settings'].get_values()
|
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 = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']), ftp_resconfig['ftp_user'],
|
||||||
ftp_resconfig['ftp_password'])
|
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)
|
logging.info('download_state:%s' % download_state)
|
||||||
return download_state
|
return download_state
|
||||||
|
|
||||||
@@ -1610,80 +1618,22 @@ class CMMprogram(models.Model):
|
|||||||
_name = 'sf.cmm.program'
|
_name = 'sf.cmm.program'
|
||||||
_description = "CMM程序"
|
_description = "CMM程序"
|
||||||
|
|
||||||
cmm_id = fields.Many2one('ir.attachment')
|
|
||||||
sequence_number = fields.Integer('序号')
|
sequence_number = fields.Integer('序号')
|
||||||
program_name = fields.Char('程序名')
|
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('备注')
|
remark = fields.Text('备注')
|
||||||
workorder_id = fields.Many2one('mrp.workorder', string="工单")
|
workorder_id = fields.Many2one('mrp.workorder', string="工单")
|
||||||
production_id = fields.Many2one('mrp.production', string="制造订单")
|
production_id = fields.Many2one('mrp.production', string="制造订单")
|
||||||
program_path = fields.Char('程序文件路径')
|
program_path = fields.Char('程序文件路径')
|
||||||
|
program_create_date = fields.Datetime('程序创建日期')
|
||||||
|
|
||||||
def cmm_program_create(self, ret, program_path, program_path_tmp):
|
def _json_cmm_program(self, panel, ret):
|
||||||
cmm_program = None
|
cmm_program = []
|
||||||
for obj in ret['programming_list']:
|
for item in ret['programming_list']:
|
||||||
workorder = self.env['mrp.workorder'].search(
|
if item['processing_panel'] == panel and item['ftp_path'].find('.dmi') != -1:
|
||||||
[('production_id.name', '=', ret['production_order_no'].split(',')[0]),
|
cmm_program.append((0, 0, {
|
||||||
('processing_panel', '=', obj['processing_panel']),
|
'sequence_number': 1,
|
||||||
('routing_type', '=', 'CNC加工')])
|
'program_name': item['program_name'],
|
||||||
if obj['program_name'] in program_path:
|
'program_path': item['ftp_path'],
|
||||||
logging.info('obj:%s' % obj['program_name'])
|
'program_create_date': datetime.strptime(item['program_create_date'], '%Y-%m-%d %H:%M:%S'),
|
||||||
cmm_program = self.sudo().create({
|
}))
|
||||||
'workorder_id': workorder.id,
|
|
||||||
'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', '')
|
|
||||||
})
|
|
||||||
cmm_program.get_cmm_program_file(program_path_tmp, cmm_program, program_path)
|
|
||||||
return cmm_program
|
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
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import base64
|
import base64
|
||||||
import qrcode
|
import qrcode
|
||||||
|
from itertools import groupby
|
||||||
from collections import defaultdict, namedtuple
|
from collections import defaultdict, namedtuple
|
||||||
import logging
|
import logging
|
||||||
import io
|
import io
|
||||||
@@ -205,61 +206,37 @@ class StockRule(models.Model):
|
|||||||
|
|
||||||
# self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
|
# self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
|
||||||
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
|
self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
|
||||||
'''
|
|
||||||
创建工单
|
|
||||||
'''
|
|
||||||
productions._create_workorder()
|
|
||||||
|
|
||||||
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \
|
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \
|
||||||
(
|
(
|
||||||
p.move_dest_ids.procure_method != 'make_to_order' and not
|
p.move_dest_ids.procure_method != 'make_to_order' and not
|
||||||
p.move_raw_ids and not p.workorder_ids)).action_confirm()
|
p.move_raw_ids and not p.workorder_ids)).action_confirm()
|
||||||
|
'''
|
||||||
|
创建工单
|
||||||
|
'''
|
||||||
|
# productions._create_workorder()
|
||||||
|
#
|
||||||
|
grouped_product_ids = {k: list(g) for k, g in groupby(productions, 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_item in productions:
|
for production_item in productions:
|
||||||
process_parameter_workorder = self.env['mrp.workorder'].search(
|
if production_item.product_id.id in product_id_to_production_names:
|
||||||
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_item.id),
|
# # 同一个产品多个制造订单对应一个编程单和模型库
|
||||||
('is_subcontract', '=', True)])
|
# # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递
|
||||||
if process_parameter_workorder:
|
if not production_item.programming_no:
|
||||||
is_pick = False
|
production_programming = self.env['mrp.production'].search(
|
||||||
consecutive_workorders = []
|
[('product_id.id', '=', production_item.product_id.id),
|
||||||
m = 0
|
('origin', '=', production_item.origin)],
|
||||||
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id)
|
limit=1, order='id asc')
|
||||||
for i in range(len(sorted_workorders) - 1):
|
if not production_programming.programming_no:
|
||||||
if m == 0:
|
production_item.fetchCNC(
|
||||||
is_pick = False
|
', '.join(product_id_to_production_names[production_item.product_id.id]))
|
||||||
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:
|
else:
|
||||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
production_item.write({'programming_no': production_programming.programming_no,
|
||||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
|
'programming_state': '编程中'})
|
||||||
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:
|
for production in productions:
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
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_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_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_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,1
|
||||||
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_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_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
|
access_sf_model_type_manager,sf_model_type,model_sf_model_type,sf_base.group_sf_mrp_manager,1,1,1,0
|
||||||
|
|||||||
|
@@ -219,9 +219,6 @@
|
|||||||
attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
|
attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
|
||||||
<field name="functional_fixture_type_id"
|
<field name="functional_fixture_type_id"
|
||||||
attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
|
attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
|
||||||
<field name="rfid_code" force_save="1" readonly="1" cache="True"
|
|
||||||
attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
|
|
||||||
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
|
|
||||||
</group>
|
</group>
|
||||||
<!-- <group>-->
|
<!-- <group>-->
|
||||||
<!-- <div>-->
|
<!-- <div>-->
|
||||||
@@ -507,11 +504,11 @@
|
|||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//page[1]" position="before">
|
<xpath expr="//page[1]" position="before">
|
||||||
<page string="CNC程序" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
|
<page string="CNC程序" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
|
||||||
<field name="cnc_ids" widget="one2many" string="工作程序" default_order="sequence_number,id">
|
<field name="cnc_ids" widget="one2many" string="工作程序" default_order="sequence_number,id"
|
||||||
<tree decoration-success="button_state" decoration-bf="button_state">
|
readonly="1">
|
||||||
|
<tree>
|
||||||
<field name="sequence_number"/>
|
<field name="sequence_number"/>
|
||||||
<field name="program_name"/>
|
<field name="program_name"/>
|
||||||
<field name="cnc_id" string="文件"/>
|
|
||||||
<field name="cutting_tool_name"/>
|
<field name="cutting_tool_name"/>
|
||||||
<field name="cutting_tool_no"/>
|
<field name="cutting_tool_no"/>
|
||||||
<field name="processing_type"/>
|
<field name="processing_type"/>
|
||||||
@@ -521,8 +518,10 @@
|
|||||||
<field name="cutting_tool_extension_length"/>
|
<field name="cutting_tool_extension_length"/>
|
||||||
<field name="cutting_tool_handle_type"/>
|
<field name="cutting_tool_handle_type"/>
|
||||||
<field name="estimated_processing_time"/>
|
<field name="estimated_processing_time"/>
|
||||||
|
<field name="program_path"/>
|
||||||
|
<field name="program_create_date"/>
|
||||||
<field name="remark"/>
|
<field name="remark"/>
|
||||||
<field name="button_state" invisible="1"/>
|
<!-- <field name="button_state" invisible="1"/>-->
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
<group>
|
<group>
|
||||||
@@ -530,20 +529,12 @@
|
|||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
<page string="CMM程序" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
|
<page string="CMM程序" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
|
||||||
<field name="cmm_ids" widget="one2many" string="CMM程序">
|
<field name="cmm_ids" widget="one2many" string="CMM程序" readonly="1">
|
||||||
<tree>
|
<tree>
|
||||||
<field name="sequence_number"/>
|
<field name="sequence_number"/>
|
||||||
<field name="program_name"/>
|
<field name="program_name"/>
|
||||||
<field name="cmm_id" string="文件"/>
|
<field name="program_path"/>
|
||||||
<field name="cutting_tool_name"/>
|
<field name="program_create_date"/>
|
||||||
<field name="cutting_tool_no"/>
|
|
||||||
<field name="processing_type"/>
|
|
||||||
<field name="margin_x_y"/>
|
|
||||||
<field name="margin_z"/>
|
|
||||||
<field name="depth_of_processing_z"/>
|
|
||||||
<field name="cutting_tool_extension_length"/>
|
|
||||||
<field name="cutting_tool_handle_type"/>
|
|
||||||
<field name="estimated_processing_time"/>
|
|
||||||
<field name="remark"/>
|
<field name="remark"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
@@ -574,8 +565,8 @@
|
|||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//form//sheet//group//group//div[3]" position="after">
|
<xpath expr="//form//sheet//group//group//div[3]" position="after">
|
||||||
<field name="is_ok"/>
|
<field name="is_ok"/>
|
||||||
<field name="processing_user_id"/>
|
<!-- <field name="processing_user_id"/>-->
|
||||||
<field name="inspection_user_id"/>
|
<!-- <field name="inspection_user_id"/>-->
|
||||||
<field name="save_name" widget="CopyClipboardChar"
|
<field name="save_name" widget="CopyClipboardChar"
|
||||||
attrs="{'invisible':[('routing_type','!=','装夹预调')]}"/>
|
attrs="{'invisible':[('routing_type','!=','装夹预调')]}"/>
|
||||||
<label for="material_length" string="物料尺寸"/>
|
<label for="material_length" string="物料尺寸"/>
|
||||||
@@ -590,6 +581,9 @@
|
|||||||
<field name="material_height" class="o_address_zip"/>
|
<field name="material_height" class="o_address_zip"/>
|
||||||
</div>
|
</div>
|
||||||
<field name="part_number" string="成品的零件图号"/>
|
<field name="part_number" string="成品的零件图号"/>
|
||||||
|
<field name="rfid_code" force_save="1" readonly="1" cache="True"
|
||||||
|
attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
|
||||||
|
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -24,82 +24,69 @@ class Sf_Mrs_Connect(http.Controller):
|
|||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
ret = json.loads(ret['result'])
|
ret = json.loads(ret['result'])
|
||||||
logging.info('下发编程单:%s' % ret)
|
logging.info('下发编程单:%s' % ret)
|
||||||
is_delete_file = False
|
productions = request.env['mrp.production'].with_user(
|
||||||
# 查询状态为进行中且类型为获取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(
|
|
||||||
request.env.ref("base.user_admin")).search(
|
request.env.ref("base.user_admin")).search(
|
||||||
[('programming_no', '=', cnc_production.programming_no), ('id', '!=', cnc_production.id)])
|
[('programming_no', '=', ret['programming_no'])])
|
||||||
if cnc_production.workorder_ids.filtered(lambda a: a.routing_type == 'CNC加工').cnc_ids:
|
if productions:
|
||||||
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'])
|
|
||||||
# 拉取所有加工面的程序文件
|
# 拉取所有加工面的程序文件
|
||||||
if is_delete_file is True:
|
for r in ret['processing_panel'].split(','):
|
||||||
program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', 'R')
|
program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r)
|
||||||
files_r = os.listdir(program_path_tmp_r)
|
files_r = os.listdir(program_path_tmp_r)
|
||||||
if files_r:
|
if files_r:
|
||||||
for file_name in files_r:
|
for file_name in files_r:
|
||||||
file_path = os.path.join(program_path_tmp_r, file_name)
|
file_path = os.path.join(program_path_tmp_r, file_name)
|
||||||
os.remove(file_path)
|
os.remove(file_path)
|
||||||
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(
|
ret['folder_name'], r)
|
||||||
ret['folder_name'], r)
|
if download_state == 0:
|
||||||
if download_state == 0:
|
res['status'] = -2
|
||||||
res['status'] = -2
|
res['message'] = '制造订单号为%s的CNC程序文件从FTP拉取失败' % (cnc_production.name)
|
||||||
res['message'] = '制造订单号为%s的CNC程序文件从FTP拉取失败' % (cnc_production.name)
|
return json.JSONEncoder().encode(res)
|
||||||
return json.JSONEncoder().encode(res)
|
for production in productions:
|
||||||
logging.info('创建cnc工单')
|
if not production.workorder_ids:
|
||||||
program_path_tmp = os.path.join('/tmp', ret['folder_name'], 'return', r)
|
production.product_id.model_processing_panel = ret['processing_panel']
|
||||||
# program_path_tmp = "C://Users//43484//Desktop//机企猫工作文档//其他//model_analysis"
|
production._create_workorder(ret)
|
||||||
files = os.listdir(program_path_tmp)
|
else:
|
||||||
cnc_processing_arr = []
|
for panel in ret['processing_panel'].split(','):
|
||||||
for f in files:
|
# 查询状态为进行中且工序类型为CNC加工的工单
|
||||||
program_path = os.path.join(program_path_tmp, f)
|
cnc_workorder = production.workorder_ids.filtered(
|
||||||
logging.info('cnc程序路径 :%s' % program_path)
|
lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done',
|
||||||
if f.endswith(".doc"):
|
'cancel'] and ac.processing_panel == panel)
|
||||||
# 插入cmm程序数据
|
if cnc_workorder:
|
||||||
cmm_program = request.env['sf.cmm.program'].with_user(
|
if cnc_workorder.cnc_ids:
|
||||||
request.env.ref("base.user_admin")).cmm_program_create(ret, program_path, program_path_tmp)
|
cnc_workorder.cmm_ids.sudo().unlink()
|
||||||
cnc_processing = request.env['sf.cnc.processing'].with_user(
|
cnc_workorder.cnc_ids.sudo().unlink()
|
||||||
request.env.ref("base.user_admin")).cnc_processing_create(cnc_production, ret, program_path,
|
request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(
|
||||||
program_path_tmp)
|
production)
|
||||||
logging.info('cnc_processing111:%s' % cnc_processing)
|
# program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
|
||||||
if cnc_processing:
|
# panel)
|
||||||
cnc_processing_arr.append(cnc_processing._json_cnc_processing(cnc_processing))
|
program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
|
||||||
if (cnc_program and cnc_processing_arr) or (not cnc_program and cnc_processing_arr):
|
logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
|
||||||
cnc_production.workorder_ids.filtered(lambda g: g.routing_type == '装夹预调').write(
|
files_panel = os.listdir(program_path_tmp_panel)
|
||||||
{'processing_drawing': cnc_production.workorder_ids.filtered(
|
if files_panel:
|
||||||
lambda g1: g1.routing_type == 'CNC加工').cnc_worksheet})
|
for file in files_panel:
|
||||||
if cnc_program and cnc_processing_arr:
|
file_extension = os.path.splitext(file)[1]
|
||||||
cnc_program.write({'programming_state': '已编程', 'work_state': '已编程'})
|
logging.info('file_extension:%s' % file_extension)
|
||||||
cnc_program.workorder_ids.filtered(lambda d: d.routing_type == '装夹预调').write(
|
if file_extension.lower() == '.pdf':
|
||||||
{'processing_drawing': cnc_production.workorder_ids.filtered(
|
panel_file_path = os.path.join(program_path_tmp_panel, file)
|
||||||
lambda d1: d1.routing_type == 'CNC加工').cnc_worksheet})
|
logging.info('panel_file_path:%s' % panel_file_path)
|
||||||
cnc_program.workorder_ids.filtered(lambda b: b.routing_type == 'CNC加工').write(
|
cnc_workorder.write(
|
||||||
{'cnc_ids': cnc_processing_arr, 'cnc_worksheet': cnc_production.workorder_ids.filtered(
|
{'cnc_ids': cnc_workorder.cnc_ids.sudo()._json_cnc_processing(panel, ret),
|
||||||
lambda b1: b1.routing_type == 'CNC加工').cnc_worksheet})
|
'cmm_ids': cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel, ret),
|
||||||
cnc_program |= cnc_production
|
'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||||
if not cnc_program and cnc_processing_arr:
|
pre_workorder = production.workorder_ids.filtered(
|
||||||
cnc_program = cnc_production
|
lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done',
|
||||||
cnc_program_ids = [item.id for item in cnc_program]
|
'cancel'] and ap.processing_panel == panel)
|
||||||
workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(
|
if pre_workorder:
|
||||||
[('production_id', 'in', cnc_program_ids)])
|
pre_workorder.write(
|
||||||
if workpiece_delivery:
|
{'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
|
||||||
workpiece_delivery.write({'is_cnc_program_down': True})
|
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)
|
return json.JSONEncoder().encode(res)
|
||||||
else:
|
else:
|
||||||
res = {'status': 0, 'message': '该制造订单暂未开始'}
|
res = {'status': 0, 'message': '该制造订单暂未开始'}
|
||||||
|
|||||||
@@ -200,22 +200,23 @@ class sf_production_plan(models.Model):
|
|||||||
raise ValidationError("未选择生产线")
|
raise ValidationError("未选择生产线")
|
||||||
else:
|
else:
|
||||||
workorder_id_list = record.production_id.workorder_ids.ids
|
workorder_id_list = record.production_id.workorder_ids.ids
|
||||||
if record.production_id.workorder_ids:
|
if record.production_id:
|
||||||
for item in record.production_id.workorder_ids:
|
if record.production_id.workorder_ids:
|
||||||
if item.name == 'CNC加工':
|
for item in record.production_id.workorder_ids:
|
||||||
item.date_planned_finished = datetime.now() + timedelta(days=100)
|
if item.name == 'CNC加工':
|
||||||
# item.date_planned_start = record.date_planned_start
|
item.date_planned_finished = datetime.now() + timedelta(days=100)
|
||||||
item.date_planned_start = self.date_planned_start if self.date_planned_start else datetime.now()
|
# item.date_planned_start = record.date_planned_start
|
||||||
record.sudo().production_id.plan_start_processing_time = item.date_planned_start
|
item.date_planned_start = self.date_planned_start if self.date_planned_start else datetime.now()
|
||||||
item.date_planned_finished = item.date_planned_start + timedelta(
|
record.sudo().production_id.plan_start_processing_time = item.date_planned_start
|
||||||
minutes=record.env['mrp.routing.workcenter'].sudo().search(
|
item.date_planned_finished = item.date_planned_start + timedelta(
|
||||||
[('name', '=', 'CNC加工')]).time_cycle)
|
minutes=record.env['mrp.routing.workcenter'].sudo().search(
|
||||||
item.duration_expected = record.env['mrp.routing.workcenter'].sudo().search(
|
[('name', '=', 'CNC加工')]).time_cycle)
|
||||||
[('name', '=', 'CNC加工')]).time_cycle
|
item.duration_expected = record.env['mrp.routing.workcenter'].sudo().search(
|
||||||
record.calculate_plan_time_before(item, workorder_id_list)
|
[('name', '=', 'CNC加工')]).time_cycle
|
||||||
record.calculate_plan_time_after(item, workorder_id_list)
|
record.calculate_plan_time_before(item, workorder_id_list)
|
||||||
record.date_planned_start, record.date_planned_finished = \
|
record.calculate_plan_time_after(item, workorder_id_list)
|
||||||
item.date_planned_start, item.date_planned_finished
|
record.date_planned_start, record.date_planned_finished = \
|
||||||
|
item.date_planned_start, item.date_planned_finished
|
||||||
record.state = 'done'
|
record.state = 'done'
|
||||||
# record.production_id.schedule_state = '已排'
|
# record.production_id.schedule_state = '已排'
|
||||||
record.sudo().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_start = record.date_planned_start
|
||||||
# record.production_id.date_planned_finished = record.date_planned_finished
|
# 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.production_line_id = record.production_line_id.id
|
||||||
record.sudo().production_id.workorder_ids.filtered(
|
if record.production_id.workorder_ids:
|
||||||
lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write(
|
record.sudo().production_id.workorder_ids.filtered(
|
||||||
{'production_line_id': record.production_line_id.id,
|
lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write(
|
||||||
'plan_start_processing_time': record.date_planned_start})
|
{'production_line_id': record.production_line_id.id,
|
||||||
else:
|
'plan_start_processing_time': record.date_planned_start})
|
||||||
raise ValidationError("未找到工单")
|
|
||||||
# record.date_planned_finished = record.date_planned_start + timedelta(days=3)
|
# record.date_planned_finished = record.date_planned_start + timedelta(days=3)
|
||||||
# record.state = 'done'
|
# record.state = 'done'
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user