diff --git a/sf_tool_management/controllers/controllers.py b/sf_tool_management/controllers/controllers.py index 4b0909dc..b3ca0224 100644 --- a/sf_tool_management/controllers/controllers.py +++ b/sf_tool_management/controllers/controllers.py @@ -122,7 +122,8 @@ class Manufacturing_Connect(http.Controller): tool_assembly.write({ 'after_assembly_tool_loading_length': float(data_list[1] or "0"), # 高度(总长度) 'after_assembly_functional_tool_diameter': float(data_list[2] or "0") * 2, # 直径 - 'after_assembly_knife_tip_r_angle': float(data_list[3] or "0") # R角 + 'after_assembly_knife_tip_r_angle': float(data_list[3] or "0"), # R角 + 'bool_preset_parameter': True }) except Exception as e: res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 518c4c0f..76fb20ff 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -358,6 +358,7 @@ class FunctionalToolAssembly(models.Model): 智能工厂组装单处扫码校验刀具物料 """ for record in self: + tool_assembly_id = self.env['sf.functional.tool.assembly'].browse(self.ids) lot_ids = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)]) if lot_ids: for lot_id in lot_ids: @@ -365,26 +366,31 @@ class FunctionalToolAssembly(models.Model): raise ValidationError(f'Rfid为【{barcode}】的刀柄已被占用,请重新扫描!!') if lot_id.product_id == record.handle_product_id: record.handle_code_id = lot_id.id - record.handle_verify = True + tool_assembly_id.handle_code_id = lot_id.id else: - raise ValidationError('刀具选择错误,请重新确认!!!') + raise ValidationError('刀柄选择错误,请重新确认!!!') else: location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', barcode)]) if location: if location == record.integral_freight_barcode_id: + tool_assembly_id.integral_verify = True record.integral_verify = True elif location == record.blade_freight_barcode_id: + tool_assembly_id.blade_verify = True record.blade_verify = True elif location == record.bar_freight_barcode_id: + tool_assembly_id.bar_verify = True record.bar_verify = True elif location == record.pad_freight_barcode_id: + tool_assembly_id.pad_verify = True record.pad_verify = True elif location == record.chuck_freight_barcode_id: + tool_assembly_id.chuck_verify = True record.chuck_verify = True else: raise ValidationError('刀具选择错误,请重新确认!') else: - raise ValidationError(f'扫描为【{barcode}】的刀具不存在,请重新扫描!') + raise ValidationError(f'扫描为【{barcode}】的货位不存在,请重新扫描!') @api.depends('functional_tool_name') def _compute_name(self): @@ -472,12 +478,9 @@ class FunctionalToolAssembly(models.Model): # 刀具物料信息 # ==============整体式刀具型号============= - integral_freight_barcode_id = fields.Many2one('sf.shelf.location', string='整体式刀具货位', + integral_freight_barcode_id = fields.Many2one('sf.shelf.location', string='整体式刀具货位', readonly=True, domain="[('product_id.cutting_tool_material_id.name', '=', '整体式刀具'),('product_num', '>', 0)]") - integral_freight_lot_id = fields.Many2one('sf.shelf.location.lot', string='整体式刀具批次', - domain="[('shelf_location_id', '=', integral_freight_barcode_id)]") - integral_lot_id = fields.Many2one('stock.lot', string='整体式刀具批次', compute='_compute_integral_lot_id', - store=True) + integral_lot_id = fields.Many2one('stock.lot', string='整体式刀具批次', readonly=True) integral_product_id = fields.Many2one('product.product', string='整体式刀具名称', compute='_compute_integral_product_id', store=True) cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号', @@ -488,19 +491,6 @@ class FunctionalToolAssembly(models.Model): related='integral_product_id.brand_id') integral_verify = fields.Boolean('整体刀校验', default=False) - @api.onchange('integral_freight_barcode_id') - def _onchange_integral_freight_barcode_id(self): - for item in self: - item.integral_freight_lot_id = False - - @api.depends('integral_freight_lot_id', 'integral_freight_barcode_id') - def _compute_integral_lot_id(self): - for item in self: - if item.integral_freight_lot_id: - item.integral_lot_id = item.integral_freight_lot_id.lot_id.id - elif not item.integral_freight_barcode_id: - item.integral_lot_id = False - @api.depends('integral_lot_id') def _compute_integral_product_id(self): for item in self: @@ -510,11 +500,9 @@ class FunctionalToolAssembly(models.Model): item.integral_product_id = False # =================刀片型号============= - blade_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀片货位', + blade_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀片货位', readonly=True, domain="[('product_id.cutting_tool_material_id.name', '=', '刀片'),('product_num', '>', 0)]") - blade_freight_lot_id = fields.Many2one('sf.shelf.location.lot', string='刀片批次', - domain="[('shelf_location_id', '=', blade_freight_barcode_id)]") - blade_lot_id = fields.Many2one('stock.lot', string='刀片批次', compute='blade_freight_lot_id.lot_id', store=True) + blade_lot_id = fields.Many2one('stock.lot', string='刀片批次', readonly=True) blade_product_id = fields.Many2one('product.product', string='刀片名称', compute='_compute_blade_product_id', store=True) cutting_tool_blade_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀片型号', @@ -524,19 +512,6 @@ class FunctionalToolAssembly(models.Model): sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', related='blade_product_id.brand_id') blade_verify = fields.Boolean('刀片校验', default=False) - @api.onchange('blade_freight_barcode_id') - def _onchange_blade_freight_barcode_id(self): - for item in self: - item.blade_freight_lot_id = False - - @api.depends('blade_freight_lot_id', 'blade_freight_barcode_id') - def _compute_blade_lot_id(self): - for item in self: - if item.blade_freight_lot_id: - item.blade_lot_id = item.blade_freight_lot_id.lot_id.id - elif not item.blade_freight_barcode_id: - item.blade_lot_id = False - @api.depends('blade_lot_id') def _compute_blade_product_id(self): for item in self: @@ -546,11 +521,9 @@ class FunctionalToolAssembly(models.Model): item.blade_product_id = False # ==============刀杆型号================ - bar_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀杆货位', + bar_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀杆货位', readonly=True, domain="[('product_id.cutting_tool_material_id.name', '=', '刀杆'),('product_num', '>', 0)]") - bar_freight_lot_id = fields.Many2one('sf.shelf.location.lot', string='刀杆批次', - domain="[('shelf_location_id', '=', bar_freight_barcode_id)]") - bar_lot_id = fields.Many2one('stock.lot', string='刀杆批次', compute='_compute_bar_lot_id', store=True) + bar_lot_id = fields.Many2one('stock.lot', string='刀杆批次', readonly=True) bar_product_id = fields.Many2one('product.product', string='刀杆名称', compute='_compute_bar_product_id', store=True) cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号', @@ -558,20 +531,7 @@ class FunctionalToolAssembly(models.Model): bar_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀杆规格', related='bar_product_id.specification_id') sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', related='bar_product_id.brand_id') - brand_verify = fields.Boolean('刀杆校验', default=False) - - @api.onchange('bar_freight_barcode_id') - def _onchange_bar_freight_barcode_id(self): - for item in self: - item.bar_freight_lot_id = False - - @api.depends('bar_freight_lot_id', 'bar_freight_barcode_id') - def _compute_bar_lot_id(self): - for item in self: - if item.bar_freight_lot_id: - item.bar_lot_id = item.bar_freight_lot_id.lot_id.id - elif not item.bar_freight_barcode_id: - item.bar_lot_id = False + bar_verify = fields.Boolean('刀杆校验', default=False) @api.depends('bar_lot_id') def _compute_bar_product_id(self): @@ -582,11 +542,9 @@ class FunctionalToolAssembly(models.Model): item.bar_product_id = False # =============刀盘型号================ - pad_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀盘货位', + pad_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀盘货位', readonly=True, domain="[('product_id.cutting_tool_material_id.name', '=', '刀盘'),('product_num', '>', 0)]") - pad_freight_lot_id = fields.Many2one('sf.shelf.location.lot', string='刀盘批次', - domain="[('shelf_location_id', '=', pad_freight_barcode_id)]") - pad_lot_id = fields.Many2one('stock.lot', string='刀盘批次', compute='_compute_pad_lot_id', store=True) + pad_lot_id = fields.Many2one('stock.lot', string='刀盘批次', readonly=True) pad_product_id = fields.Many2one('product.product', string='刀盘名称', compute='_compute_pad_product_id', store=True) cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号', @@ -596,19 +554,6 @@ class FunctionalToolAssembly(models.Model): sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', related='pad_product_id.brand_id') pad_verify = fields.Boolean('刀盘校验', default=False) - @api.onchange('pad_freight_barcode_id') - def _onchange_pad_freight_barcode_id(self): - for item in self: - item.pad_freight_lot_id = False - - @api.depends('pad_freight_lot_id', 'pad_freight_barcode_id') - def _compute_pad_lot_id(self): - for item in self: - if item.pad_freight_lot_id: - item.pad_lot_id = item.pad_freight_lot_id.lot_id.id - elif not item.pad_freight_barcode_id: - item.pad_lot_id = False - @api.depends('pad_lot_id') def _compute_pad_product_id(self): for item in self: @@ -618,12 +563,10 @@ class FunctionalToolAssembly(models.Model): item.pad_product_id = False # ==============刀柄型号============== - handle_freight_rfid = fields.Char('刀柄Rfid', compute='_compute_handle_product_id', store=True) - handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', - domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄'), - ('tool_material_status', '=', '可用')]) - handle_product_id = fields.Many2one('product.product', string='刀柄名称', compute='_compute_handle_product_id', - store=True) + handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', readonly=True, + domain="[('product_id', '=', handle_product_id)]") + handle_freight_rfid = fields.Char('刀柄Rfid', compute='_compute_handle_rfid', store=True) + handle_product_id = fields.Many2one('product.product', string='刀柄名称', readonly=True) cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号', related='handle_product_id.cutting_tool_model_id') handle_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀柄规格', @@ -632,23 +575,19 @@ class FunctionalToolAssembly(models.Model): handle_verify = fields.Boolean('刀柄校验', default=False) @api.depends('handle_code_id') - def _compute_handle_product_id(self): + def _compute_handle_rfid(self): for item in self: if item.handle_code_id: - item.handle_product_id = item.handle_code_id.product_id.id item.handle_freight_rfid = item.handle_code_id.rfid item.rfid = item.handle_freight_rfid else: - item.handle_product_id = False item.handle_freight_rfid = False item.rfid = False # ==============夹头型号============== - chuck_freight_barcode_id = fields.Many2one('sf.shelf.location', string='夹头货位', + chuck_freight_barcode_id = fields.Many2one('sf.shelf.location', string='夹头货位', readonly=True, domain="[('product_id.cutting_tool_material_id.name', '=', '夹头'),('product_num', '>', 0)]") - chuck_freight_lot_id = fields.Many2one('sf.shelf.location.lot', string='夹头批次', - domain="[('shelf_location_id', '=', chuck_freight_barcode_id)]") - chuck_lot_id = fields.Many2one('stock.lot', string='夹头批次', compute='_compute_chuck_lot_id', store=True) + chuck_lot_id = fields.Many2one('stock.lot', string='夹头批次', readonly=True) chuck_product_id = fields.Many2one('product.product', string='夹头名称', compute='_compute_chuck_product_id', store=True) cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号', @@ -658,19 +597,6 @@ class FunctionalToolAssembly(models.Model): sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', related='chuck_product_id.brand_id') chuck_verify = fields.Boolean('夹头校验', default=False) - @api.onchange('chuck_freight_barcode_id') - def _onchange_chuck_freight_barcode_id(self): - for item in self: - item.chuck_freight_lot_id = False - - @api.depends('chuck_freight_lot_id', 'chuck_freight_barcode_id') - def _compute_chuck_lot_id(self): - for item in self: - if item.chuck_freight_lot_id: - item.chuck_lot_id = item.chuck_freight_lot_id.lot_id.id - elif not item.chuck_freight_barcode_id: - item.chuck_lot_id = False - @api.depends('chuck_lot_id') def _compute_chuck_product_id(self): for item in self: @@ -841,7 +767,8 @@ class FunctionalToolAssembly(models.Model): # 配置刀柄信息 for handle_id in bom.get('handle_ids'): if handle_id: - self.handle_product_id = handle_id.id + if not self.handle_product_id: + self.handle_product_id = handle_id.id break # 刀柄之外的物料配置 @@ -850,26 +777,26 @@ class FunctionalToolAssembly(models.Model): integra_lot_id = self._get_old_tool_material_lot(bom.get('integral_ids')) integra_location_lot_id = self._get_shelf_location_lot(integra_lot_id) self.integral_freight_barcode_id = integra_location_lot_id.shelf_location_id.id - self.integral_freight_lot_id = integra_location_lot_id.id + self.integral_lot_id = integra_location_lot_id.lot_id.id else: # 配置刀片 blade_lot_id = self._get_old_tool_material_lot(bom.get('blade_ids')) blade_location_lot_id = self._get_shelf_location_lot(blade_lot_id) self.blade_freight_barcode_id = blade_location_lot_id.shelf_location_id.id - self.blade_freight_lot_id = blade_location_lot_id.id + self.blade_lot_id = blade_location_lot_id.lot_id.id if options == '刀柄+刀杆+刀片': # 配置刀杆 bar_lot_id = self._get_old_tool_material_lot(bom.get('bar_ids')) bar_location_lot_id = self._get_shelf_location_lot(bar_lot_id) self.bar_freight_barcode_id = bar_location_lot_id.shelf_location_id.id - self.bar_freight_lot_id = bar_location_lot_id.id + self.bar_lot_id = bar_location_lot_id.lot_id.id elif options == '刀柄+刀盘+刀片': # 配置刀盘 pad_lot_id = self._get_old_tool_material_lot(bom.get('pad_ids')) pad_location_lot_id = self._get_shelf_location_lot(pad_lot_id) self.pad_freight_barcode_id = pad_location_lot_id.shelf_location_id.id - self.pad_freight_lot_id = pad_location_lot_id.id + self.pad_lot_id = pad_location_lot_id.lot_id.id def _get_old_tool_material_lot(self, material_ids): """ 根据先进先出原则选择物料批次 """ @@ -896,7 +823,7 @@ class FunctionalToolAssembly(models.Model): options = inventory_id.jikimo_bom_ids.options # BOM产品组装类型 if not product_ids or not options: - raise ValidationError('功能刀具清单的BOM未进行配置,请先配置BOM再开始组装!') + raise ValidationError('功能刀具清单的BOM未进行配置,请先配置BOM信息!') handle_ids = product_ids.filtered(lambda a: a.cutting_tool_material_id.name == '刀柄') integral_ids = product_ids.filtered(lambda a: a.cutting_tool_material_id.name == '整体式刀具') blade_ids = product_ids.filtered(lambda a: a.cutting_tool_material_id.name == '刀片') @@ -934,39 +861,46 @@ class FunctionalToolAssembly(models.Model): if tool_type == '刀柄': tool_material_ids = tool_data.get('handle_ids') + tool_material_tree_id = self.env.ref('sf_tool_management.view_tool_product_tree') elif tool_type == '整体式刀具': tool_material_ids = self._get_all_material_location_lot(tool_data.get('integral_ids')) + tool_material_tree_id = self.env.ref('sf_tool_management.view_shelf_location_lot_tree_1') elif tool_type == '刀片': - tool_material_ids = self._get_all_material_location_lot(tool_data.get('handle_ids')) + tool_material_ids = self._get_all_material_location_lot(tool_data.get('blade_ids')) + tool_material_tree_id = self.env.ref('sf_tool_management.view_shelf_location_lot_tree_2') elif tool_type == '刀杆': tool_material_ids = self._get_all_material_location_lot(tool_data.get('bar_ids')) + tool_material_tree_id = self.env.ref('sf_tool_management.view_shelf_location_lot_tree_3') else: tool_material_ids = self._get_all_material_location_lot(tool_data.get('pad_ids')) + tool_material_tree_id = self.env.ref('sf_tool_management.view_shelf_location_lot_tree_4') if tool_type == '刀柄': return { "type": "ir.actions.act_window", "res_model": "product.product", - "views": [[self.env.ref('sf_tool_management.view_tool_product_tree').id, "tree"], + "views": [[tool_material_tree_id.id, "tree"], [self.env.ref('sf_tool_management.view_tool_product_search').id, "search"]], "target": "new", - "domain": [('id', 'in', tool_material_ids.ids)] + "domain": [('id', 'in', tool_material_ids.ids)], + "context": {'tool_id': self.id} } elif tool_type in ['整体式刀具', '刀片', '刀杆', '刀盘']: return { "type": "ir.actions.act_window", "res_model": "sf.shelf.location.lot", - "views": [[False, "tree"]], + "views": [[tool_material_tree_id.id, "tree"]], "target": "new", "domain": [('id', 'in', tool_material_ids.ids)], - "context": {'create': False} + "context": {'tool_id': self.id} } def _get_all_material_location_lot(self, material_ids): """ 获取所有满足条件 """ location_id = self.env['stock.location'].search([('name', '=', '刀具房')]) stock_quant_ids = self.env['stock.quant'].sudo().search( - [('location_id', '=', location_id.id), ('product_id', 'in', material_ids.ids), ('quantity', '>', '0')]) + [('location_id', '=', location_id.id), ('product_id', 'in', material_ids.ids if material_ids else []), + ('quantity', '>', '0')]) lot_ids = [] for stock_quant_id in stock_quant_ids: lot_ids.append(stock_quant_id.lot_id.id) @@ -1033,22 +967,21 @@ class FunctionalToolAssembly(models.Model): # 物料必填校验 if not self.handle_code_id: raise ValidationError('缺少【刀柄】物料信息!') - if not self.integral_product_id and not self.blade_product_id: - raise ValidationError('【整体式刀具】和【刀片】必须填写一个!') - if self.blade_product_id: - if not self.bar_product_id and not self.pad_product_id: - raise ValidationError('【刀盘】和【刀杆】必须填写一个!') + if self.integral_lot_id: + if not self.integral_verify: + raise ValidationError('【整体式刀具】未进行验证!') + elif self.blade_lot_id: + if not self.blade_verify: + raise ValidationError('【刀片】未进行验证!') + if self.bar_lot_id: + if not self.bar_verify: + raise ValidationError('【刀杆】未进行验证!') + elif self.pad_lot_id: + if not self.pad_verify: + raise ValidationError('【刀盘】未进行验证!') # 组装参数必填校验 - if self.after_assembly_functional_tool_length == 0: - raise ValidationError('组装参数信息【伸出长】不能为0!') if self.after_assembly_max_lifetime_value == 0: raise ValidationError('组装参数信息【最大寿命值】不能为0!') - # if self.after_assembly_alarm_value == 0: - # raise ValidationError('组装参数信息【报警值】不能为0!') - # if self.after_assembly_effective_length == 0: - # raise ValidationError('组装参数信息【有效长】不能为0!!!') - # if self.hiding_length == 0: - # raise ValidationError('组装参数信息【避空长】不能为0!!!') if self.after_assembly_functional_tool_diameter <= 0: raise ValidationError('组装参数信息【刀具直径】不能小于等于0!') if self.after_assembly_tool_loading_length == 0: @@ -1172,6 +1105,13 @@ class FunctionalToolAssembly(models.Model): return functional_tool return False + bool_preset_parameter = fields.Boolean('', default=False) + + def get_tool_preset_parameter(self): + if not self.bool_preset_parameter: + raise ValidationError('没有获取到测量数据, 请确认刀具预调仪操作是否正确!') + return True + def assemble_single_print(self): """ todo 组装单打印 @@ -1563,6 +1503,7 @@ class FunctionalToolDismantle(models.Model): assembly_id = self.env['sf.functional.tool.assembly'].sudo().create({ 'functional_tool_name': self.functional_tool_id.name, 'handle_code_id': self.handle_lot_id.id, + 'handle_product_id': self.handle_product_id.id, 'loading_task_source': '3', 'reason_for_applying': '刀具寿命到期' }) diff --git a/sf_tool_management/models/stock.py b/sf_tool_management/models/stock.py index 50218e65..32719520 100644 --- a/sf_tool_management/models/stock.py +++ b/sf_tool_management/models/stock.py @@ -115,6 +115,13 @@ class StockPicking(models.Model): num = "%03d" % m return name + str(num) + def tool_location_num(self, freight_barcode_id, lot_id): + location_lot = self.env['sf.shelf.location.lot'].sudo().search([('lot_id', '=', lot_id.id), ( + 'shelf_location_id', '=', freight_barcode_id.id)]) + if not location_lot: + raise ValidationError( + f'[{freight_barcode_id.barcode}]货位的[{lot_id.name}]批次物料已用完,请重新选择!') + def create_tool_stocking_picking1(self, obj): """ 创建刀具物料出库单 @@ -133,25 +140,32 @@ class StockPicking(models.Model): stock_move_id = self.env['stock.move'] datas = {'data': [], 'picking_id': picking_id} if obj.handle_code_id: + if obj.handle_code_id.tool_material_status == '在用': + raise ValidationError(f'Rfid为{obj.handle_code_id.rfid}的刀柄已被使用,请重新选择!') # 修改刀柄序列号状态为【在用】 obj.handle_code_id.sudo().write({'tool_material_status': '在用'}) datas['data'].append( {'current_location_id': self.env['sf.shelf.location'], 'lot_id': obj.handle_code_id}) if obj.integral_product_id: + self.tool_location_num(obj.integral_freight_barcode_id, obj.integral_lot_id) datas['data'].append( - {'current_location_id': obj.integral_freight_barcode_id, 'lot_id': obj.integral_freight_lot_id.lot_id}) + {'current_location_id': obj.integral_freight_barcode_id, 'lot_id': obj.integral_lot_id}) if obj.blade_product_id: + self.tool_location_num(obj.blade_freight_barcode_id, obj.blade_lot_id) datas['data'].append( - {'current_location_id': obj.blade_freight_barcode_id, 'lot_id': obj.blade_freight_lot_id.lot_id}) + {'current_location_id': obj.blade_freight_barcode_id, 'lot_id': obj.blade_lot_id}) if obj.bar_product_id: + self.tool_location_num(obj.bar_freight_barcode_id, obj.bar_lot_id) datas['data'].append( - {'current_location_id': obj.bar_freight_barcode_id, 'lot_id': obj.bar_freight_lot_id.lot_id}) + {'current_location_id': obj.bar_freight_barcode_id, 'lot_id': obj.bar_lot_id}) if obj.pad_product_id: + self.tool_location_num(obj.pad_freight_barcode_id, obj.pad_lot_id) datas['data'].append( - {'current_location_id': obj.pad_freight_barcode_id, 'lot_id': obj.pad_freight_lot_id.lot_id}) + {'current_location_id': obj.pad_freight_barcode_id, 'lot_id': obj.pad_lot_id}) if obj.chuck_product_id: + self.tool_location_num(obj.chuck_freight_barcode_id, obj.chuck_lot_id) datas['data'].append( - {'current_location_id': obj.chuck_freight_barcode_id, 'lot_id': obj.chuck_freight_lot_id.lot_id}) + {'current_location_id': obj.chuck_freight_barcode_id, 'lot_id': obj.chuck_lot_id}) # 创建刀具物料出库库存移动记录 stock_move_id.create_tool_material_stock_moves(datas) # 将刀具物料出库库单的状态更改为就绪 @@ -187,6 +201,9 @@ class StockMove(models.Model): stock_move_ids = [] for res in data: if res: + if res['lot_id'].product_qty <= 0: + raise ValidationError( + f'[{res["lot_id"].product_id.name}产品的{res["lot_id"].name}]批次/序列号库存不足!') # 创建库存移动记录 stock_move_id = self.env['stock.move'].sudo().create({ 'name': picking_id.name, @@ -248,8 +265,87 @@ class ProductProduct(models.Model): num = "%03d" % m return '%s-%s' % (code, num) + def set_tool_material(self): + tool_id = self.env.context.get('tool_id') + tool_assembly_id = self.env['sf.functional.tool.assembly'].sudo().search([('id', '=', tool_id)]) + if len(self) > 1: + raise ValidationError('请不要多选') + else: + tool_assembly_id.handle_product_id = self.id + tool_assembly_id.handle_code_id = False + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'message': '刀柄信息更改成功', + 'type': 'success', + 'next': {'type': 'ir.actions.act_window_close'} + } + } + class SfShelfLocationLot(models.Model): _inherit = 'sf.shelf.location.lot' + product_id = fields.Many2one('product.product', '产品', compute='_compute_product_id', store=True) + cutting_tool_type = fields.Char(string="刀具物料类型", compute='_compute_product_id', store=True) + cutting_tool_type_id = fields.Many2one('sf.cutting.tool.type', string='类型', + related='product_id.cutting_tool_type_id') + cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='型号名称', + related='product_id.cutting_tool_model_id') + specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='物料号', + related='product_id.specification_id') + brand_id = fields.Many2one('sf.machine.brand', '品牌', related='product_id.brand_id') + cutting_tool_blade_diameter = fields.Float('刃部直径(mm)', related='product_id.cutting_tool_blade_diameter') + cutting_tool_blade_tip_working_size = fields.Char('刀尖R角(mm)', + related='product_id.cutting_tool_blade_tip_working_size') + cutting_tool_blade_radius = fields.Char('刀尖圆弧半径(mm)', + related='product_id.cutting_tool_blade_tip_circular_arc_radius') + cutting_tool_cutter_arbor_diameter = fields.Float('刀杆直径(mm)', + related='product_id.cutting_tool_cutter_arbor_diameter') + cutting_tool_cutter_head_diameter = fields.Float('刀盘直径(mm)', + related='product_id.cutting_tool_cutter_head_diameter') + + fit_blade_shape_id = fields.Many2one('maintenance.equipment.image', '适配刀片形状', + related='product_id.fit_blade_shape_id') + + @api.depends('lot_id') + def _compute_product_id(self): + for item in self: + if item.lot_id: + item.product_id = item.lot_id.product_id.id + item.cutting_tool_type = item.lot_id.product_id.cutting_tool_type + + def set_tool_material(self): + tool_type = self.env.context.get('tool_type') + tool_id = self.env.context.get('tool_id') + tool_assembly_id = self.env['sf.functional.tool.assembly'].sudo().search([('id', '=', tool_id)]) + if len(self) > 1: + raise ValidationError('请不要多选') + if tool_type == '整体式刀具': + tool_assembly_id.integral_freight_barcode_id = self.shelf_location_id.id + tool_assembly_id.integral_lot_id = self.lot_id.id + tool_assembly_id.integral_verify = False + elif tool_type == '刀片': + tool_assembly_id.blade_freight_barcode_id = self.shelf_location_id.id + tool_assembly_id.blade_lot_id = self.lot_id.id + tool_assembly_id.blade_verify = False + elif tool_type == '刀杆': + tool_assembly_id.bar_freight_barcode_id = self.shelf_location_id.id + tool_assembly_id.bar_lot_id = self.lot_id.id + tool_assembly_id.bar_verify = False + elif tool_type == '刀盘': + tool_assembly_id.pad_freight_barcode_id = self.shelf_location_id.id + tool_assembly_id.pad_lot_id = self.lot_id.id + tool_assembly_id.pad_verify = False + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'message': f'[{tool_type}]物料信息更改成功', + 'type': 'success', + 'next': {'type': 'ir.actions.act_window_close'} + } + } diff --git a/sf_tool_management/views/stock.xml b/sf_tool_management/views/stock.xml index 81783631..c0942282 100644 --- a/sf_tool_management/views/stock.xml +++ b/sf_tool_management/views/stock.xml @@ -11,4 +11,131 @@ + + + 刀柄 + product.product + + +
+
+ + + + + + + + +
+
+
+ + + product.product + + + + + + + + + sf.shelf.location.lot.tree + sf.shelf.location.lot + + +
+
+ + + + + + + + + + + +
+
+
+ + + sf.shelf.location.lot.tree + sf.shelf.location.lot + + +
+
+ + + + + + + + + + + +
+
+
+ + + + sf.shelf.location.lot.tree + sf.shelf.location.lot + + +
+
+ + + + + + + + + + + +
+
+
+ + + sf.shelf.location.lot.tree + sf.shelf.location.lot + + +
+
+ + + + + + + + + + + +
+
+
\ No newline at end of file