From 683e9631fa0b492c7e9dacbc6affaba2ee3b1525 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Thu, 30 May 2024 09:36:17 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E5=88=80=E5=85=B7=E7=89=A9=E6=96=99?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E4=BC=98=E5=8C=96=E9=9C=80=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product_template_management_view.xml | 21 ++++++++++++--- sf_manufacturing/models/product_template.py | 27 +++++++++++++++++-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/sf_dlm_management/views/product_template_management_view.xml b/sf_dlm_management/views/product_template_management_view.xml index 8842f8bf..8dc5005d 100644 --- a/sf_dlm_management/views/product_template_management_view.xml +++ b/sf_dlm_management/views/product_template_management_view.xml @@ -31,9 +31,11 @@ options="{'no_create': True}" attrs="{'invisible': [('categ_type', '!=', '刀具')],'required': [('categ_type', '=', '刀具')],'readonly': [('id', '!=', False)]}" placeholder="请选择"/> + @@ -47,10 +49,10 @@ - - @@ -95,6 +97,16 @@ + + {'readonly': ['|',('id','!=',False),('categ_type', '=', + '刀具')], 'required': True} + + + + {'readonly': [('categ_type', '=', '刀具')], 'invisible': + [('product_variant_count', '>' , 1)]} + + @@ -455,7 +467,8 @@ - + diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 7d9bbac5..0e09b018 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -50,8 +50,8 @@ class ResProductMo(models.Model): cutting_tool_material_id = fields.Many2one('sf.cutting.tool.material', string='刀具物料') cutting_tool_type = fields.Char(string="刀具物料类型", related='cutting_tool_material_id.name', store=True) - cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='型号') - specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='规格') + cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='型号名称') + specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='物料号') cutting_tool_type_id = fields.Many2one('sf.cutting.tool.type', string='类型', domain="[('cutting_tool_material_id.name', '=', cutting_tool_type)]") @@ -104,6 +104,25 @@ class ResProductMo(models.Model): compaction_way_id = fields.Many2one('maintenance.equipment.image', '压紧方式', domain=[('type', '=', '压紧方式')]) + name = fields.Char('产品名称', compute='_compute_tool_name', store=True, required=False) + default_code = fields.Char('内部参考', compute='_onchange_tool_default_code', store=True) + + @api.depends('cutting_tool_model_id', 'specification_id') + def _compute_tool_name(self): + for item in self: + if item.cutting_tool_model_id and item.specification_id: + name = '%s%s' % (item.cutting_tool_model_id.name, item.specification_id.name) + item.name = name + + @api.depends('categ_id', 'cutting_tool_material_id', 'cutting_tool_model_id') + def _onchange_tool_default_code(self): + for item in self: + if item.categ_id and item.cutting_tool_material_id and item.cutting_tool_model_id: + if item.cutting_tool_model_id.code: + default_code = '%s-T-DJWL-%s' % ( + item.cutting_tool_model_id.code.split('-')[0], item.cutting_tool_material_id.code) + item.default_code = default_code + @api.onchange('cutting_tool_model_id') def _onchange_cutting_tool_model_id(self): for item in self: @@ -721,6 +740,10 @@ class ResProductMo(models.Model): logging.info('create-model_file:%s' % len(vals['model_file'])) self._sanitize_vals(vals) templates = super(ResProductMo, self).create(vals_list) + # 产品名称唯一性校验 + for item in templates: + if len(self.search([('name', '=', item.name)])) > 1: + raise ValidationError('产品名称【%s】已存在' % item.name) if "create_product_product" not in self._context: templates._create_variant_ids() From 1d4aaa40cdc655869f0cc912e43a11482e39f37f Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Thu, 30 May 2024 14:46:15 +0800 Subject: [PATCH 02/17] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E5=88=80?= =?UTF-8?q?=E5=85=B7=E9=87=87=E8=B4=AD=E5=85=A5=E5=BA=93=EF=BC=8C=E5=85=A5?= =?UTF-8?q?=E5=BA=93=E6=97=B6=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90=E6=89=B9?= =?UTF-8?q?=E6=AC=A1=E5=8F=B7=EF=BC=9B2=E3=80=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=B4=A7=E4=BD=8D=E7=9C=8B=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 7 +- sf_manufacturing/models/stock.py | 85 +++++++++++++++++++-- sf_warehouse/models/model.py | 3 +- sf_warehouse/views/shelf_location.xml | 8 +- 4 files changed, 89 insertions(+), 14 deletions(-) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 0e09b018..f1086c41 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -105,18 +105,13 @@ class ResProductMo(models.Model): '压紧方式', domain=[('type', '=', '压紧方式')]) name = fields.Char('产品名称', compute='_compute_tool_name', store=True, required=False) - default_code = fields.Char('内部参考', compute='_onchange_tool_default_code', store=True) - @api.depends('cutting_tool_model_id', 'specification_id') + @api.depends('categ_id', 'cutting_tool_material_id', 'cutting_tool_model_id', 'specification_id') def _compute_tool_name(self): for item in self: if item.cutting_tool_model_id and item.specification_id: name = '%s%s' % (item.cutting_tool_model_id.name, item.specification_id.name) item.name = name - - @api.depends('categ_id', 'cutting_tool_material_id', 'cutting_tool_model_id') - def _onchange_tool_default_code(self): - for item in self: if item.categ_id and item.cutting_tool_material_id and item.cutting_tool_model_id: if item.cutting_tool_model_id.code: default_code = '%s-T-DJWL-%s' % ( diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index d8a5f41f..2ff965d9 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -668,12 +668,14 @@ class ReStockMove(models.Model): else: view = self.env.ref('stock.view_stock_move_nosuggest_operations') - if self.product_id.tracking == "serial" and self.state == "assigned": - print(self.origin) - if self.product_id.categ_id.name == '刀具': - self.next_serial = self._get_tool_next_serial(self.company_id, self.product_id, self.origin) - else: - self.next_serial = self.env['stock.lot']._get_next_serial(self.company_id, self.product_id) + if self.state == "assigned": + if self.product_id.tracking == "serial": + if self.product_id.categ_id.name == '刀具': + self.next_serial = self._get_tool_next_serial(self.company_id, self.product_id, self.origin) + else: + self.next_serial = self.env['stock.lot']._get_next_serial(self.company_id, self.product_id) + elif self.product_id.tracking == "lot": + self._put_tool_lot(self.company_id, self.product_id, self.origin) return { 'name': _('Detailed Operations'), @@ -698,6 +700,16 @@ class ReStockMove(models.Model): ), } + def _put_tool_lot(self, company, product, origin): + if product.tracking == "lot" and self.product_id.categ_id.name == '刀具': + if not self.move_line_nosuggest_ids: + lot_names = self.env['stock.lot'].generate_lot_names( + '%s-%s-%s' % ('%s-T-DJWL-%s' % ( + product.cutting_tool_model_id.code.split('-')[0], product.cutting_tool_material_id.code), + datetime.now().strftime("%Y%m%d"), origin), 1) + move_lines_commands = self._generate_serial_move_line_commands_tool_lot(lot_names) + self.write({'move_line_nosuggest_ids': move_lines_commands}) + def _get_tool_next_serial(self, company, product, origin): """Return the next serial number to be attributed to the product.""" if product.tracking == "serial": @@ -711,6 +723,67 @@ class ReStockMove(models.Model): else: return "%s-T-%s-%s-%03d" % (split_codes[0], origin, product.specification_id.name, 1) + def _generate_serial_move_line_commands_tool_lot(self, lot_names, origin_move_line=None): + """Return a list of commands to update the move lines (write on + existing ones or create new ones). + Called when user want to create and assign multiple serial numbers in + one time (using the button/wizard or copy-paste a list in the field). + + :param lot_names: A list containing all serial number to assign. + :type lot_names: list + :param origin_move_line: A move line to duplicate the value from, default to None + :type origin_move_line: record of :class:`stock.move.line` + :return: A list of commands to create/update :class:`stock.move.line` + :rtype: list + """ + self.ensure_one() + + # Select the right move lines depending of the picking type configuration. + move_lines = self.env['stock.move.line'] + if self.picking_type_id.show_reserved: + move_lines = self.move_line_ids.filtered(lambda ml: not ml.lot_id and not ml.lot_name) + else: + move_lines = self.move_line_nosuggest_ids.filtered(lambda ml: not ml.lot_id and not ml.lot_name) + + loc_dest = origin_move_line and origin_move_line.location_dest_id + move_line_vals = { + 'picking_id': self.picking_id.id, + 'location_id': self.location_id.id, + 'product_id': self.product_id.id, + 'product_uom_id': self.product_id.uom_id.id, + 'qty_done': self.product_uom_qty, + } + if origin_move_line: + # `owner_id` and `package_id` are taken only in the case we create + # new move lines from an existing move line. Also, updates the + # `qty_done` because it could be usefull for products tracked by lot. + move_line_vals.update({ + 'owner_id': origin_move_line.owner_id.id, + 'package_id': origin_move_line.package_id.id, + 'qty_done': origin_move_line.qty_done or 1, + }) + + move_lines_commands = [] + qty_by_location = defaultdict(float) + for lot_name in lot_names: + # We write the lot name on an existing move line (if we have still one)... + if move_lines: + move_lines_commands.append((1, move_lines[0].id, { + 'lot_name': lot_name, + 'qty_done': 1, + })) + qty_by_location[move_lines[0].location_dest_id.id] += 1 + move_lines = move_lines[1:] + # ... or create a new move line with the serial name. + else: + loc = loc_dest or self.location_dest_id._get_putaway_strategy(self.product_id, quantity=1, + packaging=self.product_packaging_id, + additional_qty=qty_by_location) + move_line_cmd = dict(move_line_vals, lot_name=lot_name, location_dest_id=loc.id) + move_lines_commands.append((0, 0, move_line_cmd)) + qty_by_location[loc.id] += 1 + return move_lines_commands + class ReStockQuant(models.Model): _inherit = 'stock.quant' diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 1a7ba1e0..9e4eada4 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -452,8 +452,9 @@ class ShelfLocation(models.Model): # product_id = fields.Many2one('product.template', string='产品') product_id = fields.Many2one('product.product', string='产品', compute='_compute_product_id', store=True) product_sn_id = fields.Many2one('stock.lot', string='产品序列号') + product_sn_ids = fields.Many2many('stock.lot', 'shelf_location_stock_lot', string='产品批次号') # 产品数量 - product_num = fields.Integer('数量') + product_num = fields.Integer('总数量') @api.depends('product_num') def _compute_product_num(self): diff --git a/sf_warehouse/views/shelf_location.xml b/sf_warehouse/views/shelf_location.xml index a284f288..49cc1ce8 100644 --- a/sf_warehouse/views/shelf_location.xml +++ b/sf_warehouse/views/shelf_location.xml @@ -169,8 +169,14 @@ - + + + + + + + From 7d6fb4f0e3b74f084e2959ea9517a71eba7f7542 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Thu, 30 May 2024 17:26:28 +0800 Subject: [PATCH 03/17] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E8=B4=A7?= =?UTF-8?q?=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_warehouse/models/model.py | 23 ++++++++++++++--------- sf_warehouse/views/shelf_location.xml | 6 ++++-- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 9e4eada4..94194a1c 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -826,15 +826,20 @@ class Sf_stock_move_line(models.Model): obj = self.env['sf.shelf.location'].search([('name', '=', self.destination_location_id.name)]) if record.lot_id: - shelf_location_obj = self.env['sf.shelf.location'].search( - [('product_sn_id', '=', record.lot_id.id)]) - if shelf_location_obj: - shelf_location_obj.product_sn_id = False - if obj: - obj.product_sn_id = record.lot_id.id - else: - if obj: - obj.product_sn_id = record.lot_id.id + if record.product_id.tracking == 'serial': + shelf_location_obj = self.env['sf.shelf.location'].search( + [('product_sn_id', '=', record.lot_id.id)]) + if shelf_location_obj: + shelf_location_obj.product_sn_id = False + if obj: + obj.product_sn_id = record.lot_id.id + else: + if obj: + obj.product_sn_id = record.lot_id.id + elif record.product_id.tracking == 'lot': + obj.product_sn_ids |= record.lot_id + if not obj.product_id: + obj.product_id = record.product_id.id else: if obj: obj.product_id = record.product_id.id diff --git a/sf_warehouse/views/shelf_location.xml b/sf_warehouse/views/shelf_location.xml index 49cc1ce8..6c6d5c76 100644 --- a/sf_warehouse/views/shelf_location.xml +++ b/sf_warehouse/views/shelf_location.xml @@ -170,8 +170,10 @@ - - + + From a7102c81d4656754d0d14cc5e5ae9619820eff24 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 3 Jun 2024 14:14:04 +0800 Subject: [PATCH 04/17] =?UTF-8?q?1=E3=80=81=E6=96=B0=E5=A2=9E=E8=B4=A7?= =?UTF-8?q?=E4=BD=8D=E6=89=B9=E6=AC=A1=E6=95=B0=E9=87=8F=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=EF=BC=8C=E7=94=A8=E6=9D=A5=E5=AD=98=E5=82=A8=E8=B4=A7=E4=BD=8D?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E7=9A=84=E6=89=B9=E6=AC=A1=E5=8F=8A=E5=85=B6?= =?UTF-8?q?=E6=95=B0=E9=87=8F=EF=BC=9B=E5=AE=8C=E6=88=90=E8=AF=A5=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E6=A0=B9=E6=8D=AE=E8=B4=A7=E4=BD=8D=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E7=9A=84=E5=87=BA=E5=85=A5=E5=BA=93=E8=AE=B0=E5=BD=95=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=96=B0=E5=A2=9E=E6=88=96=E5=87=8F=E5=B0=91=E8=B4=A7?= =?UTF-8?q?=E4=BD=8D=E4=BA=A7=E5=93=81=E6=89=B9=E6=AC=A1=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/controllers/controllers.py | 60 +++++++++++++++++ sf_warehouse/models/model.py | 67 +++++++++++++++++-- sf_warehouse/security/ir.model.access.csv | 6 ++ sf_warehouse/views/shelf_location.xml | 4 +- 4 files changed, 131 insertions(+), 6 deletions(-) diff --git a/sf_tool_management/controllers/controllers.py b/sf_tool_management/controllers/controllers.py index a524f0bc..04b89836 100644 --- a/sf_tool_management/controllers/controllers.py +++ b/sf_tool_management/controllers/controllers.py @@ -36,3 +36,63 @@ class Manufacturing_Connect(http.Controller): res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} logging.info('get_functional_tool_groups_Info error:%s' % e) return json.JSONEncoder().encode(res) + + @http.route('/AutoDeviceApi/ToolInventory', type='json', auth='none', methods=['GET', 'POST'], csrf=False, + cors="*") + def get_functional_tool_inventory_Info(self, **kw): + """ + 功能刀具清单接口 + :param kw: + :return: + """ + logging.info('get_functional_tool_inventory_Info:%s' % kw) + try: + datas = request.httprequest.data + ret = json.loads(datas) + # ret = json.loads(ret['result']) + logging.info('DeviceId:%s' % ret) + tool_inventory = request.env['sf.tool.inventory'].sudo().search([]) + + res = {'Succeed': True, 'Datas': []} + if tool_inventory: + for item in tool_inventory: + res['Datas'].append({ + 'ToolName': item.name, + 'GroupName': item.tool_groups_id.name, + 'Lifetime': item.life_span + }) + except Exception as e: + res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} + logging.info('get_functional_tool_inventory_Info error:%s' % e) + return json.JSONEncoder().encode(res) + + @http.route('/AutoDeviceApi/ToolEntity', type='json', auth='none', methods=['GET', 'POST'], csrf=False, + cors="*") + def get_functional_tool_entity_Info(self, **kw): + """ + 功能刀具列表接口 + :param kw: + :return: + """ + logging.info('get_functional_tool_entity_Info:%s' % kw) + try: + datas = request.httprequest.data + ret = json.loads(datas) + # ret = json.loads(ret['result']) + logging.info('DeviceId:%s' % ret) + functional_tools = request.env['sf.functional.cutting.tool.entity'].sudo().search([]) + + res = {'Succeed': True, 'Datas': []} + if functional_tools: + for item in functional_tools: + res['Datas'].append({ + 'Rfid': item.rfid, + 'ToolName': item.tool_name_id.name, + 'GroupName': item.tool_groups_id.name, + 'MaxLifetime': item.max_lifetime_value, + 'KnifeHandle': item.cutting_tool_cutterhandle_model_id.name + }) + except Exception as e: + res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} + logging.info('get_functional_tool_entity_Info error:%s' % e) + return json.JSONEncoder().encode(res) diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 94194a1c..91bd5bf9 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -452,9 +452,9 @@ class ShelfLocation(models.Model): # product_id = fields.Many2one('product.template', string='产品') product_id = fields.Many2one('product.product', string='产品', compute='_compute_product_id', store=True) product_sn_id = fields.Many2one('stock.lot', string='产品序列号') - product_sn_ids = fields.Many2many('stock.lot', 'shelf_location_stock_lot', string='产品批次号') + product_sn_ids = fields.One2many('sf.shelf.location.lot', 'shelf_location_id', string='产品批次号') # 产品数量 - product_num = fields.Integer('总数量') + product_num = fields.Integer('总数量', compute='_compute_number', store=True) @api.depends('product_num') def _compute_product_num(self): @@ -464,6 +464,15 @@ class ShelfLocation(models.Model): elif record.product_num == 0: record.location_status = '空闲' + @api.depends('product_sn_ids.qty') + def _compute_number(self): + for item in self: + if item.product_sn_ids: + qty = 0 + for product_sn_id in item.product_sn_ids: + qty += product_sn_id.qty + item.product_num = qty + # 修改货位状态为禁用 def action_location_status_disable(self): self.location_status = '禁用' @@ -526,7 +535,16 @@ class ShelfLocation(models.Model): return records -class Sf_stock_move_line(models.Model): +class SfShelfLocationLot(models.Model): + _name = 'sf.shelf.location.lot' + _description = '批次数量' + + shelf_location_id = fields.Many2one('sf.shelf.location', string="货位") + lot_id = fields.Many2one('stock.lot', string='批次号') + qty = fields.Integer('数量') + + +class SfStockMoveLine(models.Model): _name = 'stock.move.line' _inherit = ['stock.move.line', 'printing.utils'] @@ -837,7 +855,7 @@ class Sf_stock_move_line(models.Model): if obj: obj.product_sn_id = record.lot_id.id elif record.product_id.tracking == 'lot': - obj.product_sn_ids |= record.lot_id + self.put_shelf_location(record) if not obj.product_id: obj.product_id = record.product_id.id else: @@ -859,6 +877,47 @@ class Sf_stock_move_line(models.Model): raise ValidationError( '【%s】货位已经被占用,请重新选择!!!' % item.destination_location_id.barcode) + def put_shelf_location(self, vals): + """ + 对货位的批量数据进行数量计算 + """ + for record in vals: + if record.lot_id and record.product_id.tracking == 'lot': + if record.current_location_id: + location_lot = self.env['sf.shelf.location.lot'].sudo().search( + [('shelf_location_id', '=', record.current_location_id.id), ('lot_id', '=', record.lot_id.id)]) + if location_lot: + location_lot.qty -= record.qty_done + if location_lot.qty == 0: + location_lot.unlink() + elif location_lot.qty < 0: + raise ValidationError('【%s】货位【%s】批次的【%s】产品数量不足!' % ( + record.current_location_id.barcode, record.lot_id.name, record.product_id.name)) + else: + raise ValidationError('【%s】货位不存在【%s】批次的【%s】产品' % ( + record.current_location_id.barcode, record.lot_id.name, record.product_id.name)) + if record.destination_location_id: + location_lot = self.env['sf.shelf.location.lot'].sudo().search( + [('shelf_location_id', '=', record.destination_location_id.id), + ('lot_id', '=', record.lot_id.id)]) + if location_lot: + location_lot.qty += record.qty_done + else: + self.env['sf.shelf.location.lot'].sudo().create({ + 'shelf_location_id': record.destination_location_id.id, + 'lot_id': record.lot_id.id, + 'qty': record.qty_done + }) + if not record.destination_location_id.product_id: + record.destination_location_id.product_id = record.product_id.id + + @api.model_create_multi + def create(self, vals_list): + + records = super(SfStockMoveLine, self).create(vals_list) + self.put_shelf_location(records) + return records + class SfStockPicking(models.Model): _inherit = 'stock.picking' diff --git a/sf_warehouse/security/ir.model.access.csv b/sf_warehouse/security/ir.model.access.csv index f981d477..88514fd3 100644 --- a/sf_warehouse/security/ir.model.access.csv +++ b/sf_warehouse/security/ir.model.access.csv @@ -1,7 +1,9 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_sf_shelf_location_group_sf_stock_user_group_sf_stock_user,sf.shelf.location,model_sf_shelf_location,sf_base.group_sf_stock_user,1,0,0,0 +access_sf_shelf_location_lot_group_sf_stock_user_group_sf_stock_user,sf.shelf.location.lot,model_sf_shelf_location_lot,sf_base.group_sf_stock_user,1,0,0,0 access_sf_shelf_location_group_sf_stock_manager,sf.shelf.location,model_sf_shelf_location,sf_base.group_sf_stock_manager,1,1,1,0 +access_sf_shelf_location_lot_group_sf_stock_manager,sf.shelf.location.lot,model_sf_shelf_location_lot,sf_base.group_sf_stock_manager,1,1,1,0 access_sf_shelf_group_sf_stock_user_group_sf_stock_user,sf.shelf.group.sf.stock.user,model_sf_shelf,sf_base.group_sf_stock_user,1,0,0,0 access_sf_shelf_group_sf_stock_manager,sf.shelf.group.sf.stock.manager,model_sf_shelf,sf_base.group_sf_stock_manager,1,1,1,0 @@ -101,6 +103,7 @@ access_stock_replenish_option_group_sf_stock_user,stock.replenishment.option,sto access_mrp_production_group_sf_stock_user,mrp.production,mrp.model_mrp_production,sf_base.group_sf_stock_user,1,1,1,0 access_sf_shelf_location_group_plan_dispatch,sf.shelf.location,model_sf_shelf_location,sf_base.group_plan_dispatch,1,0,0,0 +access_sf_shelf_location_lot_group_plan_dispatch,sf.shelf.location.lot,model_sf_shelf_location_lot,sf_base.group_plan_dispatch,1,0,0,0 access_stock_move,stock.move,stock.model_stock_move,sf_base.group_plan_dispatch,1,1,1,0 access_stock_picking_group_plan_dispatch,stock.picking,stock.model_stock_picking,sf_base.group_plan_dispatch,1,0,0,0 access_stock_lot_group_plan_dispatch,stock.lot,stock.model_stock_lot,sf_base.group_plan_dispatch,1,0,0,0 @@ -142,6 +145,9 @@ access_sf_shelf_location_wizard_group_sf_stock_manager,sf_shelf_location_wizard_ access_sf_shelf_location_group_sf_tool_user,sf.shelf.location.group_sf_tool_user,model_sf_shelf_location,sf_base.group_sf_tool_user,1,1,0,0 access_sf_shelf_group_user,sf.shelf.location.group_user,model_sf_shelf_location,base.group_user,1,1,0,0 +access_sf_shelf_location_lot_group_sf_tool_user,sf.shelf.location.lot.group_sf_tool_user,model_sf_shelf_location_lot,sf_base.group_sf_tool_user,1,1,0,0 +access_sf_shelf_lot_group_user,sf.shelf.location.lot.group_user,model_sf_shelf_location_lot,base.group_user,1,1,0,0 + access_ir_model_group_sf_stock_user,ir_model_group_sf_stock_user,base.model_ir_model,sf_base.group_sf_stock_user,1,1,0,0 access_mrp_workorder_group_sf_stock_user,mrp_workorder_group_sf_stock_user,mrp.model_mrp_workorder,sf_base.group_sf_stock_user,1,0,0,0 diff --git a/sf_warehouse/views/shelf_location.xml b/sf_warehouse/views/shelf_location.xml index 6c6d5c76..6fca54f1 100644 --- a/sf_warehouse/views/shelf_location.xml +++ b/sf_warehouse/views/shelf_location.xml @@ -175,8 +175,8 @@ - - + + From 67c4f64d084256d2482687aaebce29e405b7cdf5 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 3 Jun 2024 17:34:47 +0800 Subject: [PATCH 05/17] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E5=88=80?= =?UTF-8?q?=E5=85=B7=E7=BB=84=E8=A3=85=E5=8D=95=E3=80=81=E5=88=80=E5=85=B7?= =?UTF-8?q?=E7=BB=84=E8=A3=85=E5=8D=95=E5=BC=B9=E7=AA=97=E3=80=81=E5=88=80?= =?UTF-8?q?=E5=85=B7=E6=8B=86=E8=A7=A3=E5=8D=95=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=99=A4=E5=88=80=E6=9F=84=E5=A4=96=E5=88=80=E5=85=B7=E7=89=A9?= =?UTF-8?q?=E6=96=99=E6=8C=89=E6=89=B9=E6=AC=A1=E5=8F=B7=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E7=AE=A1=E7=90=86=EF=BC=9B=E4=BC=98=E5=8C=96=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E5=B8=83=E5=B1=80=EF=BC=8C=E4=BC=98=E5=8C=96=E7=BB=84=E8=A3=85?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 96 ++++---- .../views/functional_tool_views.xml | 6 +- sf_tool_management/views/tool_base_views.xml | 53 +++-- sf_tool_management/wizard/wizard.py | 213 +++++++----------- sf_tool_management/wizard/wizard_view.xml | 33 ++- sf_warehouse/models/model.py | 1 + 6 files changed, 201 insertions(+), 201 deletions(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 4a440df6..f763ed4b 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -401,8 +401,9 @@ class FunctionalToolAssembly(models.Model): return categories.browse(functional_tool_type_ids) # 刀具物料信息 - # ==============整体式刀具型号============ - integral_freight_barcode = fields.Char('整体式刀具货位') + # ==============整体式刀具型号============= + integral_freight_barcode_id = fields.Many2one('sf.shelf.location', string='整体式刀具货位') + integral_lot_id = fields.Many2one('stock.lot', string='整体式刀具批次') 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='整体式刀具型号', @@ -412,19 +413,15 @@ class FunctionalToolAssembly(models.Model): sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', related='integral_product_id.brand_id') - @api.depends('integral_freight_barcode') + @api.depends('integral_freight_barcode_id') def _compute_integral_product_id(self): for item in self: - if item.integral_freight_barcode: - location = self.env['sf.shelf.location'].sudo().search( - [('barcode', '=', item.integral_freight_barcode)]) - if location: - item.integral_product_id = location.product_id.id - else: - item.integral_product_id = False + if item.integral_freight_barcode_id: + item.integral_product_id = item.integral_freight_barcode_id.product_id.id # =================刀片型号============= - blade_freight_barcode = fields.Char('刀片货位') + blade_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀片货位') + blade_lot_id = fields.Many2one('stock.lot', string='刀片批次') 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='刀片型号', @@ -433,18 +430,15 @@ class FunctionalToolAssembly(models.Model): related='blade_product_id.specification_id') sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', related='blade_product_id.brand_id') - @api.depends('blade_freight_barcode') + @api.depends('blade_freight_barcode_id') def _compute_blade_product_id(self): for item in self: - if item.blade_freight_barcode: - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', item.blade_freight_barcode)]) - if location: - item.blade_product_id = location.product_id.id - else: - item.blade_product_id = False + if item.blade_freight_barcode_id: + item.blade_product_id = item.blade_freight_barcode_id.product_id.id # ==============刀杆型号================ - bar_freight_barcode = fields.Char('刀杆货位') + bar_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀杆货位') + bar_lot_id = fields.Many2one('stock.lot', string='刀杆批次') 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='刀杆型号', @@ -453,18 +447,15 @@ class FunctionalToolAssembly(models.Model): related='bar_product_id.specification_id') sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', related='bar_product_id.brand_id') - @api.depends('bar_freight_barcode') + @api.depends('bar_freight_barcode_id') def _compute_bar_product_id(self): for item in self: - if item.bar_freight_barcode: - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', item.bar_freight_barcode)]) - if location: - item.bar_product_id = location.product_id.id - else: - item.bar_product_id = False + if item.bar_freight_barcode_id: + item.bar_product_id = item.bar_freight_barcode_id.product_id.id # =============刀盘型号================ - pad_freight_barcode = fields.Char('刀盘货位') + pad_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀盘货位') + pad_lot_id = fields.Many2one('stock.lot', string='刀盘批次') 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='刀盘型号', @@ -473,15 +464,11 @@ class FunctionalToolAssembly(models.Model): related='pad_product_id.specification_id') sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', related='pad_product_id.brand_id') - @api.depends('pad_freight_barcode') + @api.depends('pad_freight_barcode_id') def _compute_pad_product_id(self): for item in self: - if item.pad_freight_barcode: - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', item.pad_freight_barcode)]) - if location: - item.pad_product_id = location.product_id.id - else: - item.pad_product_id = False + if item.pad_freight_barcode_id: + item.pad_product_id = item.pad_freight_barcode_id.product_id.id # ==============刀柄型号============== handle_freight_rfid = fields.Char('刀柄Rfid', compute='_compute_handle_product_id', store=True) @@ -505,7 +492,8 @@ class FunctionalToolAssembly(models.Model): item.handle_freight_rfid = False # ==============夹头型号============== - chuck_freight_barcode = fields.Char('夹头货位') + chuck_freight_barcode_id = fields.Many2one('sf.shelf.location', string='夹头货位') + chuck_lot_id = fields.Many2one('stock.lot', string='夹头批次') 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='夹头型号', @@ -514,17 +502,18 @@ class FunctionalToolAssembly(models.Model): related='chuck_product_id.specification_id') sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', related='chuck_product_id.brand_id') - @api.depends('chuck_freight_barcode') + @api.depends('chuck_freight_barcode_id') def _compute_chuck_product_id(self): for item in self: - if item.chuck_freight_barcode: - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', item.chuck_freight_barcode)]) - if location: - item.chuck_product_id = location.product_id.id - else: - item.chuck_product_id = False + if item.chuck_freight_barcode_id: + item.chuck_product_id = item.chuck_freight_barcode_id.product_id.id # ==================待删除字段================== + integral_freight_barcode = fields.Char('整体式刀具货位') + blade_freight_barcode = fields.Char('刀片货位') + bar_freight_barcode = fields.Char('刀杆货位') + pad_freight_barcode = fields.Char('刀盘货位') + chuck_freight_barcode = fields.Char('夹头货位') blade_name = fields.Char('') integral_name = fields.Char('') blade_code_id = fields.Many2one('stock.lot', '刀片序列号') @@ -721,6 +710,8 @@ class FunctionalToolDismantle(models.Model): related='handle_product_id.cutting_tool_model_id') handle_brand_id = fields.Many2one('sf.machine.brand', string='刀柄品牌', related='handle_product_id.brand_id') 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) # 整体式 @@ -730,6 +721,8 @@ class FunctionalToolDismantle(models.Model): related='integral_product_id.cutting_tool_model_id') integral_brand_id = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', related='integral_product_id.brand_id') + 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))]") @@ -739,6 +732,7 @@ class FunctionalToolDismantle(models.Model): blade_type_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀片型号', related='blade_product_id.cutting_tool_model_id') 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))]") @@ -748,6 +742,7 @@ class FunctionalToolDismantle(models.Model): bar_type_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号', related='bar_product_id.cutting_tool_model_id') 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))]") @@ -757,6 +752,7 @@ class FunctionalToolDismantle(models.Model): pad_type_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号', related='pad_product_id.cutting_tool_model_id') 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))]") @@ -766,6 +762,7 @@ class FunctionalToolDismantle(models.Model): chuck_type_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号', related='chuck_product_id.cutting_tool_model_id') 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))]") @@ -789,12 +786,20 @@ class FunctionalToolDismantle(models.Model): item.rfid = item.functional_tool_id.rfid item.handle_rfid = item.functional_tool_id.rfid + # 产品 item.handle_product_id = item.functional_tool_id.functional_tool_name_id.handle_product_id.id item.integral_product_id = item.functional_tool_id.functional_tool_name_id.integral_product_id.id item.blade_product_id = item.functional_tool_id.functional_tool_name_id.blade_product_id.id item.bar_product_id = item.functional_tool_id.functional_tool_name_id.bar_product_id.id item.pad_product_id = item.functional_tool_id.functional_tool_name_id.pad_product_id.id item.chuck_product_id = item.functional_tool_id.functional_tool_name_id.chuck_product_id.id + # 批次/序列号 + item.handle_lot_id = item.functional_tool_id.functional_tool_name_id.handle_code_id.id + item.integral_lot_id = item.functional_tool_id.functional_tool_name_id.integral_lot_id.id + item.blade_lot_id = item.functional_tool_id.functional_tool_name_id.blade_lot_id.id + item.bar_lot_id = item.functional_tool_id.functional_tool_name_id.bar_lot_id.id + item.pad_lot_id = item.functional_tool_id.functional_tool_name_id.pad_lot_id.id + item.chuck_lot_id = item.functional_tool_id.functional_tool_name_id.chuck_lot_id.id else: item.tool_groups_id = False item.tool_type_id = False @@ -810,6 +815,13 @@ class FunctionalToolDismantle(models.Model): item.pad_product_id = False item.chuck_product_id = False + item.handle_lot_id = False + item.integral_lot_id = False + item.blade_lot_id = False + item.bar_lot_id = False + item.pad_lot_id = False + item.chuck_lot_id = False + def confirmation_disassembly(self): logging.info('%s刀具确认开始拆解' % self.dismantle_cause) if self.functional_tool_id.functional_tool_status == '已拆除': diff --git a/sf_tool_management/views/functional_tool_views.xml b/sf_tool_management/views/functional_tool_views.xml index ac98a703..5c3d64aa 100644 --- a/sf_tool_management/views/functional_tool_views.xml +++ b/sf_tool_management/views/functional_tool_views.xml @@ -46,8 +46,8 @@
-
- + + + + diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 91bd5bf9..53d785d1 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -539,6 +539,7 @@ class SfShelfLocationLot(models.Model): _name = 'sf.shelf.location.lot' _description = '批次数量' + name = fields.Char('名称', related='lot_id.name') shelf_location_id = fields.Many2one('sf.shelf.location', string="货位") lot_id = fields.Many2one('stock.lot', string='批次号') qty = fields.Integer('数量') From 3882d3a3cb21674bbe80d9a6af2f21c8da7af8d6 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 4 Jun 2024 11:26:00 +0800 Subject: [PATCH 06/17] =?UTF-8?q?1=E3=80=81=E5=8A=9F=E8=83=BD=E5=88=80?= =?UTF-8?q?=E5=85=B7=E6=8B=86=E8=A7=A3=E5=8D=95=E6=8B=86=E8=A7=A3=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E4=BC=98=E5=8C=96=EF=BC=9B2=E3=80=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=B4=A7=E4=BD=8D=E7=9C=8B=E6=9D=BF=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 67 ++++++++++---------- sf_tool_management/views/tool_base_views.xml | 27 ++++---- sf_tool_management/wizard/wizard.py | 12 +--- sf_warehouse/views/shelf_location.xml | 8 +-- 4 files changed, 57 insertions(+), 57 deletions(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index f763ed4b..e4fdf3ef 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -847,43 +847,48 @@ class FunctionalToolDismantle(models.Model): if self.dismantle_cause in ['寿命到期报废', '崩刀报废']: # 除刀柄外物料报废 入库到Scrap if self.integral_product_id: - self.integral_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + self.integral_product_id.dismantle_stock_moves(False, self.integral_lot_id, location, + location_dest_scrap) elif self.blade_product_id: - self.blade_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + self.blade_product_id.dismantle_stock_moves(False, self.blade_lot_id, location, location_dest_scrap) if self.bar_product_id: - self.bar_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + self.bar_product_id.dismantle_stock_moves(False, self.bar_lot_id, location, location_dest_scrap) elif self.pad_product_id: - self.pad_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + self.pad_product_id.dismantle_stock_moves(False, self.pad_lot_id, location, location_dest_scrap) if self.chuck_product_id: - self.chuck_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + self.chuck_product_id.dismantle_stock_moves(False, self.chuck_lot_id, location, location_dest_scrap) # ===========功能刀具[磨削]拆解============== - elif self.dismantle_cause in ['刀具需磨削']: - location_dest = self.env['stock.location'].search([('name', '=', '磨削房')]) - # 除刀柄外物料拆解 入库到具体库位 - if self.integral_product_id: - self.integral_product_id.dismantle_stock_moves(False, location, location_dest) - elif self.blade_product_id: - self.blade_product_id.dismantle_stock_moves(False, location, location_dest) - if self.bar_product_id: - self.bar_product_id.dismantle_stock_moves(False, location, location_dest) - elif self.pad_product_id: - self.pad_product_id.dismantle_stock_moves(False, location, location_dest) - if self.chuck_product_id: - self.chuck_product_id.dismantle_stock_moves(False, location, location_dest) - # ==============功能刀具[更换]拆解============== - elif self.dismantle_cause in ['更换为其他刀具']: - # 除刀柄外物料拆解 入库到具体库位 + # elif self.dismantle_cause in ['刀具需磨削']: + # location_dest = self.env['stock.location'].search([('name', '=', '磨削房')]) + # # 除刀柄外物料拆解 入库到具体库位 + # if self.integral_product_id: + # self.integral_product_id.dismantle_stock_moves(False, location, location_dest) + # elif self.blade_product_id: + # self.blade_product_id.dismantle_stock_moves(False, location, location_dest) + # if self.bar_product_id: + # self.bar_product_id.dismantle_stock_moves(False, location, location_dest) + # elif self.pad_product_id: + # self.pad_product_id.dismantle_stock_moves(False, location, location_dest) + # if self.chuck_product_id: + # self.chuck_product_id.dismantle_stock_moves(False, location, location_dest) + # ==============功能刀具[更换,磨削]拆解============== + elif self.dismantle_cause in ['更换为其他刀具', '刀具需磨削']: + # 除刀柄外物料拆解 入库到具体货位 if self.integral_freight_id: - self.integral_product_id.dismantle_stock_moves(self.integral_freight_id.barcode, location, + self.integral_product_id.dismantle_stock_moves(self.integral_freight_id, self.integral_lot_id, location, location_dest) elif self.blade_freight_id: - self.blade_product_id.dismantle_stock_moves(self.blade_freight_id.barcode, location, location_dest) + self.blade_product_id.dismantle_stock_moves(self.blade_freight_id, self.blade_lot_id, location, + location_dest) if self.bar_freight_id: - self.bar_product_id.dismantle_stock_moves(self.bar_freight_id.barcode, location, location_dest) + self.bar_product_id.dismantle_stock_moves(self.bar_freight_id, self.bar_lot_id, location, + location_dest) elif self.pad_freight_id: - self.pad_product_id.dismantle_stock_moves(self.pad_freight_id.barcode, location, location_dest) + self.pad_product_id.dismantle_stock_moves(self.pad_freight_id, self.pad_lot_id, location, + location_dest) if self.chuck_freight_id: - self.chuck_product_id.dismantle_stock_moves(self.chuck_freight_id.barcode, location, location_dest) + self.chuck_product_id.dismantle_stock_moves(self.chuck_freight_id, self.chuck_lot_id, location, + location_dest) # ===============删除功能刀具的Rfid字段的值, 赋值给Rfid(已拆解)字段===== self.functional_tool_id.write({ 'rfid_dismantle': self.functional_tool_id.rfid, @@ -904,7 +909,7 @@ class FunctionalToolDismantle(models.Model): class ProductProduct(models.Model): _inherit = 'product.product' - def dismantle_stock_moves(self, shelf_location_barcode, location_id, location_dest_id): + def dismantle_stock_moves(self, shelf_location_id, lot_id, location_id, location_dest_id): # 创建功能刀具拆解单产品库存移动记录 stock_move_id = self.env['stock.move'].sudo().create({ 'name': '功能刀具拆解', @@ -914,16 +919,12 @@ class ProductProduct(models.Model): 'product_uom_qty': 1.00, 'state': 'done' }) - if shelf_location_barcode: - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', shelf_location_barcode)]) - location.product_num = location.product_num + 1 - else: - location = self.env['sf.shelf.location'] # 创建移动历史记录 stock_move_line_id = self.env['stock.move.line'].sudo().create({ 'product_id': self.id, + 'lot_id': lot_id.id, 'move_id': stock_move_id.id, - 'current_location_id': location.id, + 'destination_location_id': shelf_location_id.id, 'install_tool_time': fields.Datetime.now(), 'qty_done': 1.0, 'state': 'done', diff --git a/sf_tool_management/views/tool_base_views.xml b/sf_tool_management/views/tool_base_views.xml index cc9d4cd9..7e74b8fc 100644 --- a/sf_tool_management/views/tool_base_views.xml +++ b/sf_tool_management/views/tool_base_views.xml @@ -847,8 +847,8 @@ - + @@ -861,11 +861,12 @@ - - + @@ -877,11 +878,12 @@ - - + @@ -893,11 +895,12 @@ - - + @@ -907,11 +910,12 @@ - - + @@ -921,11 +925,12 @@ - - + diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py index 1789ffab..05bf6189 100644 --- a/sf_tool_management/wizard/wizard.py +++ b/sf_tool_management/wizard/wizard.py @@ -335,8 +335,8 @@ class FunctionalToolAssemblyOrder(models.TransientModel): # =================夹头型号============== chuck_freight_barcode_id = fields.Many2one('sf.shelf.location', string='夹头货位', - domain="[('product_id.cutting_tool_material_id.name', '=', '刀盘'),('product_num', '>', 0)]") - chuck_freight_lot_id = fields.Many2one('sf.shelf.location.lot', string='刀盘批次', + 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_product_id = fields.Many2one('product.product', string='夹头名称', compute='_compute_chuck_product_id', store=True) @@ -826,18 +826,12 @@ class ProductProduct(models.Model): stock_move_line_id = self.env['stock.move.line'].sudo().create({ 'product_id': self.id, 'move_id': stock_move_id.id, - 'lot_id': lot_id.id, + 'lot_id': lot_id.lot_id.id, 'current_location_id': shelf_location_barcode_id.id, 'install_tool_time': fields.Datetime.now(), 'qty_done': 1.0, 'state': 'done', }) - if shelf_location_barcode_id.product_num > 0: - shelf_location_barcode_id.product_num = shelf_location_barcode_id.product_num - 1 - else: - raise ValidationError( - '【%s】货位的【%s】产品库存数量为零,请采购入库后再重新组装!' % ( - shelf_location_barcode_id.barcode, shelf_location_barcode_id.product_id.name)) return stock_move_id, stock_move_line_id diff --git a/sf_warehouse/views/shelf_location.xml b/sf_warehouse/views/shelf_location.xml index 6fca54f1..2716dd91 100644 --- a/sf_warehouse/views/shelf_location.xml +++ b/sf_warehouse/views/shelf_location.xml @@ -172,11 +172,11 @@ - - - - + + + From d47dcc76117dda520dc473b7886ea4ff1326d7ce Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 4 Jun 2024 17:25:45 +0800 Subject: [PATCH 07/17] =?UTF-8?q?1=E3=80=81=E5=8F=96=E6=B6=88=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E4=BA=A7=E5=93=81=E6=97=B6=EF=BC=8C=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=86=85=E9=83=A8=E5=8F=82=E8=80=83=E7=9A=84?= =?UTF-8?q?=E5=80=BC=EF=BC=9B2=E3=80=81=E4=BC=98=E5=8C=96=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=88=80=E5=85=B7=E6=8B=86=E8=A7=A3=E5=8D=95=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=B1=E6=8B=86=E8=A7=A3=E5=8D=95=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=9A=84=E7=A7=BB=E5=8A=A8=E5=8E=86=E5=8F=B2=E5=8D=95?= =?UTF-8?q?=E6=8D=AE=E7=BC=96=E7=A0=81=E7=94=9F=E6=88=90=E8=A7=84=E5=88=99?= =?UTF-8?q?=EF=BC=9B3=E3=80=81=E4=BC=98=E5=8C=96=E8=B4=A7=E4=BD=8D?= =?UTF-8?q?=E7=9C=8B=E6=9D=BF=E4=BB=A5=E5=8F=8A=E8=B4=A7=E4=BD=8D=E7=9C=8B?= =?UTF-8?q?=E6=9D=BF=E7=9A=84=E8=B4=A7=E4=BD=8D=E5=8F=98=E6=9B=B4=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product_template_management_view.xml | 10 +-- sf_manufacturing/models/product_template.py | 7 +- sf_tool_management/models/base.py | 29 ++++---- sf_warehouse/models/model.py | 12 +++- sf_warehouse/views/shelf_location.xml | 4 +- sf_warehouse/wizard/wizard.py | 66 ++++++++++++++----- sf_warehouse/wizard/wizard_view.xml | 34 +++++++--- 7 files changed, 111 insertions(+), 51 deletions(-) diff --git a/sf_dlm_management/views/product_template_management_view.xml b/sf_dlm_management/views/product_template_management_view.xml index 8dc5005d..a62adf34 100644 --- a/sf_dlm_management/views/product_template_management_view.xml +++ b/sf_dlm_management/views/product_template_management_view.xml @@ -102,11 +102,11 @@ '刀具')], 'required': True} - - {'readonly': [('categ_type', '=', '刀具')], 'invisible': - [('product_variant_count', '>' , 1)]} - - + + + + + diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index f1086c41..b500a6e8 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -106,17 +106,12 @@ class ResProductMo(models.Model): name = fields.Char('产品名称', compute='_compute_tool_name', store=True, required=False) - @api.depends('categ_id', 'cutting_tool_material_id', 'cutting_tool_model_id', 'specification_id') + @api.depends('cutting_tool_model_id', 'specification_id') def _compute_tool_name(self): for item in self: if item.cutting_tool_model_id and item.specification_id: name = '%s%s' % (item.cutting_tool_model_id.name, item.specification_id.name) item.name = name - if item.categ_id and item.cutting_tool_material_id and item.cutting_tool_model_id: - if item.cutting_tool_model_id.code: - default_code = '%s-T-DJWL-%s' % ( - item.cutting_tool_model_id.code.split('-')[0], item.cutting_tool_material_id.code) - item.default_code = default_code @api.onchange('cutting_tool_model_id') def _onchange_cutting_tool_model_id(self): diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index e4fdf3ef..87dcfb28 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -824,6 +824,7 @@ class FunctionalToolDismantle(models.Model): def confirmation_disassembly(self): logging.info('%s刀具确认开始拆解' % self.dismantle_cause) + t_id = self.id if self.functional_tool_id.functional_tool_status == '已拆除': raise ValidationError('Rfid为【%s】的功能刀具已经拆解,请勿重复操作!' % self.functional_tool_id.rfid_dismantle) location = self.env['stock.location'].search([('name', '=', '刀具组装位置')]) @@ -848,15 +849,19 @@ class FunctionalToolDismantle(models.Model): # 除刀柄外物料报废 入库到Scrap if self.integral_product_id: self.integral_product_id.dismantle_stock_moves(False, self.integral_lot_id, location, - location_dest_scrap) + location_dest_scrap, t_id) elif self.blade_product_id: - self.blade_product_id.dismantle_stock_moves(False, self.blade_lot_id, location, location_dest_scrap) + self.blade_product_id.dismantle_stock_moves(False, self.blade_lot_id, location, location_dest_scrap, + t_id) if self.bar_product_id: - self.bar_product_id.dismantle_stock_moves(False, self.bar_lot_id, location, location_dest_scrap) + self.bar_product_id.dismantle_stock_moves(False, self.bar_lot_id, location, location_dest_scrap, + t_id) elif self.pad_product_id: - self.pad_product_id.dismantle_stock_moves(False, self.pad_lot_id, location, location_dest_scrap) + self.pad_product_id.dismantle_stock_moves(False, self.pad_lot_id, location, location_dest_scrap, + t_id) if self.chuck_product_id: - self.chuck_product_id.dismantle_stock_moves(False, self.chuck_lot_id, location, location_dest_scrap) + self.chuck_product_id.dismantle_stock_moves(False, self.chuck_lot_id, location, location_dest_scrap, + t_id) # ===========功能刀具[磨削]拆解============== # elif self.dismantle_cause in ['刀具需磨削']: # location_dest = self.env['stock.location'].search([('name', '=', '磨削房')]) @@ -876,19 +881,19 @@ class FunctionalToolDismantle(models.Model): # 除刀柄外物料拆解 入库到具体货位 if self.integral_freight_id: self.integral_product_id.dismantle_stock_moves(self.integral_freight_id, self.integral_lot_id, location, - location_dest) + location_dest, t_id) elif self.blade_freight_id: self.blade_product_id.dismantle_stock_moves(self.blade_freight_id, self.blade_lot_id, location, - location_dest) + location_dest, t_id) if self.bar_freight_id: self.bar_product_id.dismantle_stock_moves(self.bar_freight_id, self.bar_lot_id, location, - location_dest) + location_dest, t_id) elif self.pad_freight_id: self.pad_product_id.dismantle_stock_moves(self.pad_freight_id, self.pad_lot_id, location, - location_dest) + location_dest, t_id) if self.chuck_freight_id: self.chuck_product_id.dismantle_stock_moves(self.chuck_freight_id, self.chuck_lot_id, location, - location_dest) + location_dest, t_id) # ===============删除功能刀具的Rfid字段的值, 赋值给Rfid(已拆解)字段===== self.functional_tool_id.write({ 'rfid_dismantle': self.functional_tool_id.rfid, @@ -909,10 +914,10 @@ class FunctionalToolDismantle(models.Model): class ProductProduct(models.Model): _inherit = 'product.product' - def dismantle_stock_moves(self, shelf_location_id, lot_id, location_id, location_dest_id): + def dismantle_stock_moves(self, shelf_location_id, lot_id, location_id, location_dest_id, t_id): # 创建功能刀具拆解单产品库存移动记录 stock_move_id = self.env['stock.move'].sudo().create({ - 'name': '功能刀具拆解', + 'name': 'DJCJ/%s' % t_id, 'product_id': self.id, 'location_id': location_id.id, 'location_dest_id': location_dest_id.id, diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 53d785d1..155d5924 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -481,7 +481,7 @@ class ShelfLocation(models.Model): def action_location_status_enable(self): self.location_status = '空闲' - @api.depends('product_sn_id') + @api.depends('product_sn_id', 'product_sn_ids') def _compute_product_id(self): """ 根据产品序列号,获取产品 @@ -494,7 +494,8 @@ class ShelfLocation(models.Model): record.sudo().product_num = 1 except Exception as e: print('eeeeeee占用', e) - + elif record.product_sn_ids: + return True else: try: record.sudo().product_id = False @@ -543,6 +544,13 @@ class SfShelfLocationLot(models.Model): shelf_location_id = fields.Many2one('sf.shelf.location', string="货位") lot_id = fields.Many2one('stock.lot', string='批次号') qty = fields.Integer('数量') + qty_num = fields.Integer('变更数量') + + @api.onchange('qty_num') + def _onchange_qty_num(self): + for item in self: + if item.qty_num > item.qty: + raise ValidationError('变更数量不能比库存数量大!!!') class SfStockMoveLine(models.Model): diff --git a/sf_warehouse/views/shelf_location.xml b/sf_warehouse/views/shelf_location.xml index 2716dd91..418f7d5c 100644 --- a/sf_warehouse/views/shelf_location.xml +++ b/sf_warehouse/views/shelf_location.xml @@ -133,9 +133,11 @@ type="action" context="{'default_name':name, 'default_current_name':name, + 'default_current_product_sn_ids':product_sn_ids, + 'default_lot_id':product_sn_id, 'default_current_shelf_id':shelf_id, 'default_current_location_id':location_id, - 'default_current_barcode':barcode, + 'default_current_barcode_id':id, 'default_current_product_id':product_id, }" class="btn-primary" attrs="{'invisible':[('location_status','!=','占用')]}"/> diff --git a/sf_warehouse/wizard/wizard.py b/sf_warehouse/wizard/wizard.py index db64fe07..62ed5771 100644 --- a/sf_warehouse/wizard/wizard.py +++ b/sf_warehouse/wizard/wizard.py @@ -8,17 +8,23 @@ class ShelfLocationWizard(models.TransientModel): name = fields.Char('') - current_location_id = fields.Many2one('stock.location', string='所属库区', readonly=True) + lot_id = fields.Many2one('stock.lot', string="序列号", readonly=True) + current_location_id = fields.Many2one('stock.location', string='所属库区', readonly=True) current_shelf_id = fields.Many2one('sf.shelf', string='当前货架', readonly=True) - current_barcode = fields.Char('当前货位编码', readonly=True) + current_barcode_id = fields.Many2one('sf.shelf.location', string='当前货位编码', readonly=True) current_name = fields.Char('当前货位名称', readonly=True) current_product_id = fields.Many2one('product.product', string='产品', readonly=True) + current_product_sn_ids = fields.Many2many('sf.shelf.location.lot', 'shelf_location_wizard', string='产品批次号', + readonly=True) + destination_location_id = fields.Many2one('stock.location', string='目标库区', compute='_compute_destination_name') destination_shelf_id = fields.Many2one('sf.shelf', string='目标货架', compute='_compute_destination_name') destination_barcode_id = fields.Many2one('sf.shelf.location', string='目标货位编码', required=True, - domain="") + domain="[('product_id', 'in', (False, current_product_id))]") destination_name = fields.Char('目标货位名称', compute='_compute_destination_name') + destination_product_sn_ids = fields.Many2many('sf.shelf.location.lot', 'shelf_location_wizard', string='批次号', + domain="[('shelf_location_id', '=', current_barcode_id)]") def return_domain(self): val = [('location_status', '=', '空闲')] @@ -32,9 +38,11 @@ class ShelfLocationWizard(models.TransientModel): def _compute_destination_name(self): if self.destination_barcode_id: self.destination_name = self.destination_barcode_id.name + self.destination_location_id = self.destination_barcode_id.location_id.id self.destination_shelf_id = self.destination_barcode_id.shelf_id.id else: self.destination_name = '' + self.destination_location_id = False self.destination_shelf_id = False # @@ -43,22 +51,46 @@ class ShelfLocationWizard(models.TransientModel): # if self.destination_barcode_id: # self.destination_shelf_id = self.destination_barcode_id.shelf_id.id - def confirm_the_change(self): - shelf_location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.current_barcode)]) - # 变更货位 - if self.destination_barcode_id and shelf_location: - if self.destination_barcode_id.product_id and self.destination_barcode_id.product_id == shelf_location.product_id and not self.destination_barcode_id.product_sn_id: - self.destination_barcode_id.product_num += shelf_location.product_num - else: - self.destination_barcode_id.product_sn_id = shelf_location.product_sn_id.id - self.destination_barcode_id.product_id = shelf_location.product_id.id - self.destination_barcode_id.product_num = shelf_location.product_num + def create_stock_moves(self, lot_id, num): + # 创建产品货位变更的库存移动记录 + stock_move_id = self.env['stock.move'].sudo().create({ + 'name': 'HWBG/%s' % self.id, + 'product_id': self.current_product_id.id, + 'location_id': self.current_location_id.id, + 'location_dest_id': self.destination_location_id.id, + 'product_uom_qty': num, + 'state': 'done' + }) + # 创建移动历史记录 + stock_move_line_id = self.env['stock.move.line'].sudo().create({ + 'product_id': self.current_product_id.id, + 'lot_id': lot_id.id, + 'move_id': stock_move_id.id, + 'current_location_id': self.current_barcode_id.id, + 'destination_location_id': self.destination_barcode_id.id, + 'install_tool_time': fields.Datetime.now(), + 'qty_done': num, + 'state': 'done' + }) - shelf_location.product_sn_id = False - shelf_location.product_id = False - shelf_location.product_num = 0 + return stock_move_id, stock_move_line_id + + def confirm_the_change(self): + if self.destination_barcode_id: + if self.lot_id: + self.current_barcode_id.product_sn_id = False + self.destination_barcode_id.product_sn_id = self.lot_id.id + self.create_stock_moves(self.lot_id, 1) + elif self.current_product_sn_ids: + for current_product_sn_id in self.current_product_sn_ids: + self.create_stock_moves(current_product_sn_id.lot_id, current_product_sn_id.qty_num) + current_product_sn_id.write({ + 'qty_num': 0 + }) + else: + raise ValidationError('没有需要变更的批次/序列号!') else: - raise ValidationError('目标货位出错,请联系管理员!') + raise ValidationError('请选择目标货位编码!') # 关闭弹出窗口 return {'type': 'ir.actions.act_window_close'} diff --git a/sf_warehouse/wizard/wizard_view.xml b/sf_warehouse/wizard/wizard_view.xml index 1bb95e15..d77a813c 100644 --- a/sf_warehouse/wizard/wizard_view.xml +++ b/sf_warehouse/wizard/wizard_view.xml @@ -6,27 +6,45 @@
- + - + + + + + + + + + + - - - + + + + + + + + + + + +
From b6acbb835783b1dd12983b8518f24bdfc2060256 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Wed, 5 Jun 2024 10:23:13 +0800 Subject: [PATCH 08/17] =?UTF-8?q?1=E3=80=81=E5=8A=9F=E8=83=BD=E5=88=80?= =?UTF-8?q?=E5=85=B7=E6=8B=86=E8=A7=A3=E5=8D=95=E6=96=B0=E5=A2=9E=E6=8B=86?= =?UTF-8?q?=E8=A7=A3=E5=8D=95=E5=8F=B7=EF=BC=8C=E4=BC=98=E5=8C=96=E6=8B=86?= =?UTF-8?q?=E8=A7=A3=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 42 ++++++++++++++------ sf_tool_management/views/tool_base_views.xml | 7 +++- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 87dcfb28..1d482781 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -679,6 +679,22 @@ class FunctionalToolDismantle(models.Model): raise ValidationError('该功能刀具因为%s拆解,无需录入库位' % self.dismantle_cause) name = fields.Char('名称', related='functional_tool_id.name') + code = fields.Char('拆解单号', default=lambda self: self._get_code(), readonly=True) + + def _get_code(self): + """ + 自动生成拆解单编码 + """ + new_time = str(fields.Date.today()) + datetime = new_time[2:4] + new_time[5:7] + new_time[-2:] + functional_tool_dismantle = self.env['sf.functional.tool.dismantle'].sudo().search( + [('code', 'ilike', datetime)], limit=1, order="id desc") + if not functional_tool_dismantle: + num = "%03d" % 1 + else: + m = int(functional_tool_dismantle.code[-3:]) + 1 + num = "%03d" % m + return 'GNDJ-CJD-%s-%s' % (datetime, num) functional_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', required=True, domain=[('functional_tool_status', '!=', '已拆除')]) @@ -824,7 +840,7 @@ class FunctionalToolDismantle(models.Model): def confirmation_disassembly(self): logging.info('%s刀具确认开始拆解' % self.dismantle_cause) - t_id = self.id + code = self.code if self.functional_tool_id.functional_tool_status == '已拆除': raise ValidationError('Rfid为【%s】的功能刀具已经拆解,请勿重复操作!' % self.functional_tool_id.rfid_dismantle) location = self.env['stock.location'].search([('name', '=', '刀具组装位置')]) @@ -849,19 +865,19 @@ class FunctionalToolDismantle(models.Model): # 除刀柄外物料报废 入库到Scrap if self.integral_product_id: self.integral_product_id.dismantle_stock_moves(False, self.integral_lot_id, location, - location_dest_scrap, t_id) + location_dest_scrap, code) elif self.blade_product_id: self.blade_product_id.dismantle_stock_moves(False, self.blade_lot_id, location, location_dest_scrap, - t_id) + code) if self.bar_product_id: self.bar_product_id.dismantle_stock_moves(False, self.bar_lot_id, location, location_dest_scrap, - t_id) + code) elif self.pad_product_id: self.pad_product_id.dismantle_stock_moves(False, self.pad_lot_id, location, location_dest_scrap, - t_id) + code) if self.chuck_product_id: self.chuck_product_id.dismantle_stock_moves(False, self.chuck_lot_id, location, location_dest_scrap, - t_id) + code) # ===========功能刀具[磨削]拆解============== # elif self.dismantle_cause in ['刀具需磨削']: # location_dest = self.env['stock.location'].search([('name', '=', '磨削房')]) @@ -881,19 +897,19 @@ class FunctionalToolDismantle(models.Model): # 除刀柄外物料拆解 入库到具体货位 if self.integral_freight_id: self.integral_product_id.dismantle_stock_moves(self.integral_freight_id, self.integral_lot_id, location, - location_dest, t_id) + location_dest, code) elif self.blade_freight_id: self.blade_product_id.dismantle_stock_moves(self.blade_freight_id, self.blade_lot_id, location, - location_dest, t_id) + location_dest, code) if self.bar_freight_id: self.bar_product_id.dismantle_stock_moves(self.bar_freight_id, self.bar_lot_id, location, - location_dest, t_id) + location_dest, code) elif self.pad_freight_id: self.pad_product_id.dismantle_stock_moves(self.pad_freight_id, self.pad_lot_id, location, - location_dest, t_id) + location_dest, code) if self.chuck_freight_id: self.chuck_product_id.dismantle_stock_moves(self.chuck_freight_id, self.chuck_lot_id, location, - location_dest, t_id) + location_dest, code) # ===============删除功能刀具的Rfid字段的值, 赋值给Rfid(已拆解)字段===== self.functional_tool_id.write({ 'rfid_dismantle': self.functional_tool_id.rfid, @@ -914,10 +930,10 @@ class FunctionalToolDismantle(models.Model): class ProductProduct(models.Model): _inherit = 'product.product' - def dismantle_stock_moves(self, shelf_location_id, lot_id, location_id, location_dest_id, t_id): + def dismantle_stock_moves(self, shelf_location_id, lot_id, location_id, location_dest_id, code): # 创建功能刀具拆解单产品库存移动记录 stock_move_id = self.env['stock.move'].sudo().create({ - 'name': 'DJCJ/%s' % t_id, + 'name': code, 'product_id': self.id, 'location_id': location_id.id, 'location_dest_id': location_dest_id.id, diff --git a/sf_tool_management/views/tool_base_views.xml b/sf_tool_management/views/tool_base_views.xml index 7e74b8fc..54f9d7f9 100644 --- a/sf_tool_management/views/tool_base_views.xml +++ b/sf_tool_management/views/tool_base_views.xml @@ -778,6 +778,7 @@ sf.functional.tool.dismantle + @@ -805,13 +806,14 @@

- +

+ @@ -946,6 +948,7 @@ + From 2065625cd631573072b0636720889cda6b6be71b Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Fri, 7 Jun 2024 09:42:09 +0800 Subject: [PATCH 09/17] =?UTF-8?q?1=E3=80=81=E7=BB=84=E8=A3=85=E5=8D=95?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 41 ++++++++++++---- sf_tool_management/models/functional_tool.py | 7 +-- .../views/functional_tool_views.xml | 4 ++ sf_tool_management/views/tool_base_views.xml | 47 +++++++++++++------ sf_tool_management/wizard/wizard.py | 1 + 5 files changed, 75 insertions(+), 25 deletions(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index cfb68b7f..3f4031ce 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -181,6 +181,7 @@ class MachineTableToolChangingApply(models.Model): class CAMWorkOrderProgramKnifePlan(models.Model): _name = 'sf.cam.work.order.program.knife.plan' + _inherit = ['mail.thread'] _description = 'CAM工单程序用刀计划' name = fields.Char('工单任务编号') @@ -228,7 +229,7 @@ class CAMWorkOrderProgramKnifePlan(models.Model): estimated_processing_time = fields.Char('预计加工时间') plan_execute_status = fields.Selection([('0', '待下发'), ('1', '执行中'), ('2', '已完成')], - string='计划执行状态', default='0', readonly=False) + string='计划执行状态', default='0', readonly=False, tracking=True) sf_functional_tool_assembly_id = fields.Many2one('sf.functional.tool.assembly', '功能刀具组装', readonly=True) @@ -362,6 +363,7 @@ class CAMWorkOrderProgramKnifePlan(models.Model): class FunctionalToolAssembly(models.Model): _name = 'sf.functional.tool.assembly' + _inherit = ['mail.thread'] _description = '功能刀具组装' _order = 'assemble_status, use_tool_time asc' @@ -396,7 +398,7 @@ class FunctionalToolAssembly(models.Model): applicant = fields.Char(string='申请人', readonly=True) apply_time = fields.Datetime(string='申请时间', default=fields.Datetime.now(), readonly=True) assemble_status = fields.Selection([('0', '待组装'), ('1', '已组装')], string='组装状态', default='0', - readonly=True) + tracking=True, readonly=True) cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', readonly=True) whether_standard_knife = fields.Boolean(string='是否标准刀', default=True, readonly=True) reason_for_applying = fields.Char(string='申请原因', readonly=True) @@ -668,7 +670,7 @@ class FunctionalToolAssembly(models.Model): class FunctionalToolDismantle(models.Model): _name = 'sf.functional.tool.dismantle' - _inherit = ["barcodes.barcode_events_mixin"] + _inherit = ["barcodes.barcode_events_mixin", 'mail.thread'] _description = '功能刀具拆解' def on_barcode_scanned(self, barcode): @@ -758,7 +760,7 @@ class FunctionalToolDismantle(models.Model): dismantle_cause = fields.Selection( [('寿命到期报废', '寿命到期报废'), ('崩刀报废', '崩刀报废'), ('更换为其他刀具', '更换为其他刀具'), - ('刀具需磨削', '刀具需磨削')], string='拆解原因', required=True) + ('刀具需磨削', '刀具需磨削')], string='拆解原因', required=True, tracking=True) dismantle_data = fields.Datetime('拆解日期', readonly=True) dismantle_person = fields.Char('拆解人', readonly=True) image = fields.Binary('图片', readonly=True) @@ -766,7 +768,7 @@ class FunctionalToolDismantle(models.Model): scrap_id = fields.Char('报废单号', readonly=True) grinding_id = fields.Char('磨削单号', readonly=True) - state = fields.Selection([('待拆解', '待拆解'), ('已拆解', '已拆解')], default='待拆解') + state = fields.Selection([('待拆解', '待拆解'), ('已拆解', '已拆解')], default='待拆解', tracking=True) active = fields.Boolean('有效', default=True) # 刀柄 @@ -778,7 +780,7 @@ 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) + scrap_boolean = fields.Boolean(string='刀柄是否报废', default=False, tracking=True) # 整体式 integral_product_id = fields.Many2one('product.product', string='整体式刀具', @@ -888,6 +890,27 @@ class FunctionalToolDismantle(models.Model): item.pad_lot_id = False item.chuck_lot_id = False + def location_duplicate_check(self): + """ + 目标货位去重校验 + """ + if self.blade_freight_id: + if self.bar_freight_id: + if self.blade_freight_id == self.bar_freight_id: + raise ValidationError('【刀片】和【刀杆】的目标货位重复,请重新选择!') + elif self.pad_freight_id: + if self.blade_freight_id == self.pad_freight_id: + raise ValidationError('【刀片】和【刀盘】的目标货位重复,请重新选择!') + if self.chuck_freight_id: + if self.chuck_freight_id == self.integral_freight_id: + raise ValidationError('【夹头】和【整体式刀具】的目标货位重复,请重新选择!') + if self.chuck_freight_id == self.blade_freight_id: + raise ValidationError('【夹头】和【刀片】的目标货位重复,请重新选择!') + if self.chuck_freight_id == self.bar_freight_id: + raise ValidationError('【夹头】和【刀杆】的目标货位重复,请重新选择!') + if self.chuck_freight_id == self.pad_freight_id: + raise ValidationError('【夹头】和【刀盘】的目标货位重复,请重新选择!') + def confirmation_disassembly(self): logging.info('%s刀具确认开始拆解' % self.dismantle_cause) code = self.code @@ -897,6 +920,8 @@ class FunctionalToolDismantle(models.Model): if self.functional_tool_id.tool_room_num == 0: raise ValidationError('Rfid为【%s】的功能刀具当前位置为【%s】,不能进行拆解!' % ( self.rfid, self.functional_tool_id.current_location)) + # 目标重复校验 + self.location_duplicate_check() location = self.env['stock.location'].search([('name', '=', '刀具组装位置')]) location_dest = self.env['stock.location'].search([('name', '=', '刀具房')]) # =================刀柄是否[报废]拆解======= @@ -908,11 +933,11 @@ class FunctionalToolDismantle(models.Model): functional_tool_assembly = self.functional_tool_id.functional_tool_name_id if self.scrap_boolean: # 刀柄报废 入库到Scrap - lot.create_stock_quant(location, location_dest_scrap, functional_tool_assembly.id, '功能刀具拆解', + lot.create_stock_quant(location, location_dest_scrap, functional_tool_assembly.id, code, functional_tool_assembly, functional_tool_assembly.tool_groups_id) else: # 刀柄不报废 入库到刀具房 - lot.create_stock_quant(location, location_dest, functional_tool_assembly.id, '功能刀具拆解', + lot.create_stock_quant(location, location_dest, functional_tool_assembly.id, code, functional_tool_assembly, functional_tool_assembly.tool_groups_id) # ==============功能刀具[报废]拆解================ if self.dismantle_cause in ['寿命到期报废', '崩刀报废']: diff --git a/sf_tool_management/models/functional_tool.py b/sf_tool_management/models/functional_tool.py index 6f7e14bb..84df4b8b 100644 --- a/sf_tool_management/models/functional_tool.py +++ b/sf_tool_management/models/functional_tool.py @@ -318,6 +318,7 @@ class StockMoveLine(models.Model): class RealTimeDistributionOfFunctionalTools(models.Model): _name = 'sf.real.time.distribution.of.functional.tools' + _inherit = ['mail.thread'] _description = '功能刀具安全库存' name = fields.Char('名称', readonly=True, compute='_compute_name', store=True) @@ -331,11 +332,11 @@ class RealTimeDistributionOfFunctionalTools(models.Model): side_shelf_num = fields.Integer(string='线边刀库数量') on_tool_stock_num = fields.Integer(string='机内刀库数量') tool_stock_total = fields.Integer(string='当前库存量', readonly=True) - min_stock_num = fields.Integer('最低库存量') - max_stock_num = fields.Integer('最高库存量') + min_stock_num = fields.Integer('最低库存量', tracking=True) + max_stock_num = fields.Integer('最高库存量', tracking=True) batch_replenishment_num = fields.Integer('批次补货量', readonly=True, compute='_compute_batch_replenishment_num', store=True) - unit = fields.Char('单位') + unit = fields.Char('单位', default="件") image = fields.Binary('图片', readonly=False) coarse_middle_thin = fields.Selection([("1", "粗"), ('2', '中'), ('3', '精')], string='粗/中/精', readonly=False) diff --git a/sf_tool_management/views/functional_tool_views.xml b/sf_tool_management/views/functional_tool_views.xml index 100ee297..35bf6d21 100644 --- a/sf_tool_management/views/functional_tool_views.xml +++ b/sf_tool_management/views/functional_tool_views.xml @@ -411,6 +411,10 @@
+
+ + +
diff --git a/sf_tool_management/views/tool_base_views.xml b/sf_tool_management/views/tool_base_views.xml index 7a8eed80..3366c52e 100644 --- a/sf_tool_management/views/tool_base_views.xml +++ b/sf_tool_management/views/tool_base_views.xml @@ -376,6 +376,10 @@ +
+ + +
@@ -464,8 +468,8 @@
- - + +
From bae947bdca15cc86dfccf50dc20f0f90dfd74f7c Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 11 Jun 2024 15:18:13 +0800 Subject: [PATCH 12/17] =?UTF-8?q?1=E3=80=81=E6=B7=BB=E5=8A=A0=E9=87=87?= =?UTF-8?q?=E8=B4=AD=E5=85=A5=E5=BA=93=E6=97=B6=E5=AF=B9=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E5=BD=95=E5=85=A5=E7=9A=84Rfid=E8=BF=9B=E8=A1=8C=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E6=A0=A1=E9=AA=8C=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_warehouse/models/model.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 155d5924..286cdf88 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -968,6 +968,8 @@ class SfStockPicking(models.Model): if move and move.product_id.cutting_tool_material_id.name == '刀柄' or '托盘' in ( move.product_id.fixture_material_id.name or ''): for item in move.move_line_nosuggest_ids: + if self.env['stock.lot'].search([('rfid', '=', item.rfid)]): + raise ValidationError('该Rfid【%s】在系统中已经存在,请重新录入!' % item.rfid) if item.location_dest_id.name == '进货': if not item.rfid: raise ValidationError('你需要提供%s的Rfid' % move.product_id.name) From 7d7f0348d22d45082eadd4fa1f81dafc76e60e64 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 11 Jun 2024 17:00:25 +0800 Subject: [PATCH 13/17] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E4=BA=A7?= =?UTF-8?q?=E5=93=81=E6=8C=89=E6=89=B9=E9=87=8F=E9=87=87=E8=B4=AD=E5=85=A5?= =?UTF-8?q?=E5=BA=93=E6=97=B6=EF=BC=8C=E6=B2=A1=E6=9C=89=E7=94=9F=E6=88=90?= =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E7=A0=81=E9=97=AE=E9=A2=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/wizard/wizard.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py index 41a78ed0..eb6f9fc1 100644 --- a/sf_tool_management/wizard/wizard.py +++ b/sf_tool_management/wizard/wizard.py @@ -837,19 +837,15 @@ class ProductProduct(models.Model): return stock_lot - def get_stock_lot_name(self, tool_assembly_order_id): + def get_stock_lot_name(self, obj): """ 生成功能刀具序列号 """ - tool_assembly_order = self.env['sf.functional.tool.assembly.order'].search( - [('id', '=', tool_assembly_order_id)]) - code = 'JKM-T-' + str(tool_assembly_order.after_assembly_functional_tool_type_id.code) + '-' + str( - tool_assembly_order.after_assembly_functional_tool_diameter) + '-' + company = obj.cutting_tool_cutterhandle_model_id.code.split('-', 1)[0] new_time = datetime.strptime(str(fields.Date.today()), "%Y-%m-%d").strftime("%Y%m%d") - code += str(new_time) + '-' + code = '%s-GNDJ-%s-%s' % (company, obj.after_assembly_functional_tool_type_id.code, new_time) stock_lot_id = self.env['stock.lot'].sudo().search( - [('name', 'like', new_time), ('product_id.categ_type', '=', '功能刀具'), - ('product_id.tracking', '=', 'serial')], limit=1, order="id desc") + [('name', 'like', code)], limit=1, order="id desc") if not stock_lot_id: num = "%03d" % 1 else: From 469839f38e7b0af7c582e07a950fa4433e658c34 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Wed, 12 Jun 2024 10:02:15 +0800 Subject: [PATCH 14/17] =?UTF-8?q?1=E3=80=81=E5=A4=84=E7=90=86=E4=BA=8C?= =?UTF-8?q?=E7=BB=B4=E7=A0=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 20 ++++++++++++++++++++ sf_warehouse/models/model.py | 5 +++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index f0961947..950e0948 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -3,6 +3,7 @@ import base64 import qrcode from collections import defaultdict, namedtuple import logging +import io import json from re import split as regex_split from re import findall as regex_findall @@ -709,6 +710,25 @@ class ReStockMove(models.Model): datetime.now().strftime("%Y%m%d"), origin), 1) move_lines_commands = self._generate_serial_move_line_commands_tool_lot(lot_names) self.write({'move_line_nosuggest_ids': move_lines_commands}) + for item in self.move_line_nosuggest_ids: + if item.lot_name: + item.lot_qr_code = self.compute_lot_qr_code(item.lot_name) + + def compute_lot_qr_code(self, lot_name): + qr = qrcode.QRCode( + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=10, + border=4, + ) + qr.add_data(lot_name) + qr.make(fit=True) + img = qr.make_image(fill_color="black", back_color="white") + buffer = io.BytesIO() + img.save(buffer, format="PNG") + binary_data = buffer.getvalue() + data = base64.b64encode(binary_data).decode() # 确保返回的是字符串形式的数据 + return data def _get_tool_next_serial(self, company, product, origin): """Return the next serial number to be attributed to the product.""" diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index 286cdf88..1c9b11f4 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -968,8 +968,9 @@ class SfStockPicking(models.Model): if move and move.product_id.cutting_tool_material_id.name == '刀柄' or '托盘' in ( move.product_id.fixture_material_id.name or ''): for item in move.move_line_nosuggest_ids: - if self.env['stock.lot'].search([('rfid', '=', item.rfid)]): - raise ValidationError('该Rfid【%s】在系统中已经存在,请重新录入!' % item.rfid) + if item.rfid: + if self.env['stock.lot'].search([('rfid', '=', item.rfid)]): + raise ValidationError('该Rfid【%s】在系统中已经存在,请重新录入!' % item.rfid) if item.location_dest_id.name == '进货': if not item.rfid: raise ValidationError('你需要提供%s的Rfid' % move.product_id.name) From 42cded8c6481364387d382b2b1eee7c4a6d3e6da Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Wed, 12 Jun 2024 10:24:16 +0800 Subject: [PATCH 15/17] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=88=80=E5=85=B7=E5=BA=8F=E5=88=97=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/functional_tool.py | 2 +- sf_tool_management/views/functional_tool_views.xml | 2 +- sf_tool_management/wizard/wizard.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sf_tool_management/models/functional_tool.py b/sf_tool_management/models/functional_tool.py index 84df4b8b..628f0b52 100644 --- a/sf_tool_management/models/functional_tool.py +++ b/sf_tool_management/models/functional_tool.py @@ -21,7 +21,7 @@ class FunctionalCuttingToolEntity(models.Model): name = fields.Char('名称') tool_name_id = fields.Many2one('sf.tool.inventory', '功能刀具名称') sf_cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀具型号') - barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True) + barcode_id = fields.Many2one('stock.lot', string='序列号', readonly=True) sf_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', group_expand='_read_group_mrs_cutting_tool_type_id', compute_sudo=True) diff --git a/sf_tool_management/views/functional_tool_views.xml b/sf_tool_management/views/functional_tool_views.xml index 35bf6d21..1dafacf3 100644 --- a/sf_tool_management/views/functional_tool_views.xml +++ b/sf_tool_management/views/functional_tool_views.xml @@ -86,7 +86,7 @@ - + Date: Wed, 12 Jun 2024 14:20:15 +0800 Subject: [PATCH 16/17] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E7=BB=84?= =?UTF-8?q?=E8=A3=85=E6=97=B6=E9=87=8D=E5=A4=8D=E9=80=89=E5=8F=96=E8=B4=A7?= =?UTF-8?q?=E4=BD=8D=E6=97=B6=EF=BC=8C=E6=89=B9=E6=AC=A1=E5=8F=B7=E6=B6=88?= =?UTF-8?q?=E5=A4=B1=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/wizard/wizard.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py index f0a67482..40dbcc52 100644 --- a/sf_tool_management/wizard/wizard.py +++ b/sf_tool_management/wizard/wizard.py @@ -246,6 +246,11 @@ class FunctionalToolAssemblyOrder(models.TransientModel): sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', related='integral_product_id.brand_id') + @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') def _compute_integral_product_id(self): if self.integral_freight_lot_id: @@ -266,6 +271,11 @@ class FunctionalToolAssemblyOrder(models.TransientModel): related='blade_product_id.specification_id') sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', related='blade_product_id.brand_id') + @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') def _compute_blade_product_id(self): if self.blade_freight_lot_id: @@ -286,6 +296,11 @@ class FunctionalToolAssemblyOrder(models.TransientModel): related='bar_product_id.specification_id') sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', related='bar_product_id.brand_id') + @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') def _compute_bar_product_id(self): if self.bar_freight_lot_id: @@ -306,6 +321,11 @@ class FunctionalToolAssemblyOrder(models.TransientModel): related='pad_product_id.specification_id') sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', related='pad_product_id.brand_id') + @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') def _compute_pad_product_id(self): if self.pad_freight_lot_id: @@ -346,6 +366,11 @@ class FunctionalToolAssemblyOrder(models.TransientModel): related='chuck_product_id.specification_id') sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', related='chuck_product_id.brand_id') + @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') def _compute_chuck_product_id(self): if self.chuck_freight_lot_id: From 0ad7e72b15ae4141aa76fafb797024ee7c24a27c Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Wed, 12 Jun 2024 16:28:42 +0800 Subject: [PATCH 17/17] =?UTF-8?q?1=E3=80=81=E8=A7=A3=E5=86=B3=20=E5=88=80?= =?UTF-8?q?=E5=85=B7=E7=BB=84=E8=A3=85=E9=80=89=E6=8B=A9=E7=9A=84=E6=89=B9?= =?UTF-8?q?=E6=AC=A1=E5=8F=B7=E9=98=9F=E5=8F=8B=E7=89=A9=E6=96=99=E5=8F=AA?= =?UTF-8?q?=E5=89=A9=E4=B8=8B1=E4=B8=AA=E6=97=B6-=E7=BB=84=E8=A3=85?= =?UTF-8?q?=E5=AE=8C=E8=AF=A5=E5=8D=95=E6=8D=AE=E8=AF=A6=E6=83=85=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E6=89=B9=E6=AC=A1=E4=BF=A1=E6=81=AF=20?= =?UTF-8?q?=E7=9A=84bug=EF=BC=9B2=E3=80=81=E8=B0=83=E6=95=B4=E6=8B=86?= =?UTF-8?q?=E8=A7=A3=E5=8D=95=E7=95=8C=E9=9D=A2=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 30 ++++++------ sf_tool_management/views/tool_base_views.xml | 50 ++++++++------------ sf_tool_management/wizard/wizard.py | 8 ++-- 3 files changed, 38 insertions(+), 50 deletions(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 3f4031ce..39c43d8e 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -427,11 +427,11 @@ class FunctionalToolAssembly(models.Model): sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', related='integral_product_id.brand_id') - @api.depends('integral_freight_barcode_id') + @api.depends('integral_lot_id') def _compute_integral_product_id(self): for item in self: - if item.integral_freight_barcode_id: - item.integral_product_id = item.integral_freight_barcode_id.product_id.id + if item.integral_lot_id: + item.integral_product_id = item.integral_lot_id.product_id.id # =================刀片型号============= blade_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀片货位') @@ -444,11 +444,11 @@ class FunctionalToolAssembly(models.Model): related='blade_product_id.specification_id') sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', related='blade_product_id.brand_id') - @api.depends('blade_freight_barcode_id') + @api.depends('blade_lot_id') def _compute_blade_product_id(self): for item in self: - if item.blade_freight_barcode_id: - item.blade_product_id = item.blade_freight_barcode_id.product_id.id + if item.blade_lot_id: + item.blade_product_id = item.blade_lot_id.product_id.id # ==============刀杆型号================ bar_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀杆货位') @@ -461,11 +461,11 @@ class FunctionalToolAssembly(models.Model): related='bar_product_id.specification_id') sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', related='bar_product_id.brand_id') - @api.depends('bar_freight_barcode_id') + @api.depends('bar_lot_id') def _compute_bar_product_id(self): for item in self: - if item.bar_freight_barcode_id: - item.bar_product_id = item.bar_freight_barcode_id.product_id.id + if item.bar_lot_id: + item.bar_product_id = item.bar_lot_id.product_id.id # =============刀盘型号================ pad_freight_barcode_id = fields.Many2one('sf.shelf.location', string='刀盘货位') @@ -478,11 +478,11 @@ class FunctionalToolAssembly(models.Model): related='pad_product_id.specification_id') sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', related='pad_product_id.brand_id') - @api.depends('pad_freight_barcode_id') + @api.depends('pad_lot_id') def _compute_pad_product_id(self): for item in self: - if item.pad_freight_barcode_id: - item.pad_product_id = item.pad_freight_barcode_id.product_id.id + if item.pad_lot_id: + item.pad_product_id = item.pad_lot_id.product_id.id # ==============刀柄型号============== handle_freight_rfid = fields.Char('刀柄Rfid', compute='_compute_handle_product_id', store=True) @@ -516,11 +516,11 @@ class FunctionalToolAssembly(models.Model): related='chuck_product_id.specification_id') sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', related='chuck_product_id.brand_id') - @api.depends('chuck_freight_barcode_id') + @api.depends('chuck_lot_id') def _compute_chuck_product_id(self): for item in self: - if item.chuck_freight_barcode_id: - item.chuck_product_id = item.chuck_freight_barcode_id.product_id.id + if item.chuck_lot_id: + item.chuck_product_id = item.chuck_lot_id.product_id.id # ==================待删除字段================== integral_freight_barcode = fields.Char('整体式刀具货位') diff --git a/sf_tool_management/views/tool_base_views.xml b/sf_tool_management/views/tool_base_views.xml index 3366c52e..050b4d21 100644 --- a/sf_tool_management/views/tool_base_views.xml +++ b/sf_tool_management/views/tool_base_views.xml @@ -804,90 +804,78 @@ + + + - - - - - - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + - - - - - + + + diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py index 40dbcc52..6aec47e9 100644 --- a/sf_tool_management/wizard/wizard.py +++ b/sf_tool_management/wizard/wizard.py @@ -617,6 +617,10 @@ class FunctionalToolAssemblyOrder(models.TransientModel): # 创建组装入库单 # 创建功能刀具批次/序列号记录 stock_lot = product_id.create_assemble_warehouse_receipt(self.id, functional_tool_assembly, self) + # 封装功能刀具数据,用于更新组装单信息 + desc_1 = self.get_desc_1(stock_lot) + # 封装功能刀具数据,用于创建功能刀具记录 + desc_2 = self.get_desc_2(stock_lot, functional_tool_assembly) # 创建刀具组装入库单 self.env['stock.picking'].create_stocking_picking(stock_lot, functional_tool_assembly, self) # 刀具物料出库 @@ -639,8 +643,6 @@ class FunctionalToolAssemblyOrder(models.TransientModel): self.chuck_freight_lot_id, self.assembly_order_code) # ============================创建功能刀具列表、安全库存记录=============================== - # 封装功能刀具数据 - desc_2 = self.get_desc_2(stock_lot, functional_tool_assembly) # 创建功能刀具列表记录 record_1 = self.env['sf.functional.cutting.tool.entity'].create(desc_2) # 创建安全库存信息 @@ -649,8 +651,6 @@ class FunctionalToolAssemblyOrder(models.TransientModel): }, record_1) # =====================修改功能刀具组装单、机床换刀申请、CAM工单程序用刀计划的状态============== - # 封装功能刀具数据 - desc_1 = self.get_desc_1(stock_lot) # 修改功能刀具组装单信息 functional_tool_assembly.write(desc_1) if functional_tool_assembly.sf_machine_table_tool_changing_apply_id: