diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 12f7e79e..b77e6469 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -669,6 +669,20 @@ class FunctionalToolAssembly(models.Model): :return: """ + picking_num = fields.Integer('调拨单数量', compute='compute_picking_num', store=True) + + @api.depends('assemble_status') + def compute_picking_num(self): + for item in self: + picking_ids = self.env['stock.picking'].sudo().search([('origin', '=', item.assembly_order_code)]) + item.picking_num = len(picking_ids) + + def open_tool_stock_picking(self): + action = self.env.ref('stock.action_picking_tree_all') + result = action.read()[0] + result['domain'] = [('origin', '=', self.assembly_order_code)] + return result + @api.model_create_multi def create(self, vals): obj = super(FunctionalToolAssembly, self).create(vals) @@ -758,7 +772,7 @@ class FunctionalToolDismantle(models.Model): num = "%03d" % m return 'GNDJ-CJD-%s-%s' % (datetime, num) - functional_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', required=True, + functional_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', required=True, tracking=True, domain=[('functional_tool_status', '!=', '已拆除'), ('current_location', '=', '刀具房')]) tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', store=True, @@ -778,6 +792,16 @@ class FunctionalToolDismantle(models.Model): scrap_ids = fields.One2many('stock.scrap', 'functional_tool_dismantle_id', string='报废单号', readonly=True) grinding_id = fields.Char('磨削单号', readonly=True) + picking_id = fields.Many2one('stock.picking', string='刀具物料调拨单') + picking_num = fields.Integer('调拨单数量', default=0, compute='compute_picking_num', store=True) + + @api.depends('picking_id') + def compute_picking_num(self): + for item in self: + if item.picking_id: + item.picking_num = 1 + else: + item.picking_num = 0 state = fields.Selection([('待拆解', '待拆解'), ('已拆解', '已拆解')], default='待拆解', tracking=True) active = fields.Boolean('有效', default=True) @@ -791,7 +815,14 @@ class FunctionalToolDismantle(models.Model): handle_rfid = fields.Char(string='刀柄Rfid', compute='_compute_functional_tool_num', store=True) handle_lot_id = fields.Many2one('stock.lot', string='刀柄序列号', compute='_compute_functional_tool_num', store=True) - scrap_boolean = fields.Boolean(string='刀柄是否报废', default=False, tracking=True) + scrap_boolean = fields.Boolean(string='刀柄是否报废', default=False, tracking=True, compute='compute_scrap_boolean', + store=True) + + @api.depends('dismantle_cause') + def compute_scrap_boolean(self): + for item in self: + if item.dismantle_cause not in ['寿命到期报废', '崩刀报废']: + item.scrap_boolean = False # 整体式 integral_product_id = fields.Many2one('product.product', string='整体式刀具', @@ -974,20 +1005,19 @@ class FunctionalToolDismantle(models.Model): if self.chuck_freight_id: datas['picking'].append({'lot_id': self.chuck_lot_id, 'destination': self.chuck_freight_id}) self.create_tool_picking_scrap(datas) - # ===============修改功能刀具数据===== + # ===============创建功能刀具拆解移动记录===== + self.env['stock.move'].create_functional_tool_stock_move(self) + # 修改功能刀具数据 self.functional_tool_id.write({ 'rfid_dismantle': self.functional_tool_id.rfid, 'rfid': '', 'functional_tool_status': '已拆除' }) - # 创建功能刀具拆解移动记录 - location_dismantle_id = self.env['stock.location'].search([('name', '=', '拆解')]) # 修改拆解单的值 self.write({ - 'rfid_dismantle': self.rfid, 'dismantle_data': fields.Datetime.now(), 'dismantle_person': self.env.user.name, - 'rfid': '', + 'rfid': '%s(已拆解)' % self.rfid, 'state': '已拆解' }) logging.info('【%s】刀具拆解成功!' % self.name) @@ -1001,6 +1031,7 @@ class FunctionalToolDismantle(models.Model): self.env['stock.scrap'].create_tool_dismantle_stock_scrap(data['lot_id'], self) if picking_data: picking_id = self.env['stock.picking'].create_tool_dismantle_picking(self) + self.picking_id = picking_id.id self.env['stock.move'].create_tool_stock_move({'data': picking_data, 'picking_id': picking_id}) # 将刀具物料出库库单的状态更改为就绪 picking_id.action_confirm() @@ -1010,6 +1041,27 @@ class FunctionalToolDismantle(models.Model): picking_id.action_set_quantities_to_reservation() picking_id.button_validate() + def action_open_reference1(self): + self.ensure_one() + return { + 'res_model': self._name, + 'type': 'ir.actions.act_window', + 'views': [[False, "form"]], + 'res_id': self.id, + } + + def open_function_tool_stock_move_line(self): + action = self.env.ref('sf_tool_management.sf_inbound_and_outbound_records_of_functional_tools_view_act') + result = action.read()[0] + result['domain'] = [('functional_tool_dismantle_id', '=', self.id), ('qty_done', '>', 0)] + return result + + def open_tool_stock_picking(self): + action = self.env.ref('stock.action_picking_tree_all') + result = action.read()[0] + result['domain'] = [('origin', '=', self.code)] + return result + class StockPicking(models.Model): _inherit = 'stock.picking' @@ -1073,38 +1125,39 @@ class StockMove(models.Model): }) return True - def create_functional_tool_stock_move(self, location_inventory_id, stock_location_id, functional_tool_assembly_id, - name, obj, - tool_groups_id): + def create_functional_tool_stock_move(self, dismantle_id): """ 对功能刀具拆解过程的功能刀具进行库存移动,以及创建移动历史 """ + location_dismantle_id = self.env['stock.location'].search([('name', '=', '拆解')]) + if not location_dismantle_id: + raise ValidationError('缺少名称为【拆解】的仓库管理地点') + tool_id = dismantle_id.functional_tool_id # 创建库存移动记录 stock_move_id = self.env['stock.move'].sudo().create({ - 'name': name, - 'product_id': self.product_id.id, - 'location_id': location_inventory_id.id, - 'location_dest_id': stock_location_id.id, + 'name': dismantle_id.code, + 'product_id': tool_id.barcode_id.product_id.id, + 'location_id': tool_id.current_location_id.id, + 'location_dest_id': location_dismantle_id.id, 'product_uom_qty': 1.00, 'state': 'done' }) # 创建移动历史记录 stock_move_line_id = self.env['stock.move.line'].sudo().create({ - 'product_id': self.product_id.id, - 'functional_tool_name_id': functional_tool_assembly_id, - 'lot_id': self.id, + 'product_id': tool_id.barcode_id.product_id.id, + 'functional_tool_dismantle_id': dismantle_id.id, + 'lot_id': tool_id.barcode_id.id, 'move_id': stock_move_id.id, - 'install_tool_time': fields.Datetime.now(), 'qty_done': 1.0, 'state': 'done', - 'functional_tool_type_id': False if not obj else obj.functional_tool_type_id.id, - 'diameter': None if not obj else obj.after_assembly_functional_tool_diameter, - 'knife_tip_r_angle': None if not obj else obj.after_assembly_knife_tip_r_angle, - 'code': '' if not obj else obj.code, - 'rfid': '' if not obj else obj.rfid, - 'functional_tool_name': '' if not obj else obj.after_assembly_functional_tool_name, - 'tool_groups_id': False if not tool_groups_id else tool_groups_id.id + 'functional_tool_type_id': tool_id.sf_cutting_tool_type_id.id, + 'diameter': tool_id.functional_tool_diameter, + 'knife_tip_r_angle': tool_id.knife_tip_r_angle, + 'code': tool_id.code, + 'rfid': tool_id.rfid, + 'functional_tool_name': tool_id.name, + 'tool_groups_id': tool_id.tool_groups_id.id }) return stock_move_id, stock_move_line_id diff --git a/sf_tool_management/models/functional_tool.py b/sf_tool_management/models/functional_tool.py index 18f0a466..4e791fe5 100644 --- a/sf_tool_management/models/functional_tool.py +++ b/sf_tool_management/models/functional_tool.py @@ -252,9 +252,7 @@ class FunctionalCuttingToolEntity(models.Model): def open_safety_stock(self): action = self.env.ref('sf_tool_management.sf_real_time_distribution_of_functional_tools_view_act') result = action.read()[0] - result['domain'] = [('name', '=', self.name), ('diameter', '=', self.functional_tool_diameter), - ('knife_tip_r_angle', '=', self.knife_tip_r_angle), - ('coarse_middle_thin', '=', self.coarse_middle_thin)] + result['domain'] = [('id', '=', self.safe_inventory_id.id)] return result def tool_inventory_displacement_out(self): @@ -372,6 +370,7 @@ class StockMoveLine(models.Model): _order = 'date desc' functional_tool_name_id = fields.Many2one('sf.functional.tool.assembly', string='功能刀具组装单') + functional_tool_dismantle_id = fields.Many2one('sf.functional.tool.dismantle', string='功能刀具拆解单') functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', store=True, group_expand='_read_group_functional_tool_type_id') functional_tool_name = fields.Char('刀具名称') @@ -392,6 +391,9 @@ class StockMoveLine(models.Model): if self.functional_tool_name_id: action = self.functional_tool_name_id.action_open_reference1() return action + if self.functional_tool_dismantle_id: + action = self.functional_tool_dismantle_id.action_open_reference1() + return action elif self.move_id: action = self.move_id.action_open_reference() if action['res_model'] != 'stock.move': @@ -409,13 +411,14 @@ class RealTimeDistributionOfFunctionalTools(models.Model): _inherit = ['mail.thread'] _description = '功能刀具安全库存' - name = fields.Char('名称', readonly=True, compute='_compute_name', store=True) + name = fields.Char('名称', compute='_compute_num', store=True) functional_name_id = fields.Many2one('sf.tool.inventory', string='功能刀具名称', required=True) - tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', readonly=False, required=True) - sf_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=False, - group_expand='_read_mrs_cutting_tool_type_ids', store=True) - diameter = fields.Float(string='刀具直径(mm)', readonly=False) - knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', readonly=False) + tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', compute='_compute_num', store=True) + sf_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', + compute='_compute_num', store=True, + group_expand='_read_mrs_cutting_tool_type_ids') + diameter = fields.Float(string='刀具直径(mm)', compute='_compute_num', store=True) + knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', compute='_compute_num', store=True) tool_stock_num = fields.Integer(string='刀具房数量', compute='_compute_stock_num', store=True) side_shelf_num = fields.Integer(string='线边刀库数量', compute='_compute_stock_num', store=True) on_tool_stock_num = fields.Integer(string='机内刀库数量', compute='_compute_stock_num', store=True) @@ -460,22 +463,18 @@ class RealTimeDistributionOfFunctionalTools(models.Model): active = fields.Boolean(string='已归档', default=True) - @api.onchange('functional_name_id') - def _onchange_num(self): + @api.depends('functional_name_id', 'functional_name_id.diameter', 'functional_name_id.angle', + 'functional_name_id.functional_cutting_tool_model_id') + def _compute_num(self): for item in self: if item.functional_name_id: item.tool_groups_id = item.functional_name_id.tool_groups_id.id item.sf_cutting_tool_type_id = item.functional_name_id.functional_cutting_tool_model_id.id item.diameter = item.functional_name_id.diameter item.knife_tip_r_angle = item.functional_name_id.angle - - @api.depends('functional_name_id') - def _compute_name(self): - for obj in self: - if obj.tool_groups_id: - obj.name = obj.functional_name_id.name + item.name = item.functional_name_id.name else: - obj.sudo().name = '' + item.sudo().name = '' @api.constrains('min_stock_num', 'max_stock_num') def _check_stock_num(self): @@ -583,4 +582,10 @@ class RealTimeDistributionOfFunctionalTools(models.Model): for vals in vals_list: vals['status_create'] = False records = super(RealTimeDistributionOfFunctionalTools, self).create(vals_list) + for item in records: + if item: + record = self.search([('functional_name_id', '=', item.functional_name_id.id)]) + if len(record) > 1: + raise ValidationError( + '功能刀具名称为【%s】的安全库存已经存在,请勿重复创建!!!' % item.functional_name_id.name) return records diff --git a/sf_tool_management/models/functional_tool_enroll.py b/sf_tool_management/models/functional_tool_enroll.py index 9c5b1417..ba3553e1 100644 --- a/sf_tool_management/models/functional_tool_enroll.py +++ b/sf_tool_management/models/functional_tool_enroll.py @@ -37,14 +37,10 @@ class ToolDatasync(models.Model): def _cron_tool_datasync_all(self): try: - self.env['stock.lot'].sudo().sync_enroll_tool_material_stock_all() - - self.env['stock.lot'].sudo().sync_enroll_fixture_material_stock_all() - self.env['sf.tool.material.search'].sudo().sync_enroll_tool_material_all() - + self.env['stock.lot'].sudo().sync_enroll_tool_material_stock_all() self.env['sf.fixture.material.search'].sudo().sync_enroll_fixture_material_all() - + self.env['stock.lot'].sudo().sync_enroll_fixture_material_stock_all() self.env['sf.functional.cutting.tool.entity'].sudo().esync_enroll_functional_tool_entity_all() logging.info("已全部同步完成!!!") # self.env['sf.functional.tool.warning'].sudo().sync_enroll_functional_tool_warning_all() @@ -106,7 +102,7 @@ class StockLot(models.Model): logging.info("没有刀具物料序列号信息") except Exception as e: logging.info("刀具物料序列号同步失败:%s" % e) - + class ToolMaterial(models.Model): _inherit = 'sf.tool.material.search' @@ -198,7 +194,7 @@ class FunctionalCuttingToolEntity(models.Model): for item in objs_all: val = { 'id': item.id, - 'code': item.code, + 'code': False if not item.code else item.code.split('-', 1)[1], 'name': item.name, 'rfid': item.rfid, 'tool_groups_name': item.tool_groups_id.name, diff --git a/sf_tool_management/views/functional_tool_views.xml b/sf_tool_management/views/functional_tool_views.xml index 7211548c..103583c2 100644 --- a/sf_tool_management/views/functional_tool_views.xml +++ b/sf_tool_management/views/functional_tool_views.xml @@ -29,7 +29,6 @@ - @@ -61,13 +60,9 @@ +

@@ -763,10 +775,25 @@
+
+ + +

@@ -777,12 +804,13 @@ - - + + + @@ -883,8 +911,22 @@ - - + + + + + + + + + + + + + +