From 857d5d8916c95730f8740ae6ef771df1bf2c0dde Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Fri, 19 Apr 2024 20:12:32 +0800 Subject: [PATCH 1/4] =?UTF-8?q?1=E3=80=81=E6=96=B0=E5=A2=9E=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=88=80=E5=85=B7=E6=8B=86=E8=A7=A3=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E5=8F=8A=E5=85=B6=E5=89=8D=E7=AB=AF=E7=9A=84tree=E3=80=81form?= =?UTF-8?q?=E8=A7=86=E5=9B=BE=EF=BC=8C=E6=96=B0=E5=A2=9E=E6=89=AB=E7=A0=81?= =?UTF-8?q?=E5=BD=95=E5=85=A5=E9=9C=80=E8=A6=81=E6=8B=86=E8=A7=A3=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 128 +++++++++++++++- .../security/ir.model.access.csv | 6 +- sf_tool_management/views/menu_view.xml | 8 + sf_tool_management/views/tool_base_views.xml | 143 ++++++++++++++++++ sf_tool_management/wizard/wizard.py | 55 ++++--- 5 files changed, 309 insertions(+), 31 deletions(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 83b4b550..235935a0 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -423,7 +423,8 @@ class FunctionalToolAssembly(models.Model): 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)]) + location = self.env['sf.shelf.location'].sudo().search( + [('barcode', '=', item.integral_freight_barcode)]) if location: item.integral_product_id = location.product_id.id else: @@ -442,7 +443,7 @@ class FunctionalToolAssembly(models.Model): @api.depends('blade_freight_barcode') def _compute_blade_product_id(self): for item in self: - if item.integral_freight_barcode: + 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 @@ -462,7 +463,7 @@ class FunctionalToolAssembly(models.Model): @api.depends('bar_freight_barcode') def _compute_bar_product_id(self): for item in self: - if item.integral_freight_barcode: + 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 @@ -482,7 +483,7 @@ class FunctionalToolAssembly(models.Model): @api.depends('pad_freight_barcode') def _compute_pad_product_id(self): for item in self: - if item.integral_freight_barcode: + 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 @@ -523,7 +524,7 @@ class FunctionalToolAssembly(models.Model): @api.depends('chuck_freight_barcode') def _compute_chuck_product_id(self): for item in self: - if item.integral_freight_barcode: + 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 @@ -631,3 +632,120 @@ class FunctionalToolAssembly(models.Model): code = self._get_code(obj.loading_task_source) obj.assembly_order_code = code return obj + + +class FunctionalToolDismantle(models.Model): + _name = 'sf.functional.tool.dismantle' + _inherit = ["barcodes.barcode_events_mixin"] + _description = '功能刀具拆解' + + def on_barcode_scanned(self, barcode): + """ + 扫码 + """ + tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search([('rfid', '=', barcode)]) + if tool_id: + self.functional_tool_id = tool_id.id + else: + pass + + name = fields.Char('名称', related='functional_tool_id.name') + + functional_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', required=True, + domain=[('functional_tool_status', '!=', '已拆除')]) + tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', store=True, + compute='_compute_functional_tool_num') + tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', compute='_compute_functional_tool_num', store=True) + diameter = fields.Integer(string='刀具直径(mm)', compute='_compute_functional_tool_num', store=True) + knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', compute='_compute_functional_tool_num', store=True) + rfid = fields.Char('Rfid', compute='_compute_functional_tool_num', store=True) + + dismantle_cause = fields.Selection( + [('寿命到期报废', '寿命到期报废'), ('崩刀报废', '崩刀报废'), ('更换为其他刀具', '更换为其他刀具'), + ('刀具需磨削', '刀具需磨削')], string='拆解原因', required=True) + dismantle_data = fields.Datetime('拆解日期', readonly=True) + dismantle_person = fields.Char('拆解人', readonly=True) + image = fields.Binary('图片', readonly=True) + + scrap_id = fields.Char('报废单号') + grinding_id = fields.Char('磨削单号') + + # 刀柄 + handle_product_id = fields.Many2one('product.product', string='刀柄', compute='_compute_functional_tool_num', + store=True) + handle_type_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号', + 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') + scrap_boolean = fields.Boolean(string='刀柄是否报废', default=False) + + # 整体式 + integral_product_id = fields.Many2one('product.product', string='整体式刀具', + compute='_compute_functional_tool_num', store=True) + integral_type_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号', + related='integral_product_id.cutting_tool_model_id') + integral_brand_id = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', + related='integral_product_id.brand_id') + integral_freight_barcode = fields.Char('整体式刀具目标货位') + + # 刀片 + blade_product_id = fields.Many2one('product.product', string='刀片', compute='_compute_functional_tool_num', + store=True) + 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_freight_barcode = fields.Char('刀片目标货位') + + # 刀杆 + bar_product_id = fields.Many2one('product.product', string='刀杆', compute='_compute_functional_tool_num', + store=True) + 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_freight_barcode = fields.Char('刀杆目标货位') + + # 刀盘 + pad_product_id = fields.Many2one('product.product', string='刀盘', compute='_compute_functional_tool_num', + store=True) + 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_freight_barcode = fields.Char('刀盘目标货位') + + # 夹头 + chuck_product_id = fields.Many2one('product.product', string='夹头', compute='_compute_functional_tool_num', + store=True) + 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_freight_barcode = fields.Char('夹头目标货位') + + @api.depends('functional_tool_id') + def _compute_functional_tool_num(self): + for item in self: + if item.functional_tool_id: + item.tool_groups_id = item.functional_tool_id.tool_groups_id.id + item.tool_type_id = item.functional_tool_id.sf_cutting_tool_type_id.id + item.diameter = item.functional_tool_id.functional_tool_diameter + item.knife_tip_r_angle = item.functional_tool_id.knife_tip_r_angle + item.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 + else: + item.tool_groups_id = False + item.tool_type_id = False + item.diameter = 0 + item.knife_tip_r_angle = 0 + item.rfid = '' + + item.handle_product_id = False + item.integral_product_id = False + item.blade_product_id = False + item.bar_product_id = False + item.pad_product_id = False + item.chuck_product_id = False diff --git a/sf_tool_management/security/ir.model.access.csv b/sf_tool_management/security/ir.model.access.csv index 3a7b4589..79800637 100644 --- a/sf_tool_management/security/ir.model.access.csv +++ b/sf_tool_management/security/ir.model.access.csv @@ -30,4 +30,8 @@ access_sf_tool_material_search,sf.tool.material.search,model_sf_tool_material_se access_sf_tool_material_search_group_plan_dispatch,sf.tool.material.search,model_sf_tool_material_search,sf_base.group_plan_dispatch,1,0,0,0 access_sf_fixture_material_search,sf.fixture.material.search,model_sf_fixture_material_search,sf_base.group_sf_order_user,1,0,0,0 -access_sf_fixture_material_search_group_plan_dispatch,sf.fixture.material.search,model_sf_fixture_material_search,sf_base.group_plan_dispatch,1,0,0,0 \ No newline at end of file +access_sf_fixture_material_search_group_plan_dispatch,sf.fixture.material.search,model_sf_fixture_material_search,sf_base.group_plan_dispatch,1,0,0,0 + + +access_sf_functional_tool_dismantle_group_sf_tool_user,sf.functional.tool.dismantle,model_sf_functional_tool_dismantle,sf_base.group_sf_tool_user,1,1,1,0 +access_sf_functional_tool_dismantle_group_plan_dispatch,sf.functional.tool.dismantle,model_sf_functional_tool_dismantle,sf_base.group_plan_dispatch,1,0,0,0 diff --git a/sf_tool_management/views/menu_view.xml b/sf_tool_management/views/menu_view.xml index 13a12725..eae7532e 100644 --- a/sf_tool_management/views/menu_view.xml +++ b/sf_tool_management/views/menu_view.xml @@ -78,5 +78,13 @@ parent="menu_sf_tool_manage" /> + + diff --git a/sf_tool_management/views/tool_base_views.xml b/sf_tool_management/views/tool_base_views.xml index 46c77b82..4e1a6fc4 100644 --- a/sf_tool_management/views/tool_base_views.xml +++ b/sf_tool_management/views/tool_base_views.xml @@ -766,5 +766,148 @@ {'search_default_no_assemble_status':1} + + + + + 功能刀具拆解 + sf.functional.tool.dismantle + + + + + + + + + + + + + + + + + 功能刀具拆解 + sf.functional.tool.dismantle + +
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + sf.functional.tool.dismantle + + + + + + + + + + + + + 功能刀具拆解 + ir.actions.act_window + sf.functional.tool.dismantle + tree,form,search + + + + + diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py index 979d8efe..be31d7f0 100644 --- a/sf_tool_management/wizard/wizard.py +++ b/sf_tool_management/wizard/wizard.py @@ -243,11 +243,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel): @api.depends('integral_freight_barcode') def _compute_integral_product_id(self): - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.integral_freight_barcode)]) - if location: - self.integral_product_id = location.product_id.id - else: - self.integral_product_id = False + if self.integral_freight_barcode: + location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.integral_freight_barcode)]) + if location: + self.integral_product_id = location.product_id.id + else: + self.integral_product_id = False # ===============刀片型号==================== blade_freight_barcode = fields.Char('刀片货位') @@ -261,11 +262,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel): @api.depends('blade_freight_barcode') def _compute_blade_product_id(self): - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.blade_freight_barcode)]) - if location: - self.blade_product_id = location.product_id.id - else: - self.blade_product_id = False + if self.blade_freight_barcode: + location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.blade_freight_barcode)]) + if location: + self.blade_product_id = location.product_id.id + else: + self.blade_product_id = False # ====================刀杆型号================== bar_freight_barcode = fields.Char('刀杆货位') @@ -279,11 +281,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel): @api.depends('bar_freight_barcode') def _compute_bar_product_id(self): - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.bar_freight_barcode)]) - if location: - self.bar_product_id = location.product_id.id - else: - self.bar_product_id = False + if self.bar_freight_barcode: + location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.bar_freight_barcode)]) + if location: + self.bar_product_id = location.product_id.id + else: + self.bar_product_id = False # ===============刀盘型号=================== pad_freight_barcode = fields.Char('刀盘货位') @@ -297,11 +300,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel): @api.depends('pad_freight_barcode') def _compute_pad_product_id(self): - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.pad_freight_barcode)]) - if location: - self.pad_product_id = location.product_id.id - else: - self.pad_product_id = False + if self.pad_freight_barcode: + location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.pad_freight_barcode)]) + if location: + self.pad_product_id = location.product_id.id + else: + self.pad_product_id = False # ================刀柄型号=============== handle_freight_rfid = fields.Char('刀柄Rfid', compute='_compute_rfid') @@ -335,11 +339,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel): @api.depends('chuck_freight_barcode') def _compute_chuck_product_id(self): - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.chuck_freight_barcode)]) - if location: - self.chuck_product_id = location.product_id.id - else: - self.chuck_product_id = False + if self.chuck_freight_barcode: + location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.chuck_freight_barcode)]) + if location: + self.chuck_product_id = location.product_id.id + else: + self.chuck_product_id = False # ======================================== From 080a3d717535d230365517781391a8355921429e Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Mon, 22 Apr 2024 17:59:48 +0800 Subject: [PATCH 2/4] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E6=89=AB?= =?UTF-8?q?=E7=A0=81=E7=9A=84=E6=89=98=E7=9B=98=E5=B7=B2=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E5=B7=A5=E5=8D=95=E7=9A=84=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=EF=BC=9B2=E3=80=81=E4=BC=98=E5=8C=96=E9=87=87=E8=B4=AD?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=9C=AA=E5=AE=A1=E6=A0=B8=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E9=87=91=E9=A2=9D=E6=95=B0=E6=8D=AE=E4=B8=8D=E8=83=BD=E6=94=B9?= =?UTF-8?q?=E5=8F=98=E7=9A=84bug=EF=BC=9B3=E3=80=81=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=88=80=E5=85=B7=E6=8B=86=E8=A7=A3=E5=8D=95=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E4=B8=8D=E5=90=8C=E6=83=85=E5=86=B5=E6=89=AB?= =?UTF-8?q?=E5=BA=93=E4=BD=8D=E7=A0=81=E5=BD=95=E5=85=A5=E4=BA=94=E7=A7=8D?= =?UTF-8?q?=E7=89=A9=E6=96=99=E7=9A=84=E7=9B=AE=E7=9A=84=E5=BA=93=E4=BD=8D?= =?UTF-8?q?=E7=9A=84=E4=BF=A1=E6=81=AF=EF=BC=9B4=E3=80=81=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=88=80=E5=85=B7=E6=8B=86=E8=A7=A3=E5=8D=95=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=8B=86=E8=A7=A3=E5=90=8E=E7=9A=84Rfid=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=8C=E6=96=B0=E5=A2=9E=E6=8B=86=E8=A7=A3=E5=8D=95?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=AD=97=E6=AE=B5=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=88=80=E5=85=B7=E7=89=A9=E6=96=99=E5=BA=93=E4=BD=8D=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E6=90=9C=E7=B4=A2=E8=BF=87=E6=BB=A4=EF=BC=9B5?= =?UTF-8?q?=E3=80=81=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E6=8B=86=E8=A7=A3?= =?UTF-8?q?=E5=8D=95=E6=96=B0=E5=A2=9E=E7=A1=AE=E8=AE=A4=E6=8B=86=E8=A7=A3?= =?UTF-8?q?=E6=8C=89=E9=92=AE=EF=BC=8C=E5=AE=8C=E6=88=90=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E6=8B=86=E8=A7=A3=E5=90=8E=E7=9A=84=E5=88=80?= =?UTF-8?q?=E5=85=B7=E7=89=A9=E6=96=99=E6=98=AF=E5=90=A6=E6=8A=A5=E5=BA=9F?= =?UTF-8?q?=E3=80=81=E7=A3=A8=E5=89=8A=E6=88=96=E8=80=85=E6=9B=B4=E6=8D=A2?= =?UTF-8?q?=E7=9A=84=E4=B8=8D=E5=90=8C=E6=9D=A1=E4=BB=B6=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E6=8B=86=E8=A7=A3=E5=90=8E=E7=89=A9=E6=96=99=E7=9A=84=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E5=8E=BB=E5=90=91=E7=9A=84=E5=8A=9F=E8=83=BD=E5=8F=8A?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=A7=BB=E5=8A=A8=E5=8E=86=E5=8F=B2=EF=BC=8C?= =?UTF-8?q?=E8=A7=A3=E9=99=A4=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7Rfid?= =?UTF-8?q?=E7=9A=84=E7=BB=91=E5=AE=9A=E5=B9=B6=E6=9B=B4=E6=94=B9=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E7=AD=89=E3=80=826=E3=80=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E7=AE=A1=E7=90=86=E4=B8=8B?= =?UTF-8?q?=E7=9A=84=E8=8F=9C=E5=8D=95=E7=9B=AE=E5=BD=95=E5=B8=83=E5=B1=80?= =?UTF-8?q?=EF=BC=9B7=E3=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 2 +- sf_sale/views/purchase_order_view.xml | 2 +- sf_tool_management/models/base.py | 162 ++++++++++++++++-- sf_tool_management/models/functional_tool.py | 1 + sf_tool_management/views/menu_view.xml | 120 ++++++++----- sf_tool_management/views/tool_base_views.xml | 144 ++++++++++------ .../views/tool_material_search.xml | 7 - 7 files changed, 318 insertions(+), 120 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 9627a0f7..54024fe3 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -988,7 +988,7 @@ class SfWorkOrderBarcodes(models.Model): # [('routing_type', '=', '装夹预调'), ('production_id', '=', self.production_id.id)]) workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)]) if workorder_old: - raise UserError('该托盘已绑定工件,请先解除绑定!!!') + raise UserError('该托盘已绑定【%s】制造订单,请先解除绑定!!!' % workorder_old.production_id.name) if workorder: if workorder.routing_type == '装夹预调': if workorder.state in ['done']: diff --git a/sf_sale/views/purchase_order_view.xml b/sf_sale/views/purchase_order_view.xml index f92658fc..90c9bd4b 100644 --- a/sf_sale/views/purchase_order_view.xml +++ b/sf_sale/views/purchase_order_view.xml @@ -94,7 +94,7 @@ {'readonly': ['&',('state', 'in', ['purchase']),('check_status','in', - ['pending','approved'])]} + ['approved'])]} diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 235935a0..350658a4 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import re + import logging from datetime import timedelta @@ -643,11 +645,35 @@ class FunctionalToolDismantle(models.Model): """ 扫码 """ - tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search([('rfid', '=', barcode)]) - if tool_id: - self.functional_tool_id = tool_id.id + # 对barcode进行校验是否为货位编码 + if not re.match(r'^[A-Za-z0-9]+-[A-Za-z0-9]+-\d{3}-\d{3}$', barcode): + tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search([('rfid', '=', barcode)]) + if tool_id: + self.functional_tool_id = tool_id.id + else: + raise ValidationError('Rfid为【%s】的功能刀具不存在,请重新扫描!' % barcode) else: - pass + location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', barcode)]) + if not location: + raise ValidationError('【%s】该货位不存在,请重新扫码!' % barcode) + else: + # 判断是否有夹头物料 + if not self.chuck_product_id: + # 判断是否有整体式刀具物料 + if self.integral_product_id: + # 判断货位是否为空货位 或者 是存有整体式刀具的货位 + if location.product_id in [False, self.integral_product_id]: + self.integral_freight_id = location.id + else: + raise ValidationError('【%s】该货位已存在【%s】产品,请重新扫码!' % location.barcode, + location.product_id.name) + # 判断是否有刀片物料 + elif self.blade_product_id: + # 判断是否有刀杆物料 + if self.bar_product_id: + pass + else: + pass name = fields.Char('名称', related='functional_tool_id.name') @@ -659,6 +685,7 @@ class FunctionalToolDismantle(models.Model): diameter = fields.Integer(string='刀具直径(mm)', compute='_compute_functional_tool_num', store=True) knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', compute='_compute_functional_tool_num', store=True) rfid = fields.Char('Rfid', compute='_compute_functional_tool_num', store=True) + rfid_dismantle = fields.Char('Rfid(已拆解)', readonly=True) dismantle_cause = fields.Selection( [('寿命到期报废', '寿命到期报废'), ('崩刀报废', '崩刀报废'), ('更换为其他刀具', '更换为其他刀具'), @@ -667,8 +694,10 @@ class FunctionalToolDismantle(models.Model): dismantle_person = fields.Char('拆解人', readonly=True) image = fields.Binary('图片', readonly=True) - scrap_id = fields.Char('报废单号') - grinding_id = fields.Char('磨削单号') + scrap_id = fields.Char('报废单号', readonly=True) + grinding_id = fields.Char('磨削单号', readonly=True) + + state = fields.Selection([('待拆解', '待拆解'), ('已拆解', '已拆解')], default='待拆解') # 刀柄 handle_product_id = fields.Many2one('product.product', string='刀柄', compute='_compute_functional_tool_num', @@ -676,7 +705,7 @@ class FunctionalToolDismantle(models.Model): handle_type_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号', 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') + handle_rfid = fields.Char(string='刀柄Rfid', compute='_compute_functional_tool_num', store=True) scrap_boolean = fields.Boolean(string='刀柄是否报废', default=False) # 整体式 @@ -686,7 +715,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_freight_barcode = fields.Char('整体式刀具目标货位') + integral_freight_id = fields.Many2one('sf.shelf.location', '整体式刀具目标货位', + domain="[('product_id', 'in', (integral_product_id, False))]") # 刀片 blade_product_id = fields.Many2one('product.product', string='刀片', compute='_compute_functional_tool_num', @@ -694,7 +724,8 @@ 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_freight_barcode = fields.Char('刀片目标货位') + blade_freight_id = fields.Many2one('sf.shelf.location', '刀片目标货位', + domain="[('product_id', 'in', (blade_product_id, False))]") # 刀杆 bar_product_id = fields.Many2one('product.product', string='刀杆', compute='_compute_functional_tool_num', @@ -702,7 +733,8 @@ 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_freight_barcode = fields.Char('刀杆目标货位') + bar_freight_id = fields.Many2one('sf.shelf.location', '刀杆目标货位', + domain="[('product_id', 'in', (bar_product_id, False))]") # 刀盘 pad_product_id = fields.Many2one('product.product', string='刀盘', compute='_compute_functional_tool_num', @@ -710,7 +742,8 @@ 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_freight_barcode = fields.Char('刀盘目标货位') + pad_freight_id = fields.Many2one('sf.shelf.location', '刀盘目标货位', + domain="[('product_id', 'in', (pad_product_id, False))]") # 夹头 chuck_product_id = fields.Many2one('product.product', string='夹头', compute='_compute_functional_tool_num', @@ -718,7 +751,8 @@ 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_freight_barcode = fields.Char('夹头目标货位') + chuck_freight_id = fields.Many2one('sf.shelf.location', '夹头目标货位', + domain="[('product_id', 'in', (chuck_product_id, False))]") @api.depends('functional_tool_id') def _compute_functional_tool_num(self): @@ -729,6 +763,7 @@ class FunctionalToolDismantle(models.Model): item.diameter = item.functional_tool_id.functional_tool_diameter item.knife_tip_r_angle = item.functional_tool_id.knife_tip_r_angle 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 @@ -742,6 +777,7 @@ class FunctionalToolDismantle(models.Model): item.diameter = 0 item.knife_tip_r_angle = 0 item.rfid = '' + item.handle_rfid = '' item.handle_product_id = False item.integral_product_id = False @@ -749,3 +785,105 @@ class FunctionalToolDismantle(models.Model): item.bar_product_id = False item.pad_product_id = False item.chuck_product_id = False + + def confirmation_disassembly(self): + logging.info('%s刀具确认拆解' % self.dismantle_cause) + location = self.env['stock.location'].search([('name', '=', '刀具组装位置')]) + location_dest = self.env['stock.location'].search([('name', '=', '刀具房')]) + # =================刀柄是否报废拆解======= + location_dest_scrap = self.env['stock.location'].search([('name', '=', 'Scrap')]) + if self.handle_rfid: + lot = self.env['stock.lot'].sudo().search([('name', '=', self.handle_rfid)]) + 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, '功能刀具拆解', + functional_tool_assembly) + else: + # 刀柄不报废 入库到刀具房 + lot.create_stock_quant(location, location_dest, functional_tool_assembly.id, '功能刀具拆解', + functional_tool_assembly) + # ==============功能刀具报废拆解================ + if self.dismantle_cause in ['寿命到期报废', '崩刀报废']: + # 除刀柄外物料报废 入库到Scrap + if self.integral_freight_id: + self.integral_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + elif self.blade_freight_id: + self.blade_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + if self.bar_freight_id: + self.bar_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + elif self.pad_freight_id: + self.pad_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + if self.chuck_freight_id: + self.chuck_product_id.dismantle_stock_moves(False, location, location_dest_scrap) + # ===========功能刀具磨削拆解============== + elif self.dismantle_cause in ['刀具需磨削']: + location_dest = self.env['stock.location'].search([('name', '=', '磨削房')]) + # 除刀柄外物料拆解 入库到具体库位 + if self.integral_freight_id: + self.integral_product_id.dismantle_stock_moves(False, location, location_dest) + elif self.blade_freight_id: + self.blade_product_id.dismantle_stock_moves(False, location, location_dest) + if self.bar_freight_id: + self.bar_product_id.dismantle_stock_moves(False, location, location_dest) + elif self.pad_freight_id: + self.pad_product_id.dismantle_stock_moves(False, location, location_dest) + if self.chuck_freight_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, + location_dest) + elif self.blade_freight_id: + self.blade_product_id.dismantle_stock_moves(self.blade_freight_id.barcode, location, location_dest) + if self.bar_freight_id: + self.bar_product_id.dismantle_stock_moves(self.bar_freight_id.barcode, location, location_dest) + elif self.pad_freight_id: + self.pad_product_id.dismantle_stock_moves(self.pad_freight_id.barcode, location, location_dest) + if self.chuck_freight_id: + self.chuck_product_id.dismantle_stock_moves(self.chuck_freight_id.barcode, location, location_dest) + # ===============删除功能刀具的Rfid字段的值, 赋值给Rfid(已拆解)字段===== + self.functional_tool_id.write({ + 'rfid_dismantle': self.functional_tool_id.rfid, + 'rfid': '', + 'functional_tool_status': '已拆除' + }) + # 修改拆解单的值 + self.write({ + 'rfid_dismantle': self.rfid, + 'rfid': '', + 'state': '已拆解' + }) + + +class ProductProduct(models.Model): + _inherit = 'product.product' + + def dismantle_stock_moves(self, shelf_location_barcode, location_id, location_dest_id): + # 创建功能刀具拆解单产品库存移动记录 + stock_move_id = self.env['stock.move'].sudo().create({ + 'name': '功能刀具拆解', + 'product_id': self.id, + 'location_id': location_id.id, + 'location_dest_id': location_dest_id.id, + '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 = False + # 创建移动历史记录 + stock_move_line_id = self.env['stock.move.line'].sudo().create({ + 'product_id': self.id, + 'move_id': stock_move_id.id, + 'current_location_id': location.id or False, + 'install_tool_time': fields.Datetime.now(), + 'qty_done': 1.0, + 'state': 'done', + }) + + 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 c37d5317..d4718f34 100644 --- a/sf_tool_management/models/functional_tool.py +++ b/sf_tool_management/models/functional_tool.py @@ -14,6 +14,7 @@ class FunctionalCuttingToolEntity(models.Model): tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', related='functional_tool_name_id.tool_groups_id') code = fields.Char('编码') rfid = fields.Char('Rfid', readonly=True) + rfid_dismantle = fields.Char('Rfid(已拆解)', readonly=True) name = fields.Char('名称') tool_name_id = fields.Many2one('sf.tool.inventory', '功能刀具名称') sf_cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀具型号') diff --git a/sf_tool_management/views/menu_view.xml b/sf_tool_management/views/menu_view.xml index eae7532e..8ddee8eb 100644 --- a/sf_tool_management/views/menu_view.xml +++ b/sf_tool_management/views/menu_view.xml @@ -14,77 +14,111 @@ parent="mrp.menu_mrp_root" sequence="20"/> - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/sf_tool_management/views/tool_base_views.xml b/sf_tool_management/views/tool_base_views.xml index 4e1a6fc4..944decd2 100644 --- a/sf_tool_management/views/tool_base_views.xml +++ b/sf_tool_management/views/tool_base_views.xml @@ -792,11 +792,16 @@ sf.functional.tool.dismantle
+
+

