Merge branch 'feature/无效刀返工' into feature/NC程序和功能刀具校验
# Conflicts: # sf_manufacturing/models/mrp_workorder.py
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
<field name="program_name"/>
|
||||
<field name="functional_tool_type_id"/>
|
||||
<field name="cutting_tool_name"/>
|
||||
<field name="tool_state"/>
|
||||
<field name="cutting_tool_no"/>
|
||||
<field name="processing_type"/>
|
||||
<field name="margin_x_y"/>
|
||||
|
||||
@@ -27,6 +27,43 @@ class MrpProduction(models.Model):
|
||||
string='工单状态', default='未排')
|
||||
|
||||
detection_result_ids = fields.One2many('sf.detection.result', 'production_id', '检测报告')
|
||||
tool_state = fields.Selection([('0', '正常'), ('1', '缺刀'), ('2', '无效刀')], string='功能刀具状态', default='0',
|
||||
store=True, compute='_compute_tool_state')
|
||||
tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', readonly=True)
|
||||
tool_state_remark2 = fields.Text(string='功能刀具状态备注(无效刀)', readonly=True)
|
||||
|
||||
@api.depends('workorder_ids.tool_state')
|
||||
def _compute_tool_state(self):
|
||||
for item in self:
|
||||
if item:
|
||||
workorder_ids = item.workorder_ids.filtered(lambda a: a.state not in ('rework', '返工'))
|
||||
if workorder_ids.filtered(lambda a: a.tool_state == '2'):
|
||||
item.tool_state = '2'
|
||||
elif workorder_ids.filtered(lambda a: a.tool_state == '1'):
|
||||
tool_state_remark = ''
|
||||
data = {}
|
||||
# 获取所有缺刀工单加工面对应缺的刀
|
||||
for work in workorder_ids.filtered(lambda a: a.tool_state == '1'):
|
||||
if work.processing_panel not in list(data.keys()):
|
||||
data.update({work.processing_panel: []})
|
||||
for cnc in work.cnc_ids.filtered(lambda a: a.tool_state == '1'):
|
||||
if cnc.cutting_tool_name not in data[work.processing_panel]:
|
||||
data[work.processing_panel].append(cnc.cutting_tool_name)
|
||||
# 按格式生成缺刀提示信息
|
||||
for key in data:
|
||||
if data.get(key) and not data.get(key):
|
||||
if tool_state_remark != '':
|
||||
tool_state_remark = f'{tool_state_remark}\n{key}缺刀:{data.get(key)}'
|
||||
else:
|
||||
tool_state_remark = f'{key}缺刀:{data.get(key)}'
|
||||
item.tool_state = '1'
|
||||
item.tool_state_remark = tool_state_remark
|
||||
item.tool_state_remark2 = ''
|
||||
else:
|
||||
item.tool_state = '0'
|
||||
item.tool_state_remark = ''
|
||||
item.tool_state_remark2 = ''
|
||||
|
||||
# state = fields.Selection(selection_add=[
|
||||
# ('pending_scheduling', '待排程'),
|
||||
# ('pending_processing', '待加工'),
|
||||
|
||||
@@ -13,7 +13,7 @@ from dateutil.relativedelta import relativedelta
|
||||
# import subprocess
|
||||
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||
from odoo.addons.sf_base.commons.common import Common
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.exceptions import UserError,ValidationError
|
||||
from odoo.addons.sf_mrs_connect.models.ftp_operate import FtpController
|
||||
|
||||
|
||||
@@ -170,6 +170,21 @@ class ResMrpWorkOrder(models.Model):
|
||||
# 加工图纸
|
||||
processing_drawing = fields.Binary(string='加工图纸')
|
||||
|
||||
# 功能刀具状态
|
||||
tool_state = fields.Selection([('0', '正常'), ('1', '缺刀'), ('2', '无效刀')], string='功能刀具状态', default='0',
|
||||
store=True, compute='_compute_tool_state')
|
||||
|
||||
@api.depends('cnc_ids.tool_state')
|
||||
def _compute_tool_state(self):
|
||||
for item in self:
|
||||
if item:
|
||||
if item.cnc_ids.filtered(lambda a: a.tool_state == '2'):
|
||||
item.tool_state = '2'
|
||||
elif item.cnc_ids.filtered(lambda a: a.tool_state == '1'):
|
||||
item.tool_state = '1'
|
||||
else:
|
||||
item.tool_state = '0'
|
||||
|
||||
@api.depends('production_id')
|
||||
def _compute_save_name(self):
|
||||
"""
|
||||
@@ -999,8 +1014,11 @@ class ResMrpWorkOrder(models.Model):
|
||||
rfid_code = workorder.rfid_code
|
||||
workorder.write({'rfid_code_old': rfid_code,
|
||||
'rfid_code': False})
|
||||
if workorder.rfid_code:
|
||||
raise ValidationError(f'【{workorder.name}】工单解绑失败,请重新点击完成按钮!!!')
|
||||
# workorder.rfid_code_old = rfid_code
|
||||
# workorder.rfid_code = False
|
||||
|
||||
if is_production_id is True and record.routing_type in ['解除装夹', '表面工艺']:
|
||||
logging.info('product_qty:%s' % record.production_id.product_qty)
|
||||
for move_raw_id in record.production_id.move_raw_ids:
|
||||
@@ -1094,6 +1112,8 @@ class CNCprocessing(models.Model):
|
||||
program_path = fields.Char('程序文件路径')
|
||||
program_create_date = fields.Datetime('程序创建日期')
|
||||
|
||||
tool_state = fields.Selection([('0', '正常'), ('1', '缺刀'), ('2', '无效刀')], string='刀具状态', default='0')
|
||||
|
||||
# mrs下发编程单创建CNC加工
|
||||
def cnc_processing_create(self, cnc_workorder, ret, program_path, program_path_tmp):
|
||||
cnc_processing = None
|
||||
|
||||
@@ -99,6 +99,9 @@
|
||||
<!-- <field name="production_line_state" readonly="1"/>-->
|
||||
<field name="part_number" string="成品的零件图号"/>
|
||||
<field name="part_drawing"/>
|
||||
<field name="tool_state"/>
|
||||
<field name="tool_state_remark" string="备注" attrs="{'invisible': [('tool_state', '!=', '1')]}"/>
|
||||
<field name="tool_state_remark2" string="备注" attrs="{'invisible': [('tool_state', '!=', '2')]}"/>
|
||||
</xpath>
|
||||
<xpath expr="//header//button[@name='action_cancel']" position="replace">
|
||||
<button name="action_cancel" type="object" string="取消" data-hotkey="z"
|
||||
@@ -421,7 +424,9 @@
|
||||
<xpath expr="//header//button[@name='action_cancel']" position="replace">
|
||||
<button name="action_cancel" type="object" string="取消" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='state']" position="after">
|
||||
<field name="tool_state" invisible="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
</field>
|
||||
<field name="state" position="after">
|
||||
<field name="work_state" optional="hide"/>
|
||||
<field name="tool_state" invisible="1"/>
|
||||
<field name="product_tmpl_name" invisible="1"/>
|
||||
</field>
|
||||
<field name="duration" position="replace">
|
||||
@@ -124,6 +125,7 @@
|
||||
</button>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='state']" position="before">
|
||||
<field name='tool_state' invisible="1"/>
|
||||
<field name='user_permissions' invisible="1"/>
|
||||
<field name='name' invisible="1"/>
|
||||
<field name='is_rework' invisible="1"/>
|
||||
@@ -513,6 +515,7 @@
|
||||
<field name="sequence_number"/>
|
||||
<field name="program_name"/>
|
||||
<field name="cutting_tool_name"/>
|
||||
<field name="tool_state"/>
|
||||
<field name="cutting_tool_no"/>
|
||||
<field name="processing_type"/>
|
||||
<field name="margin_x_y"/>
|
||||
|
||||
@@ -313,42 +313,27 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
|
||||
'applicant': None,
|
||||
'sf_functional_tool_assembly_id': None})
|
||||
|
||||
def create_cam_work_plan(self, cnc_processing_ids):
|
||||
def create_cam_work_plan(self, cnc_processing):
|
||||
"""
|
||||
根据传入的工单信息,查询是否有需要的功能刀具,如果没有则生成CAM工单程序用刀计划
|
||||
"""
|
||||
for cnc_processing in cnc_processing_ids:
|
||||
status = False
|
||||
if cnc_processing.cutting_tool_name:
|
||||
functional_tools = self.env['sf.real.time.distribution.of.functional.tools'].sudo().search(
|
||||
[('name', '=', cnc_processing.cutting_tool_name)])
|
||||
if functional_tools:
|
||||
for functional_tool in functional_tools:
|
||||
if functional_tool.on_tool_stock_num == 0:
|
||||
if functional_tool.tool_stock_num == 0 and functional_tool.side_shelf_num == 0:
|
||||
status = True
|
||||
else:
|
||||
status = True
|
||||
if status:
|
||||
knife_plan = self.env['sf.cam.work.order.program.knife.plan'].sudo().create({
|
||||
'name': cnc_processing.workorder_id.production_id.name,
|
||||
'cam_procedure_code': cnc_processing.program_name,
|
||||
'filename': cnc_processing.cnc_id.name,
|
||||
'functional_tool_name': cnc_processing.cutting_tool_name,
|
||||
'cam_cutter_spacing_code': cnc_processing.cutting_tool_no,
|
||||
'process_type': cnc_processing.processing_type,
|
||||
'margin_x_y': float(cnc_processing.margin_x_y),
|
||||
'margin_z': float(cnc_processing.margin_z),
|
||||
'finish_depth': float(cnc_processing.depth_of_processing_z),
|
||||
'extension_length': float(cnc_processing.cutting_tool_extension_length),
|
||||
'shank_model': cnc_processing.cutting_tool_handle_type,
|
||||
'estimated_processing_time': cnc_processing.estimated_processing_time,
|
||||
})
|
||||
logging.info('CAM工单程序用刀计划创建成功!!!')
|
||||
# 创建装刀请求
|
||||
knife_plan.apply_for_tooling()
|
||||
else:
|
||||
logging.info('功能刀具【%s】满足CNC用刀需求!!!' % cnc_processing.cutting_tool_name)
|
||||
knife_plan = self.env['sf.cam.work.order.program.knife.plan'].sudo().create({
|
||||
'name': cnc_processing.workorder_id.production_id.name,
|
||||
'cam_procedure_code': cnc_processing.program_name,
|
||||
'filename': cnc_processing.cnc_id.name,
|
||||
'functional_tool_name': cnc_processing.cutting_tool_name,
|
||||
'cam_cutter_spacing_code': cnc_processing.cutting_tool_no,
|
||||
'process_type': cnc_processing.processing_type,
|
||||
'margin_x_y': float(cnc_processing.margin_x_y),
|
||||
'margin_z': float(cnc_processing.margin_z),
|
||||
'finish_depth': float(cnc_processing.depth_of_processing_z),
|
||||
'extension_length': float(cnc_processing.cutting_tool_extension_length),
|
||||
'shank_model': cnc_processing.cutting_tool_handle_type,
|
||||
'estimated_processing_time': cnc_processing.estimated_processing_time,
|
||||
})
|
||||
logging.info('CAM工单程序用刀计划创建成功!!!')
|
||||
# 创建装刀请求
|
||||
knife_plan.apply_for_tooling()
|
||||
|
||||
def unlink_cam_plan(self, production):
|
||||
for item in production:
|
||||
@@ -834,7 +819,7 @@ class FunctionalToolDismantle(models.Model):
|
||||
integral_lot_id = fields.Many2one('stock.lot', string='整体式刀具批次', compute='_compute_functional_tool_num',
|
||||
store=True)
|
||||
integral_freight_id = fields.Many2one('sf.shelf.location', '整体式刀具目标货位',
|
||||
domain="[('product_id', 'in', (integral_product_id, False))]")
|
||||
domain="[('product_id', 'in', (integral_product_id, False)),('location_id.name', '=', '刀具房')]")
|
||||
|
||||
# 刀片
|
||||
blade_product_id = fields.Many2one('product.product', string='刀片', compute='_compute_functional_tool_num',
|
||||
@@ -844,7 +829,7 @@ class FunctionalToolDismantle(models.Model):
|
||||
blade_brand_id = fields.Many2one('sf.machine.brand', string='刀片品牌', related='blade_product_id.brand_id')
|
||||
blade_lot_id = fields.Many2one('stock.lot', string='刀片批次', compute='_compute_functional_tool_num', store=True)
|
||||
blade_freight_id = fields.Many2one('sf.shelf.location', '刀片目标货位',
|
||||
domain="[('product_id', 'in', (blade_product_id, False))]")
|
||||
domain="[('product_id', 'in', (blade_product_id, False)),('location_id.name', '=', '刀具房')]")
|
||||
|
||||
# 刀杆
|
||||
bar_product_id = fields.Many2one('product.product', string='刀杆', compute='_compute_functional_tool_num',
|
||||
@@ -854,7 +839,7 @@ class FunctionalToolDismantle(models.Model):
|
||||
bar_brand_id = fields.Many2one('sf.machine.brand', string='刀杆品牌', related='bar_product_id.brand_id')
|
||||
bar_lot_id = fields.Many2one('stock.lot', string='刀杆批次', compute='_compute_functional_tool_num', store=True)
|
||||
bar_freight_id = fields.Many2one('sf.shelf.location', '刀杆目标货位',
|
||||
domain="[('product_id', 'in', (bar_product_id, False))]")
|
||||
domain="[('product_id', 'in', (bar_product_id, False)),('location_id.name', '=', '刀具房')]")
|
||||
|
||||
# 刀盘
|
||||
pad_product_id = fields.Many2one('product.product', string='刀盘', compute='_compute_functional_tool_num',
|
||||
@@ -864,7 +849,7 @@ class FunctionalToolDismantle(models.Model):
|
||||
pad_brand_id = fields.Many2one('sf.machine.brand', string='刀盘品牌', related='pad_product_id.brand_id')
|
||||
pad_lot_id = fields.Many2one('stock.lot', string='刀盘批次', compute='_compute_functional_tool_num', store=True)
|
||||
pad_freight_id = fields.Many2one('sf.shelf.location', '刀盘目标货位',
|
||||
domain="[('product_id', 'in', (pad_product_id, False))]")
|
||||
domain="[('product_id', 'in', (pad_product_id, False)),('location_id.name', '=', '刀具房')]")
|
||||
|
||||
# 夹头
|
||||
chuck_product_id = fields.Many2one('product.product', string='夹头', compute='_compute_functional_tool_num',
|
||||
@@ -874,7 +859,7 @@ class FunctionalToolDismantle(models.Model):
|
||||
chuck_brand_id = fields.Many2one('sf.machine.brand', string='夹头品牌', related='chuck_product_id.brand_id')
|
||||
chuck_lot_id = fields.Many2one('stock.lot', string='夹头批次', compute='_compute_functional_tool_num', store=True)
|
||||
chuck_freight_id = fields.Many2one('sf.shelf.location', '夹头目标货位',
|
||||
domain="[('product_id', 'in', (chuck_product_id, False))]")
|
||||
domain="[('product_id', 'in', (chuck_product_id, False)),('location_id.name', '=', '刀具房')]")
|
||||
|
||||
@api.onchange('functional_tool_id')
|
||||
def _onchange_freight(self):
|
||||
|
||||
@@ -255,6 +255,16 @@ class FunctionalCuttingToolEntity(models.Model):
|
||||
result['domain'] = [('id', '=', self.safe_inventory_id.id)]
|
||||
return result
|
||||
|
||||
def cnc_function_tool_use_verify(self):
|
||||
"""
|
||||
cnc程序用刀可用校验(校验是否是制造订单所缺刀)
|
||||
"""
|
||||
if self.tool_name_id.name:
|
||||
cnc_processing_ids = self.env['sf.cnc.processing'].search(
|
||||
[('tool_state', '=', '1'), ('cutting_tool_name', '=', self.tool_name_id.name)])
|
||||
if cnc_processing_ids:
|
||||
cnc_processing_ids.sudo().write({'tool_state': '0'})
|
||||
|
||||
def tool_inventory_displacement_out(self):
|
||||
"""
|
||||
机床当前刀库实时信息接口,功能刀具出库
|
||||
@@ -265,6 +275,7 @@ class FunctionalCuttingToolEntity(models.Model):
|
||||
self.create_stock_move(stock_location_id, False)
|
||||
self.current_location_id = stock_location_id.id
|
||||
self.current_shelf_location_id = False
|
||||
|
||||
# self.barcode_id.create_stock_quant(location_inventory_id, stock_location_id,
|
||||
# self.functional_tool_name_id.id, '机床装刀', self.functional_tool_name_id,
|
||||
# self.functional_tool_name_id.tool_groups_id)
|
||||
|
||||
@@ -29,13 +29,105 @@ class CNCprocessing(models.Model):
|
||||
# else:
|
||||
# raise ValidationError("MES装刀指令发送失败")
|
||||
|
||||
def cnc_tool_checkout(self, cnc_processing_ids):
|
||||
"""
|
||||
根据传入的工单信息,查询是否有需要的功能刀具,如果没有则生成CAM工单程序用刀计划
|
||||
"""
|
||||
cam_id = self.env['sf.cam.work.order.program.knife.plan']
|
||||
production_ids = [] # 制造订单集
|
||||
datas = {'缺刀': {}, '无效刀': {}} # 缺刀/无效刀集
|
||||
for cnc_processing in cnc_processing_ids:
|
||||
# ======创建字典: {'缺刀': {'制造订单1': {'加工面1': [], ...}, ...}, '无效刀': {'制造订单1': {'加工面1': [], ...}, ...}}======
|
||||
production_name = cnc_processing.production_id.name # 制造订单
|
||||
processing_panel = cnc_processing.workorder_id.processing_panel # 加工面
|
||||
if production_name not in list(datas['缺刀'].keys()):
|
||||
datas['缺刀'].update({production_name: {processing_panel: []}})
|
||||
datas['无效刀'].update({production_name: {processing_panel: []}})
|
||||
production_ids.append(cnc_processing.production_id)
|
||||
else:
|
||||
if processing_panel not in list[datas['缺刀'].get(production_name).keys()]:
|
||||
datas['缺刀'].get(production_name).update({processing_panel: []})
|
||||
datas['无效刀'].get(production_name).update({processing_panel: []})
|
||||
# ======================================
|
||||
if cnc_processing.cutting_tool_name:
|
||||
tool_name = cnc_processing.cutting_tool_name
|
||||
# 检验CNC用刀是否是功能刀具清单中的刀具
|
||||
tool_inventory_id = self.env['sf.tool.inventory'].sudo().search([('name', '=', tool_name)])
|
||||
if not tool_inventory_id:
|
||||
if cnc_processing.cutting_tool_name not in datas['无效刀'][production_name][processing_panel]:
|
||||
datas['无效刀'][production_name][processing_panel].append(cnc_processing.cutting_tool_name)
|
||||
cnc_processing.tool_state = '2'
|
||||
logging.info(f'"无效刀":[{production_name}、{processing_panel}、{cnc_processing.cutting_tool_name}]')
|
||||
# 跳过本次循环
|
||||
continue
|
||||
# 校验CNC用刀在系统是否存在
|
||||
functional_tools = self.env['sf.functional.cutting.tool.entity'].sudo().search(
|
||||
[('tool_name_id', '=', tool_inventory_id.id), ('functional_tool_status', '=', '正常')])
|
||||
# 判断线边、机内是否有满足条件的刀
|
||||
if not functional_tools.filtered(lambda p: p.current_location in ('线边刀库', '机内刀库')):
|
||||
if cnc_processing.cutting_tool_name not in datas['缺刀'][production_name][processing_panel]:
|
||||
datas['缺刀'][production_name][processing_panel].append(cnc_processing.cutting_tool_name)
|
||||
cnc_processing.tool_state = '1'
|
||||
logging.info(f'"缺刀":[{production_name}、{processing_panel}、{cnc_processing.cutting_tool_name}]')
|
||||
# 判断是否有满足条件的刀
|
||||
if not functional_tools:
|
||||
# 创建CAM申请装刀记录
|
||||
cam_id.create_cam_work_plan(cnc_processing)
|
||||
logging.info('成功调用CAM工单程序用刀计划创建方法!!!')
|
||||
logging.info(datas)
|
||||
for production_id in production_ids:
|
||||
if production_id:
|
||||
data1 = datas['无效刀'].get(production_id.name) # data1: {'加工面1': [], ...}
|
||||
data2 = datas['缺刀'].get(production_id.name) # data2: {'加工面1': [], ...}
|
||||
tool_state_remark1 = ''
|
||||
tool_state_remark2 = ''
|
||||
# 对无效刀信息进行处理
|
||||
for key in data1:
|
||||
if data1.get(key):
|
||||
if tool_state_remark1 != '':
|
||||
tool_state_remark1 = f'{tool_state_remark1}\n{key}无效刀:{data1.get(key)}'
|
||||
else:
|
||||
tool_state_remark1 = f'{key}无效刀:{data1.get(key)}'
|
||||
# 无效刀处理逻辑
|
||||
# 1、创建制造订单无效刀检测结果记录
|
||||
production_id.detection_result_ids.create({
|
||||
'production_id': production_id.id,
|
||||
'processing_panel': key,
|
||||
'routing_type': 'CNC加工',
|
||||
'rework_reason': 'programming', # 原因:编程(programming)
|
||||
'detailed_reason': '无效功能刀具',
|
||||
'test_results': '返工',
|
||||
'handle_result': '待处理'
|
||||
})
|
||||
# 2、将制造订单状态改为返工
|
||||
production_id.write({
|
||||
'state': 'rework'
|
||||
})
|
||||
# 对缺刀信息进行处理
|
||||
if tool_state_remark1 == '':
|
||||
for key in data2:
|
||||
if data2.get(key) and not data1.get(key):
|
||||
if tool_state_remark2 != '':
|
||||
tool_state_remark2 = f'{tool_state_remark2}\n{key}缺刀:{data2.get(key)}'
|
||||
else:
|
||||
tool_state_remark2 = f'{key}缺刀:{data2.get(key)}'
|
||||
# 将备注信息存入制造订单功能刀具状态的备注字段
|
||||
if production_id.tool_state_remark2 == '':
|
||||
production_id.write({
|
||||
'tool_state_remark': tool_state_remark2,
|
||||
'tool_state_remark2': tool_state_remark1
|
||||
})
|
||||
else:
|
||||
production_id.write({
|
||||
'tool_state_remark': tool_state_remark2,
|
||||
'tool_state_remark2': f'{production_id.tool_state_remark1}\n{tool_state_remark1}'
|
||||
})
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals):
|
||||
obj = super(CNCprocessing, self).create(vals)
|
||||
for item in obj:
|
||||
# 调用CAM工单程序用刀计划创建方法
|
||||
self.env['sf.cam.work.order.program.knife.plan'].create_cam_work_plan(item)
|
||||
logging.info('成功调用CAM工单程序用刀计划创建方法!!!')
|
||||
# 调用CAM工单程序用刀计划创建方法
|
||||
self.cnc_tool_checkout(obj)
|
||||
return obj
|
||||
|
||||
|
||||
|
||||
@@ -21,3 +21,40 @@ class ShelfLocation(models.Model):
|
||||
continue
|
||||
item.tool_rfid = ''
|
||||
item.tool_name_id = False
|
||||
|
||||
|
||||
class StockMoveLine(models.Model):
|
||||
_inherit = 'stock.move.line'
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
records = super(StockMoveLine, self).create(vals_list)
|
||||
move_lines = records.filtered(lambda a: a.product_id.categ_id.name == '功能刀具' and a.state == 'done')
|
||||
if move_lines: # 校验是否为功能刀具移动历史
|
||||
self.button_function_tool_use_verify(move_lines)
|
||||
return records
|
||||
|
||||
def button_function_tool_use_verify(self, move_lines):
|
||||
"""
|
||||
对所有从【刀具房】到【制造前】的功能刀具进行校验(校验是否为制造订单所缺的刀)
|
||||
"""
|
||||
location_id = self.env['stock.location'].search([('name', '=', '刀具房')])
|
||||
location_dest_id = self.env['stock.location'].search([('name', '=', '制造前')])
|
||||
line_ids = move_lines.filtered(
|
||||
lambda a: a.location_id == location_id and a.location_dest_id == location_dest_id)
|
||||
for line_id in line_ids:
|
||||
if line_id.lot_id:
|
||||
self.env['sf.functional.cutting.tool.entity'].sudo().search(
|
||||
[('barcode_id', '=', line_id.lot_id.id),
|
||||
('functional_tool_status', '=', '正常')]).cnc_function_tool_use_verify()
|
||||
|
||||
|
||||
class StockPicking(models.Model):
|
||||
_inherit = 'stock.picking'
|
||||
|
||||
def button_validate(self):
|
||||
res = super().button_validate()
|
||||
move_lines = self.move_line_ids.filtered(lambda a: a.product_id.categ_id.name == '功能刀具')
|
||||
if move_lines:
|
||||
self.env['stock.move.line'].sudo().button_function_tool_use_verify(move_lines)
|
||||
return res
|
||||
|
||||
Reference in New Issue
Block a user