+ options="{'no_create': True}" attrs="{‘readonly': [('state', '=', '已拆解')]}"/>

@@ -807,76 +812,103 @@ - + + + + + + + + + + + - - - - - + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - + - - - - - - + + + + + + + + + + - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + diff --git a/sf_tool_management/views/tool_material_search.xml b/sf_tool_management/views/tool_material_search.xml index ee63ba26..d4772244 100644 --- a/sf_tool_management/views/tool_material_search.xml +++ b/sf_tool_management/views/tool_material_search.xml @@ -94,12 +94,5 @@ sf.tool.material.search tree,form - From 8bc23f5136a4063db6abcedefd8d8ca2f2c0cb8d Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 23 Apr 2024 14:15:45 +0800 Subject: [PATCH 3/4] =?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=E6=8B=86=E8=A7=A3=E5=8D=95=E6=8B=86?= =?UTF-8?q?=E8=A7=A3=E5=8E=9F=E5=9B=A0=E4=B8=BA=E6=9B=B4=E6=8D=A2=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E5=88=80=E5=85=B7=E6=97=B6=E7=9A=84=E6=89=AB=E7=A0=81?= =?UTF-8?q?=E5=BD=95=E5=85=A5=E5=88=80=E5=85=B7=E7=89=A9=E6=96=99=E8=B4=A7?= =?UTF-8?q?=E4=BD=8D=E4=BF=A1=E6=81=AF=E5=8A=9F=E8=83=BD=EF=BC=9B2?= =?UTF-8?q?=E3=80=81=E4=BC=98=E5=8C=96=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7?= =?UTF-8?q?=E6=8B=86=E8=A7=A3=E5=8D=95=E7=A1=AE=E8=AE=A4=E6=8B=86=E8=A7=A3?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E5=88=80=E5=85=B7=E7=89=A9=E6=96=99=E6=8B=86?= =?UTF-8?q?=E8=A7=A3=E6=B5=81=E7=A8=8B=EF=BC=8C=E5=8F=8A=E5=85=B6=E5=88=80?= =?UTF-8?q?=E5=85=B7=E7=89=A9=E6=96=99=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E9=87=8F=E7=BB=9F=E8=AE=A1=E7=AD=89=EF=BC=9B?= =?UTF-8?q?3=E3=80=81=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E6=8B=86?= =?UTF-8?q?=E8=A7=A3=E3=80=81=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E6=B7=BB=E5=8A=A0=E5=8A=A8=E4=BD=9C=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E5=B7=B2=E6=8B=86=E8=A7=A3=E7=8A=B6=E6=80=81=E7=9A=84=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=9B4=E3=80=81=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=88=80=E5=85=B7=E7=BB=84=E8=A3=85=E6=B5=81=E7=A8=8B=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=88=80=E5=85=B7=E7=89=A9=E6=96=99=E8=B4=A7=E4=BD=8D?= =?UTF-8?q?=E6=95=B0=E9=87=8F=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_tool_management/models/base.py | 79 +++++++++++++------ sf_tool_management/models/functional_tool.py | 11 ++- .../models/maintenance_equipment.py | 2 + .../models/tool_material_search.py | 4 +- .../views/functional_tool_views.xml | 10 ++- sf_tool_management/views/tool_base_views.xml | 31 +++++--- sf_tool_management/wizard/wizard.py | 35 ++++---- sf_tool_management/wizard/wizard_view.xml | 2 +- 8 files changed, 114 insertions(+), 60 deletions(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 350658a4..43baaab5 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -647,33 +647,56 @@ class FunctionalToolDismantle(models.Model): """ # 对barcode进行校验是否为货位编码 if not re.match(r'^[A-Za-z0-9]+-[A-Za-z0-9]+-\d{3}-\d{3}$', barcode): - tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search([('rfid', '=', barcode)]) + tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search( + [('rfid', '=', barcode), ('functional_tool_status', '!=', '已拆除')]) if tool_id: self.functional_tool_id = tool_id.id else: raise ValidationError('Rfid为【%s】的功能刀具不存在,请重新扫描!' % barcode) else: - location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', barcode)]) - if not location: - raise ValidationError('【%s】该货位不存在,请重新扫码!' % barcode) - else: - # 判断是否有夹头物料 - if not self.chuck_product_id: - # 判断是否有整体式刀具物料 - if self.integral_product_id: - # 判断货位是否为空货位 或者 是存有整体式刀具的货位 - if location.product_id in [False, self.integral_product_id]: - self.integral_freight_id = location.id - else: - raise ValidationError('【%s】该货位已存在【%s】产品,请重新扫码!' % location.barcode, - location.product_id.name) - # 判断是否有刀片物料 - elif self.blade_product_id: - # 判断是否有刀杆物料 - if self.bar_product_id: - pass + if self.dismantle_cause == '更换为其他刀具': + location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', barcode)]) + if not location: + raise ValidationError('【%s】该货位不存在,请重新扫码!' % barcode) else: - pass + if not location.product_id: + # 判断功能刀具存在哪些刀具物料需要录入库位 + if self.chuck_product_id: # 夹头 + if not self.chuck_freight_id: + self.chuck_freight_id = location.id + return True + if self.integral_product_id: # 整体式刀具 + if not self.integral_freight_id: + self.integral_freight_id = location.id + return True + elif self.blade_product_id: # 刀片 + if not self.blade_freight_id: + self.blade_freight_id = location.id + return True + if self.bar_product_id: # 刀杆 + if not self.bar_freight_id: + self.bar_freight_id = location.id + return True + elif self.pad_product_id: # 刀盘 + if not self.pad_freight_id: + self.pad_freight_id = location.id + return True + else: + # 判断货位存放的是那个刀具物料产品 + if self.integral_product_id == location.product_id: # 整体式刀具 + self.integral_freight_id = location.id + elif self.blade_product_id == location.product_id: # 刀片 + self.blade_freight_id = location.id + elif self.bar_product_id == location.product_id: # 刀杆 + self.bar_freight_id = location.id + elif self.pad_product_id == location.product_id: # 刀盘 + self.pad_freight_id = location.id + elif self.chuck_product_id == location.product_id: # 夹头 + self.chuck_freight_id = location.id + elif self.dismantle_cause in ['寿命到期报废', '崩刀报废']: + raise ValidationError('该功能刀具因为%s拆解,无需录入库位' % self.dismantle_cause) + else: + raise ValidationError('该功能刀具因为%s拆解,无需录入库位' % self.dismantle_cause) name = fields.Char('名称', related='functional_tool_id.name') @@ -698,6 +721,7 @@ class FunctionalToolDismantle(models.Model): grinding_id = fields.Char('磨削单号', readonly=True) state = fields.Selection([('待拆解', '待拆解'), ('已拆解', '已拆解')], default='待拆解') + active = fields.Boolean('有效', default=True) # 刀柄 handle_product_id = fields.Many2one('product.product', string='刀柄', compute='_compute_functional_tool_num', @@ -787,22 +811,24 @@ class FunctionalToolDismantle(models.Model): item.chuck_product_id = False def confirmation_disassembly(self): - logging.info('%s刀具确认拆解' % self.dismantle_cause) + logging.info('%s刀具确认开始拆解' % self.dismantle_cause) + 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', '=', '刀具组装位置')]) location_dest = self.env['stock.location'].search([('name', '=', '刀具房')]) # =================刀柄是否报废拆解======= location_dest_scrap = self.env['stock.location'].search([('name', '=', 'Scrap')]) if self.handle_rfid: - lot = self.env['stock.lot'].sudo().search([('name', '=', self.handle_rfid)]) + lot = self.env['stock.lot'].sudo().search([('rfid', '=', self.handle_rfid)]) 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, '功能刀具拆解', - functional_tool_assembly) + functional_tool_assembly, functional_tool_assembly.tool_groups_id) else: # 刀柄不报废 入库到刀具房 lot.create_stock_quant(location, location_dest, functional_tool_assembly.id, '功能刀具拆解', - functional_tool_assembly) + functional_tool_assembly, functional_tool_assembly.tool_groups_id) # ==============功能刀具报废拆解================ if self.dismantle_cause in ['寿命到期报废', '崩刀报废']: # 除刀柄外物料报废 入库到Scrap @@ -853,9 +879,12 @@ class FunctionalToolDismantle(models.Model): # 修改拆解单的值 self.write({ 'rfid_dismantle': self.rfid, + 'dismantle_data': fields.Datetime.now(), + 'dismantle_person': self.env.user.name, 'rfid': '', 'state': '已拆解' }) + logging.info('刀具拆解成功!') class ProductProduct(models.Model): diff --git a/sf_tool_management/models/functional_tool.py b/sf_tool_management/models/functional_tool.py index d4718f34..eae00080 100644 --- a/sf_tool_management/models/functional_tool.py +++ b/sf_tool_management/models/functional_tool.py @@ -45,7 +45,7 @@ class FunctionalCuttingToolEntity(models.Model): active = fields.Boolean(string='已归档', default=True) - @api.depends('barcode_id.quant_ids') + @api.depends('barcode_id.quant_ids', 'functional_tool_status') def _compute_current_location_id(self): for record in self: if record.barcode_id.quant_ids: @@ -61,6 +61,12 @@ class FunctionalCuttingToolEntity(models.Model): else: record.current_location_id = False record.current_location = False + if record.functional_tool_status == '已拆除': + record.current_location_id = False + record.current_location = False + record.tool_room_num = 0 + record.line_edge_knife_library_num = 0 + record.machine_knife_library_num = 0 def get_location_num(self): """ @@ -185,7 +191,8 @@ class FunctionalCuttingToolEntity(models.Model): stock_location_id = self.env['stock.location'].search([('name', '=', '制造前')]) # 创建功能刀具该批次/序列号 库存移动和移动历史 self.barcode_id.create_stock_quant(location_inventory_id, stock_location_id, - self.functional_tool_name_id.id, '机床装刀', self.functional_tool_name_id) + self.functional_tool_name_id.id, '机床装刀', self.functional_tool_name_id, + self.functional_tool_name_id.tool_groups_id) # ==========刀具组接口========== # def _register_functional_tool_groups(self, obj): diff --git a/sf_tool_management/models/maintenance_equipment.py b/sf_tool_management/models/maintenance_equipment.py index d39dc685..4452f768 100644 --- a/sf_tool_management/models/maintenance_equipment.py +++ b/sf_tool_management/models/maintenance_equipment.py @@ -112,6 +112,8 @@ class StockLot(models.Model): record.tool_material_status = '可用' elif record.quant_ids[-1].location_id.name == '刀具组装位置': record.tool_material_status = '在用' + elif record.quant_ids[-1].location_id.name == 'Scrap': + record.tool_material_status = '报废' else: record.tool_material_status = '未入库' if record.tool_material_search_id: diff --git a/sf_tool_management/models/tool_material_search.py b/sf_tool_management/models/tool_material_search.py index bfb8d64b..ee60c048 100644 --- a/sf_tool_management/models/tool_material_search.py +++ b/sf_tool_management/models/tool_material_search.py @@ -39,9 +39,7 @@ class ToolMaterial(models.Model): usable_num += quant.quantity elif location == '刀具组装位置': have_been_used_num += quant.quantity - elif location == '进货': - pass - elif location != 'Vendors': + elif location == 'Scrap': scrap_num += quant.quantity record.usable_num = usable_num record.have_been_used_num = have_been_used_num diff --git a/sf_tool_management/views/functional_tool_views.xml b/sf_tool_management/views/functional_tool_views.xml index 82fbd8bc..53e050d9 100644 --- a/sf_tool_management/views/functional_tool_views.xml +++ b/sf_tool_management/views/functional_tool_views.xml @@ -85,7 +85,10 @@ - + + @@ -202,6 +205,9 @@ + + + @@ -218,6 +224,8 @@ sf.functional.cutting.tool.entity tree,form,search + + {'search_default_no_state_removed':1} diff --git a/sf_tool_management/views/tool_base_views.xml b/sf_tool_management/views/tool_base_views.xml index 944decd2..1db89ddb 100644 --- a/sf_tool_management/views/tool_base_views.xml +++ b/sf_tool_management/views/tool_base_views.xml @@ -783,6 +783,7 @@ + @@ -794,20 +795,21 @@

+ options="{'no_create': True}" attrs="{'readonly': [('state', '=', '已拆解')]}"/>

- + + @@ -820,7 +822,8 @@ - + + attrs="{'invisible': [('dismantle_cause', 'not in', ['寿命到期报废','崩刀报废'])], 'readonly': [('state', '=', '已拆解')]}"/> @@ -854,7 +857,7 @@ + attrs="{'invisible': [('dismantle_cause', 'not in', ['更换为其他刀具'])], 'readonly': [('state', '=', '已拆解')]}"/> @@ -868,7 +871,7 @@ + attrs="{'invisible': [('dismantle_cause', 'not in', ['更换为其他刀具'])], 'readonly': [('state', '=', '已拆解')]}"/> @@ -883,7 +886,7 @@ + attrs="{'invisible': [('dismantle_cause', 'not in', ['更换为其他刀具'])], 'readonly': [('state', '=', '已拆解')]}"/> @@ -895,7 +898,7 @@ + attrs="{'invisible': [('dismantle_cause', 'not in', ['更换为其他刀具'])], 'readonly': [('state', '=', '已拆解')]}"/> @@ -907,7 +910,7 @@ + attrs="{'invisible': [('dismantle_cause', 'not in', ['更换为其他刀具'])], 'readonly': [('state', '=', '已拆解')]}"/>
@@ -923,6 +926,10 @@ + + + + @@ -936,8 +943,8 @@ ir.actions.act_window sf.functional.tool.dismantle tree,form,search - - + + {'search_default_no_dismantle_state':1} diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py index be31d7f0..a97e7274 100644 --- a/sf_tool_management/wizard/wizard.py +++ b/sf_tool_management/wizard/wizard.py @@ -403,7 +403,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel): after_name_id = fields.Many2one('sf.tool.inventory', string='功能刀具名称', required=True) barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号') rfid = fields.Char('Rfid', compute='_compute_rfid') - tool_code = fields.Char(string='功能刀具编码', compute='_compute_tool_code') + code = fields.Char(string='功能刀具编码', compute='_compute_code') after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', compute='_compute_name', store=True) after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='组装后功能刀具类型') @@ -448,7 +448,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel): @api.depends('after_assembly_functional_tool_type_id', 'integral_specification_id', 'bar_specification_id', 'pad_specification_id', 'handle_specification_id', 'after_assembly_tool_loading_length') - def _compute_tool_code(self): + def _compute_code(self): for obj in self: str_1 = 'GNDJ-%s' % obj.after_assembly_functional_tool_type_id.code str_2 = '' @@ -467,11 +467,11 @@ class FunctionalToolAssemblyOrder(models.TransientModel): obj.pad_specification_id.cut_depth_max, obj.handle_specification_id.total_length, ) else: - obj.tool_code = str_2 + obj.code = str_2 return True - obj.tool_code = str_2 + str(self._get_code(str_2)) + obj.code = str_2 + str(self._get_code(str_2)) else: - obj.tool_code = str_2 + obj.code = str_2 def _get_code(self, str_2): functional_tool_assembly = self.env['sf.functional.cutting.tool.entity'].sudo().search( @@ -618,7 +618,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel): def get_desc_1(self, stock_lot): return { 'barcode_id': stock_lot.id, - 'code': self.tool_code, + 'code': self.code, 'rfid': self.rfid, 'tool_groups_id': self.after_tool_groups_id.id, 'integral_freight_barcode': self.integral_freight_barcode, @@ -655,7 +655,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel): def get_desc_2(self, stock_lot, functional_tool_assembly_id): return { 'barcode_id': stock_lot.id, - 'code': self.tool_code, + 'code': self.code, 'name': self.after_name_id.name, 'tool_name_id': self.after_name_id.id, 'rfid': self.rfid, @@ -718,7 +718,7 @@ class StockPicking(models.Model): 'functional_tool_type_id': obj.functional_tool_type_id.id, 'diameter': obj.after_assembly_functional_tool_diameter, 'knife_tip_r_angle': obj.after_assembly_knife_tip_r_angle, - 'code': obj.tool_code, + 'code': obj.code, 'rfid': obj.rfid, 'functional_tool_name': obj.after_assembly_functional_tool_name, 'tool_groups_id': obj.after_tool_groups_id.id @@ -762,7 +762,7 @@ class ProductProduct(models.Model): stock_location_id = self.env['stock.location'].search([('name', '=', '组装后')]) # 创建功能刀具该批次/序列号 库存移动和移动历史 stock_lot.create_stock_quant(location_inventory_id, stock_location_id, functional_tool_assembly.id, - '功能刀具组装', obj) + '功能刀具组装', obj, obj.after_tool_groups_id) return stock_lot @@ -796,7 +796,7 @@ class ProductProduct(models.Model): location_inventory_id = tool_material.quant_ids.location_id[-1] stock_location_id = self.env['stock.location'].search([('name', '=', '刀具组装位置')]) # 创建功能刀具该批次/序列号 库存移动和移动历史 - tool_material.create_stock_quant(location_inventory_id, stock_location_id, None, '功能刀具组装', False) + tool_material.create_stock_quant(location_inventory_id, stock_location_id, None, '功能刀具组装', False, False) def material_stock_moves(self, shelf_location_barcode): # 创建库存移动记录 @@ -819,16 +819,19 @@ class ProductProduct(models.Model): 'qty_done': 1.0, 'state': 'done', }) - - location.product_num = location.product_num - 1 - + if location.product_num > 0: + location.product_num = location.product_num - 1 + else: + raise ValidationError( + '【%s】货位的【%s】产品库存数量为零,请采购入库后再重新组装!' % (location.barcode, location.product_id.name)) return stock_move_id, stock_move_line_id class StockLot(models.Model): _inherit = 'stock.lot' - def create_stock_quant(self, location_inventory_id, stock_location_id, functional_tool_assembly_id, name, obj): + def create_stock_quant(self, location_inventory_id, stock_location_id, functional_tool_assembly_id, name, obj, + tool_groups_id): """ 对功能刀具组装过程的功能刀具和刀具物料进行库存移动,以及创建移动历史 """ @@ -855,10 +858,10 @@ class StockLot(models.Model): '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.tool_code, + '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 obj else obj.after_tool_groups_id.id + 'tool_groups_id': False if not tool_groups_id else tool_groups_id.id }) return stock_move_id, stock_move_line_id diff --git a/sf_tool_management/wizard/wizard_view.xml b/sf_tool_management/wizard/wizard_view.xml index 0eb2a77f..636f94f7 100644 --- a/sf_tool_management/wizard/wizard_view.xml +++ b/sf_tool_management/wizard/wizard_view.xml @@ -334,7 +334,7 @@ - + From 1fa5ebd80a7f1c6331763696c30c58dbe7147ca2 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 23 Apr 2024 14:19:55 +0800 Subject: [PATCH 4/4] 1 --- sf_manufacturing/controllers/controllers.py | 2 +- sf_mrs_connect/controllers/controllers.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index bbd9cac9..28f0702c 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -467,7 +467,7 @@ class Manufacturing_Connect(http.Controller): logging.info('DeviceId:%s' % ret['DeviceId']) workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( [('feeder_station_start_id.name', '=', ret['DeviceId']), - ('status', '=', '已配送'), ('type', '=', '上产线')], order='id asc') + ('status', '=', '已配送'), ('type', '=', '下产线')], order='id asc') if workpiece_delivery: for wd in workpiece_delivery: logging.info('wd.production_id:%s' % wd.production_id.name) diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index 6efc4b82..44a65200 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -29,8 +29,8 @@ class Sf_Mrs_Connect(http.Controller): request.env.ref("base.user_admin")).search([('name', '=', ret['production_order_no'])]) logging.info('制造订单号:%s' % cnc_production.name) if cnc_production: - if ret['glb_file']: - cnc_production.glb_file = base64.b64encode(ret['glb_file']) + # if ret['glb_file']: + # cnc_production.glb_file = base64.b64encode(ret['glb_file']) # 拉取所有加工面的程序文件 # i = 1