From 3404cccdc8e0e7dde762a77988e14b675658d407 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 16 Jul 2024 15:33:27 +0800 Subject: [PATCH 01/12] =?UTF-8?q?1=E3=80=81=E8=B4=A7=E6=9E=B6=E3=80=81?= =?UTF-8?q?=E8=B4=A7=E4=BD=8D=E6=B7=BB=E5=8A=A0=E5=BE=AA=E7=8E=AF=E8=B4=A7?= =?UTF-8?q?=E4=BD=8D=E6=A0=87=E7=AD=BE=EF=BC=9B2=E3=80=81=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=88=80=E5=85=B7=E6=8B=86=E8=A7=A3=E9=80=89=E5=8F=96?= =?UTF-8?q?=E6=B3=95=E4=BA=BA=E8=B4=A7=E4=BD=8D=E6=B7=BB=E5=8A=A0=E5=8F=AA?= =?UTF-8?q?=E8=83=BD=E9=80=89=E6=8B=A9=E5=BE=AA=E7=8E=AF=E8=B4=A7=E4=BD=8D?= =?UTF-8?q?=E7=9A=84=E8=BF=87=E6=BB=A4=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 10 +++++----- sf_warehouse/models/model.py | 2 ++ sf_warehouse/views/shelf_location.xml | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 182141cf..0fb31704 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -803,7 +803,7 @@ class FunctionalToolDismantle(models.Model): integral_lot_id = fields.Many2one('stock.lot', string='整体式刀具批次', compute='_compute_functional_tool_num', store=True) integral_freight_id = fields.Many2one('sf.shelf.location', '整体式刀具目标货位', - domain="[('product_id', 'in', (integral_product_id, False))]") + domain="[('product_id', 'in', (integral_product_id, False)),('rotative_Boolean', '=', True)]") # 刀片 blade_product_id = fields.Many2one('product.product', string='刀片', compute='_compute_functional_tool_num', @@ -813,7 +813,7 @@ class FunctionalToolDismantle(models.Model): blade_brand_id = fields.Many2one('sf.machine.brand', string='刀片品牌', related='blade_product_id.brand_id') blade_lot_id = fields.Many2one('stock.lot', string='刀片批次', compute='_compute_functional_tool_num', store=True) blade_freight_id = fields.Many2one('sf.shelf.location', '刀片目标货位', - domain="[('product_id', 'in', (blade_product_id, False))]") + domain="[('product_id', 'in', (blade_product_id, False)),('rotative_Boolean', '=', True)]") # 刀杆 bar_product_id = fields.Many2one('product.product', string='刀杆', compute='_compute_functional_tool_num', @@ -823,7 +823,7 @@ class FunctionalToolDismantle(models.Model): bar_brand_id = fields.Many2one('sf.machine.brand', string='刀杆品牌', related='bar_product_id.brand_id') bar_lot_id = fields.Many2one('stock.lot', string='刀杆批次', compute='_compute_functional_tool_num', store=True) bar_freight_id = fields.Many2one('sf.shelf.location', '刀杆目标货位', - domain="[('product_id', 'in', (bar_product_id, False))]") + domain="[('product_id', 'in', (bar_product_id, False)),('rotative_Boolean', '=', True)]") # 刀盘 pad_product_id = fields.Many2one('product.product', string='刀盘', compute='_compute_functional_tool_num', @@ -833,7 +833,7 @@ class FunctionalToolDismantle(models.Model): pad_brand_id = fields.Many2one('sf.machine.brand', string='刀盘品牌', related='pad_product_id.brand_id') pad_lot_id = fields.Many2one('stock.lot', string='刀盘批次', compute='_compute_functional_tool_num', store=True) pad_freight_id = fields.Many2one('sf.shelf.location', '刀盘目标货位', - domain="[('product_id', 'in', (pad_product_id, False))]") + domain="[('product_id', 'in', (pad_product_id, False)),('rotative_Boolean', '=', True)]") # 夹头 chuck_product_id = fields.Many2one('product.product', string='夹头', compute='_compute_functional_tool_num', @@ -843,7 +843,7 @@ class FunctionalToolDismantle(models.Model): chuck_brand_id = fields.Many2one('sf.machine.brand', string='夹头品牌', related='chuck_product_id.brand_id') chuck_lot_id = fields.Many2one('stock.lot', string='夹头批次', compute='_compute_functional_tool_num', store=True) chuck_freight_id = fields.Many2one('sf.shelf.location', '夹头目标货位', - domain="[('product_id', 'in', (chuck_product_id, False))]") + domain="[('product_id', 'in', (chuck_product_id, False)),('rotative_Boolean', '=', True)]") @api.onchange('functional_tool_id') def _onchange_freight(self): diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py index ee212b2a..770d2672 100644 --- a/sf_warehouse/models/model.py +++ b/sf_warehouse/models/model.py @@ -254,6 +254,7 @@ class SfShelf(models.Model): shelf_height = fields.Float(string='货架高度(m)') shelf_layer = fields.Integer(string='货架层数') layer_capacity = fields.Integer(string='层数容量') + shelf_rotative_Boolean = fields.Boolean('循环货架', default=False) # 是否有货位 is_there_area = fields.Boolean(string='是否有货位', compute='_compute_is_there_area', default=False, store=True) @@ -361,6 +362,7 @@ class ShelfLocation(models.Model): name = fields.Char('货位名称', required=True, size=20) barcode = fields.Char('货位编码', copy=False, size=50) + rotative_Boolean = fields.Boolean('循环货位', related='shelf_id.shelf_rotative_Boolean', store=True) qr_code = fields.Binary(string='二维码', compute='_compute_location_qr_code', store=True) # 货架 diff --git a/sf_warehouse/views/shelf_location.xml b/sf_warehouse/views/shelf_location.xml index 418f7d5c..747c25a2 100644 --- a/sf_warehouse/views/shelf_location.xml +++ b/sf_warehouse/views/shelf_location.xml @@ -23,6 +23,7 @@ + @@ -169,6 +170,7 @@ + From 9655281b671b83a2d17f08f3efc4a16620ab9e2a Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Thu, 25 Jul 2024 15:21:36 +0800 Subject: [PATCH 02/12] =?UTF-8?q?1=E3=80=81=E8=A7=A3=E5=86=B3=20=E7=BC=BA?= =?UTF-8?q?=E5=88=80=E7=8A=B6=E6=80=81=E7=AC=AC=E4=B8=80=E5=BC=A0=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E7=8A=B6=E6=80=81=E4=B8=8D=E5=AF=B9=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 520af4f4..dc172a46 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -820,6 +820,10 @@ class ResMrpWorkOrder(models.Model): # else: # if workorder.state not in ['cancel', 'rework']: # workorder.state = 'rework' + if workorder.production_id.state == 'pending_cam': + if workorder.routing_type == '装夹预调' and workorder.state in ['ready', 'waiting']: + if workorder.production_id.tool_state in ['1', '2']: + workorder.state = 'waiting' # elif workorder.routing_type == 'CNC加工' and workorder.state not in ['done', 'cancel', 'progress', # 'rework']: # per_work = self.env['mrp.workorder'].search( @@ -870,8 +874,12 @@ class ResMrpWorkOrder(models.Model): raise UserError(_('该制造订单还未下发CNC程序,请稍后再试')) else: if self.production_id.tool_state in ['1', '2']: + if self.production_id.tool_state == '1': + state = '缺刀' + else: + state = '无效刀' raise UserError( - f'制造订单【{self.production_id.name}】功能刀具状态为【{self.production_id.tool_state}】!') + f'制造订单【{self.production_id.name}】功能刀具状态为【{state}】!') if self.routing_type == '解除装夹': ''' 记录开始时间 From 9eddfe36d6f48326e75942ab8a72149670a54407 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 25 Jul 2024 15:22:48 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=94=E5=B7=A5-?= =?UTF-8?q?=E5=B7=A5=E4=BB=B6=E9=85=8D=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/controllers/controllers.py | 11 ++++++++--- sf_manufacturing/models/mrp_production.py | 3 ++- sf_manufacturing/models/mrp_workorder.py | 3 ++- sf_manufacturing/views/mrp_workorder_view.xml | 9 ++++++--- sf_manufacturing/wizard/rework_wizard.py | 8 +++++++- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index 005e3717..f5a55db2 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -486,7 +486,9 @@ class Manufacturing_Connect(http.Controller): workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( [ ('rfid_code', '=', rfid_code), ('type', '=', '上产线'), - ('production_id', '=', order.production_id.id)]) + ('production_id', '=', order.production_id.id), + ('workorder_id', '=', order.id), + ('workorder_state', '=', 'done')]) if workpiece_delivery.status == '待下发': workpiece_delivery.write({'is_manual_work': True}) else: @@ -548,8 +550,11 @@ class Manufacturing_Connect(http.Controller): workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( [ ('rfid_code', '=', rfid_code), ('type', '=', '下产线'), - ('production_id', '=', order.production_id.id)]) - delivery_Arr.append(workpiece_delivery.id) + ('production_id', '=', order.production_id.id), + ('workorder_id', '=', order.id), + ('workorder_state', '=', 'done')]) + if workpiece_delivery: + delivery_Arr.append(workpiece_delivery.id) else: res = {'Succeed': False, 'ErrorCode': 204, 'Error': 'DeviceId为%s没有对应的已配送工件数据' % ret['DeviceId']} diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index ef470678..65c3ebec 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -734,7 +734,7 @@ class MrpProduction(models.Model): for production in self: logging.info('qty_produced:%s' % production.qty_produced) - if production.qty_produced == '0.0': + if production.qty_produced == 0.0: production.qty_produced = 1.0 production.write({ 'date_finished': fields.Datetime.now(), @@ -897,6 +897,7 @@ class MrpProduction(models.Model): result), 'cmm_ids': panel_workorder.cmm_ids.sudo()._json_cmm_program(processing_panel, result), 'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())}) + logging.info('len(cnc_worksheet):%s' % len(panel_workorder.cnc_worksheet)) pre_workorder = production.workorder_ids.filtered(lambda ap: ap.routing_type == '装夹预调' and ap.processing_panel == processing_panel and ap.state not in ( 'rework', 'done')) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 8781755d..a2745150 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1404,7 +1404,8 @@ class WorkPieceDelivery(models.Model): [('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型') delivery_duration = fields.Float('配送时长', compute='_compute_delivery_duration') status = fields.Selection( - [('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态', default='待下发', + [('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送'), ('已取消', '已取消')], string='状态', + default='待下发', tracking=True) is_cnc_program_down = fields.Boolean('程序是否下发', default=False, tracking=True) is_manual_work = fields.Boolean('人工操作', default=False) diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 0f5a656e..805dcb1f 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -475,7 +475,8 @@ + decoration-danger="status == '待配送'" + decoration-info="status== '已取消'"/> @@ -635,7 +636,9 @@ + decoration-danger="status == '待配送'" + decoration-info="status == '已取消'" + /> @@ -731,7 +734,7 @@ tree,form - [('type','in',['上产线','下产线']),('workorder_state','=','done'),('is_manual_work','=',false)] + [('type','in',['上产线','下产线']),('workorder_state','in',['done','rework']),('is_manual_work','=',false)] diff --git a/sf_manufacturing/wizard/rework_wizard.py b/sf_manufacturing/wizard/rework_wizard.py index c50e267d..f15f85d1 100644 --- a/sf_manufacturing/wizard/rework_wizard.py +++ b/sf_manufacturing/wizard/rework_wizard.py @@ -69,6 +69,12 @@ class ReworkWizard(models.TransientModel): lambda ap: ap.processing_panel == panel.name and ap.state != 'rework') if panel_workorder: panel_workorder.write({'state': 'rework'}) + panel_workorder.filtered( + lambda wo: wo.routing_type == '装夹预调').workpiece_delivery_ids.filtered( + lambda wd: wd.status == '待下发').write({'status': '已取消'}) + # workpiece = self.env['sf.workpiece.delivery'].search([('status', '=', '待下发'), ( + # 'workorder_id', '=', + # panel_workorder.filtered(lambda wd: wd.routing_type == '装夹预调').id)]) product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search( [('product_model_type_id', '=', self.production_id.product_id.product_model_type_id.id)], order='sequence asc' @@ -137,7 +143,7 @@ class ReworkWizard(models.TransientModel): ret), 'cmm_ids': new_cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel.name, ret), - 'cnc_worksheet': new_cnc_workorder.cnc_worksheet}) + 'cnc_worksheet': cnc_rework.cnc_worksheet}) new_pre_workorder = self.production_id.workorder_ids.filtered(lambda p: p.routing_type == '装夹预调' and p.processing_panel == panel.name and p.state not in ( 'rework', 'done')) From 60b77e09d6590a9886167d845c5e2d2feb5a9fbe Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 25 Jul 2024 15:40:44 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=A5=E4=BB=B6?= =?UTF-8?q?=E9=85=8D=E9=80=81=E7=9B=AE=E7=9A=84=E7=94=9F=E4=BA=A7=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index a2745150..ef1f6b6f 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -567,12 +567,16 @@ class ResMrpWorkOrder(models.Model): up_route = self.env['sf.agv.task.route'].search([('route_type', '=', '上产线')], limit=1, order='id asc') down_route = self.env['sf.agv.task.route'].search([('route_type', '=', '下产线')], limit=1, order='id asc') return [ - [0, '', {'production_id': production.id, 'type': '上产线', 'route_id': up_route.id, - 'feeder_station_start_id': up_route.start_site_id.id, - 'feeder_station_destination_id': up_route.end_site_id.id}], - [0, '', {'production_id': production.id, 'type': '下产线', 'route_id': down_route.id, - 'feeder_station_start_id': down_route.start_site_id.id, - 'feeder_station_destination_id': down_route.end_site_id.id}]] + [0, '', + {'production_id': production.id, 'production_line_id': production.production_line_id.id, 'type': '上产线', + 'route_id': up_route.id, + 'feeder_station_start_id': up_route.start_site_id.id, + 'feeder_station_destination_id': up_route.end_site_id.id}], + [0, '', + {'production_id': production.id, 'production_line_id': production.production_line_id.id, 'type': '下产线', + 'route_id': down_route.id, + 'feeder_station_start_id': down_route.start_site_id.id, + 'feeder_station_destination_id': down_route.end_site_id.id}]] # 拼接工单对象属性值(表面工艺) def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id): From 258e24eb057a337717a61ea1800074e5219e4736 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 25 Jul 2024 17:30:33 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=94=E5=B7=A5bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 16 +++++++++------- sf_manufacturing/models/product_template.py | 4 ++-- sf_sale/models/quick_easy_order.py | 4 ++-- sf_sale/models/quick_easy_order_old.py | 4 ++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index e148c581..fce19e16 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -761,6 +761,10 @@ class ResMrpWorkOrder(models.Model): [('production_id', '=', workorder.production_id.id), ('processing_panel', '=', workorder.processing_panel), ('routing_type', '=', 'CNC加工'), ('state', 'in', ['pending'])]) + unclamp_workorder = self.env['mrp.workorder'].search( + [('production_id', '=', workorder.production_id.id), + ('sequence', '=', workorder.sequence - 1), + ('state', 'in', ['done'])]) if workorder.state not in ['cancel', 'progress', 'rework']: if workorder.production_id.state == 'rework': logging.info('len(re_work):%s' % len(re_work)) @@ -819,13 +823,12 @@ class ResMrpWorkOrder(models.Model): workorder.is_rework is False and workorder.state not in [ 'done', 'rework', 'cancel']: - if (re_work or cnc_workorder) and workorder.production_id.is_rework is False: - workorder.state = 'ready' + if workorder.production_id.is_rework is False: + if re_work or cnc_workorder or unclamp_workorder: + workorder.state = 'ready' + # if (re_work or cnc_workorder) and workorder.production_id.is_rework is False: + # workorder.state = 'ready' if workorder.routing_type == '表面工艺' and workorder.state not in ['done', 'progress']: - unclamp_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', workorder.production_id.id), - ('sequence', '=', workorder.sequence - 1), - ('state', 'in', ['done'])]) if unclamp_workorder: workorder.state = 'ready' # else: @@ -835,7 +838,6 @@ class ResMrpWorkOrder(models.Model): if workorder.routing_type == '装夹预调' and workorder.state in ['ready', 'waiting']: if workorder.production_id.tool_state in ['1', '2']: workorder.state = 'waiting' - logging.info('工序:%s' % workorder.sequence) logging.info('工单最终状态:%s' % workorder.state) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 4d05de81..f292d694 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -7,8 +7,8 @@ import os from odoo import models, fields, api, _ from odoo.exceptions import ValidationError from odoo.modules import get_resource_path -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file class ResProductMo(models.Model): diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index e3bf3002..11acc06f 100644 --- a/sf_sale/models/quick_easy_order.py +++ b/sf_sale/models/quick_easy_order.py @@ -8,8 +8,8 @@ from datetime import datetime import requests from odoo import http from odoo.http import request -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file from odoo import models, fields, api from odoo.modules import get_resource_path from odoo.exceptions import ValidationError, UserError diff --git a/sf_sale/models/quick_easy_order_old.py b/sf_sale/models/quick_easy_order_old.py index 3ae65db3..92f6cda2 100644 --- a/sf_sale/models/quick_easy_order_old.py +++ b/sf_sale/models/quick_easy_order_old.py @@ -6,8 +6,8 @@ import os from datetime import datetime from stl import mesh # from OCC.Core.GProp import GProp_GProps -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file from odoo.addons.sf_base.commons.common import Common from odoo import models, fields, api from odoo.modules import get_resource_path From 8686d93651b34ab43cd5ba801e5a2dbed92946e8 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 26 Jul 2024 09:43:28 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E8=BF=98=E5=8E=9F=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 4 ++-- sf_sale/models/quick_easy_order.py | 4 ++-- sf_sale/models/quick_easy_order_old.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index f292d694..4d05de81 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -7,8 +7,8 @@ import os from odoo import models, fields, api, _ from odoo.exceptions import ValidationError from odoo.modules import get_resource_path -# from OCC.Extend.DataExchange import read_step_file -# from OCC.Extend.DataExchange import write_stl_file +from OCC.Extend.DataExchange import read_step_file +from OCC.Extend.DataExchange import write_stl_file class ResProductMo(models.Model): diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index 11acc06f..e3bf3002 100644 --- a/sf_sale/models/quick_easy_order.py +++ b/sf_sale/models/quick_easy_order.py @@ -8,8 +8,8 @@ from datetime import datetime import requests from odoo import http from odoo.http import request -# from OCC.Extend.DataExchange import read_step_file -# from OCC.Extend.DataExchange import write_stl_file +from OCC.Extend.DataExchange import read_step_file +from OCC.Extend.DataExchange import write_stl_file from odoo import models, fields, api from odoo.modules import get_resource_path from odoo.exceptions import ValidationError, UserError diff --git a/sf_sale/models/quick_easy_order_old.py b/sf_sale/models/quick_easy_order_old.py index 92f6cda2..3ae65db3 100644 --- a/sf_sale/models/quick_easy_order_old.py +++ b/sf_sale/models/quick_easy_order_old.py @@ -6,8 +6,8 @@ import os from datetime import datetime from stl import mesh # from OCC.Core.GProp import GProp_GProps -# from OCC.Extend.DataExchange import read_step_file -# from OCC.Extend.DataExchange import write_stl_file +from OCC.Extend.DataExchange import read_step_file +from OCC.Extend.DataExchange import write_stl_file from odoo.addons.sf_base.commons.common import Common from odoo import models, fields, api from odoo.modules import get_resource_path From de8bebc1f90798319675e7249a254e51ec647b8e Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Fri, 26 Jul 2024 10:57:11 +0800 Subject: [PATCH 07/12] =?UTF-8?q?1=E3=80=81=E6=B7=BB=E5=8A=A0=E5=88=B6?= =?UTF-8?q?=E9=80=A0=E8=AE=A2=E5=8D=95=E7=9A=84=E5=88=80=E5=85=B7=E5=A4=87?= =?UTF-8?q?=E6=B3=A8=E5=AD=97=E6=AE=B5=E8=87=AA=E5=8A=A8=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=8F=8A=E6=96=B9=E6=B3=95=EF=BC=9B2?= =?UTF-8?q?=E3=80=81=E4=BC=98=E5=8C=96=E5=B7=A5=E5=8D=95=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=AE=A1=E7=AE=97=E6=96=B9=E6=B3=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 37 +++++++++-------------- sf_manufacturing/models/mrp_workorder.py | 25 ++++++++++++--- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 65c3ebec..27baa7be 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -29,41 +29,34 @@ class MrpProduction(models.Model): detection_result_ids = fields.One2many('sf.detection.result', 'production_id', '检测报告') tool_state = fields.Selection([('0', '正常'), ('1', '缺刀'), ('2', '无效刀')], string='功能刀具状态', default='0', store=True, compute='_compute_tool_state') - tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', readonly=True) + tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True) tool_state_remark2 = fields.Text(string='功能刀具状态备注(无效刀)', readonly=True) + @api.depends('workorder_ids.tool_state_remark') + def _compute_tool_state_remark(self): + for item in self: + if item.workorder_ids: + workorder_ids = item.workorder_ids.filtered(lambda a: a.state not in ('rework', '返工')) + if workorder_ids.filtered(lambda a: a.tool_state_remark): + work_ids = workorder_ids.filtered(lambda a: a.tool_state_remark) + tool_state_remark = '' + for work_id in work_ids: + tool_state_remark = f"{work_id.tool_state_remark}\n" + item.tool_state_remark = tool_state_remark + else: + item.tool_state_remark = False + @api.depends('workorder_ids.tool_state') def _compute_tool_state(self): - # if self.workorder_ids: for item in self: if item.workorder_ids: workorder_ids = item.workorder_ids.filtered(lambda a: a.state not in ('rework', '返工')) if workorder_ids.filtered(lambda a: a.tool_state == '2'): item.tool_state = '2' elif workorder_ids.filtered(lambda a: a.tool_state == '1'): - tool_state_remark = '' - data = {} - # 获取所有缺刀工单加工面对应缺的刀 - for work in workorder_ids.filtered(lambda a: a.tool_state == '1'): - if work.processing_panel not in list(data.keys()): - data.update({work.processing_panel: []}) - for cnc in work.cnc_ids.filtered(lambda a: a.tool_state == '1'): - if cnc.cutting_tool_name not in data[work.processing_panel]: - data[work.processing_panel].append(cnc.cutting_tool_name) - # 按格式生成缺刀提示信息 - for key in data: - if data.get(key) and not data.get(key): - if tool_state_remark != '': - tool_state_remark = f'{tool_state_remark}\n{key}缺刀:{data.get(key)}' - else: - tool_state_remark = f'{key}缺刀:{data.get(key)}' item.tool_state = '1' - item.tool_state_remark = tool_state_remark - item.tool_state_remark2 = '' else: item.tool_state = '0' - item.tool_state_remark = '' - item.tool_state_remark2 = '' # state = fields.Selection(selection_add=[ # ('pending_scheduling', '待排程'), diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index fce19e16..827f77df 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -180,11 +180,27 @@ class ResMrpWorkOrder(models.Model): # 功能刀具状态 tool_state = fields.Selection([('0', '正常'), ('1', '缺刀'), ('2', '无效刀')], string='功能刀具状态', default='0', store=True, compute='_compute_tool_state') + tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True) + + @api.depends('cnc_ids.tool_state') + def _compute_tool_state_remark(self): + for item in self: + if item.cnc_ids: + if item.cnc_ids.filtered(lambda a: a.tool_state == '2'): + item.tool_state_remark = None + elif item.cnc_ids.filtered(lambda a: a.tool_state == '1'): + tool_state_remark = f'{item.processing_panel}缺刀:[' + cnc_ids = item.cnc_ids.filtered(lambda a: a.tool_state == '1') + for cnc_id in cnc_ids: + tool_state_remark = f"{tool_state_remark}'{cnc_id.cutting_tool_name}'" + item.tool_state_remark = f"{tool_state_remark}]" + else: + item.tool_state_remark = None @api.depends('cnc_ids.tool_state') def _compute_tool_state(self): for item in self: - if item: + if item.cnc_ids: if item.cnc_ids.filtered(lambda a: a.tool_state == '2'): item.tool_state = '2' elif item.cnc_ids.filtered(lambda a: a.tool_state == '1'): @@ -835,9 +851,10 @@ class ResMrpWorkOrder(models.Model): # if workorder.state not in ['cancel', 'rework']: # workorder.state = 'rework' if workorder.production_id.state == 'pending_cam': - if workorder.routing_type == '装夹预调' and workorder.state in ['ready', 'waiting']: - if workorder.production_id.tool_state in ['1', '2']: - workorder.state = 'waiting' + if workorder.production_id.tool_state in ['1', '2']: + work_ids = workorder.production_id.workorder_ids.filtered( + lambda a: a.routing_type == '装夹预调' and a.state in ['ready', 'waiting']) + work_ids.state = 'waiting' logging.info('工序:%s' % workorder.sequence) logging.info('工单最终状态:%s' % workorder.state) From 98d2aa756a34bccbef994e3679ed5eefc8a664f3 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Fri, 26 Jul 2024 11:49:33 +0800 Subject: [PATCH 08/12] =?UTF-8?q?1=E3=80=81=E8=A7=A3=E5=86=B3=20=20?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E6=98=AF=E6=97=A0=E6=95=88?= =?UTF-8?q?=E5=88=80=E6=97=B6-=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E8=BF=94=E5=B7=A5=E3=80=90=E7=94=B3=E8=AF=B7?= =?UTF-8?q?=E9=87=8D=E6=96=B0=E7=BC=96=E7=A8=8B=E3=80=91=E8=A6=81=E5=81=9A?= =?UTF-8?q?=E6=88=90=E5=BF=85=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/wizard/rework_wizard.py | 2 ++ sf_manufacturing/wizard/rework_wizard_views.xml | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sf_manufacturing/wizard/rework_wizard.py b/sf_manufacturing/wizard/rework_wizard.py index f15f85d1..bf1224fb 100644 --- a/sf_manufacturing/wizard/rework_wizard.py +++ b/sf_manufacturing/wizard/rework_wizard.py @@ -31,6 +31,8 @@ class ReworkWizard(models.TransientModel): ('已下发', '已下发')], string='编程状态') + tool_state = fields.Selection(string='功能刀具状态', related='production_id.tool_state') + def confirm(self): if self.routing_type in ['装夹预调', 'CNC加工']: self.workorder_id.is_rework = True diff --git a/sf_manufacturing/wizard/rework_wizard_views.xml b/sf_manufacturing/wizard/rework_wizard_views.xml index 7008e4b9..08e5f8ef 100644 --- a/sf_manufacturing/wizard/rework_wizard_views.xml +++ b/sf_manufacturing/wizard/rework_wizard_views.xml @@ -9,6 +9,7 @@ + -
+
申请重新编程 - +
-
+
申请重新编程 + attrs='{"readonly": ["|",("is_reprogramming_readonly","=",False),("tool_state", "=", "2")]}'/>
From b731ffba331fc57959578190d78fca7096f1cd66 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Fri, 26 Jul 2024 14:51:23 +0800 Subject: [PATCH 09/12] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 5 +++++ sf_tool_management/models/mrp_workorder.py | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 27baa7be..0bbda373 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -50,6 +50,7 @@ class MrpProduction(models.Model): def _compute_tool_state(self): for item in self: if item.workorder_ids: + tool_state = item.tool_state workorder_ids = item.workorder_ids.filtered(lambda a: a.state not in ('rework', '返工')) if workorder_ids.filtered(lambda a: a.tool_state == '2'): item.tool_state = '2' @@ -57,6 +58,10 @@ class MrpProduction(models.Model): item.tool_state = '1' else: item.tool_state = '0' + if tool_state == '2' and item.tool_state != '2': + item.detection_result_ids.filtered( + lambda a: a.detailed_reason == '无效功能刀具' and a.handle_result == '待处理').write( + {'handle_result': '已处理'}) # state = fields.Selection(selection_add=[ # ('pending_scheduling', '待排程'), diff --git a/sf_tool_management/models/mrp_workorder.py b/sf_tool_management/models/mrp_workorder.py index 352162b7..f3fc3484 100644 --- a/sf_tool_management/models/mrp_workorder.py +++ b/sf_tool_management/models/mrp_workorder.py @@ -105,6 +105,12 @@ class CNCprocessing(models.Model): 'test_results': '返工', 'handle_result': '待处理' }) + if not production_id.is_rework: + production_id.write({ + 'is_rework': True + }) + production_id.workorder_ids.filtered( + lambda a: a.processing_panel == key and not a.is_rework).write({'is_rework': True}) # 对缺刀信息进行处理 for key in data2: if data2.get(key): From 3e61e31314b303953b277599ed89a8ead0ddfd5c Mon Sep 17 00:00:00 2001 From: hy <1298386937@qq.com> Date: Fri, 26 Jul 2024 15:44:52 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=80=E5=85=B7?= =?UTF-8?q?=E6=8B=86=E8=A7=A3=E6=97=B6=E9=80=89=E6=8B=A9=E7=9B=AE=E6=A0=87?= =?UTF-8?q?=E8=B4=A7=E4=BD=8D=E4=BC=9A=E5=87=BA=E7=8E=B0=E9=87=8D=E5=8F=A0?= =?UTF-8?q?=E7=9A=84=E7=8E=B0=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_frontend/static/src/scss/custom_style.scss | 6 ------ 1 file changed, 6 deletions(-) diff --git a/jikimo_frontend/static/src/scss/custom_style.scss b/jikimo_frontend/static/src/scss/custom_style.scss index cbd1bb4d..d7e6414c 100644 --- a/jikimo_frontend/static/src/scss/custom_style.scss +++ b/jikimo_frontend/static/src/scss/custom_style.scss @@ -532,9 +532,3 @@ div:has(.o_required_modifier) > label::before { position: unset; } -// 修改表格下拉框会被表格下面数据框覆盖的bug -.tab-pane .o_field_widget { - position: relative; - z-index: 1; -} - From 66caeee1cdf224fbcdcb8dba214b9f46ad41113e Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Fri, 26 Jul 2024 16:25:16 +0800 Subject: [PATCH 11/12] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E7=8A=B6=E6=80=81=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 20 +++++++++++++------- sf_tool_management/models/mrp_workorder.py | 12 ++++++------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 827f77df..ded46f93 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -806,8 +806,6 @@ class ResMrpWorkOrder(models.Model): if workorder.production_id.is_rework is True: if re_work or cnc_workorder: workorder.state = 'waiting' - if workorder.production_id.tool_state in ['1', '2'] and workorder.state != 'pending': - workorder.state = 'waiting' elif workorder.routing_type == 'CNC加工' and workorder.state not in ['done', 'rework', 'cancel']: pre_workorder = self.env['mrp.workorder'].search( @@ -850,11 +848,19 @@ class ResMrpWorkOrder(models.Model): # else: # if workorder.state not in ['cancel', 'rework']: # workorder.state = 'rework' - if workorder.production_id.state == 'pending_cam': - if workorder.production_id.tool_state in ['1', '2']: - work_ids = workorder.production_id.workorder_ids.filtered( - lambda a: a.routing_type == '装夹预调' and a.state in ['ready', 'waiting']) - work_ids.state = 'waiting' + # 当工单对应制造订单的功能刀具状态为 【无效刀】时,先对的第一个装夹预调工单状态设置为 【等待组件】 + if workorder.production_id.tool_state in ['1', '2']: + if workorder.routing_type == '装夹预调': + if workorder.state in ['ready']: + workorder.state = 'waiting' + continue + elif workorder.state == 'pending' and self.search( + [('production_id', '=', workorder.production_id.id), + ('sequence', '=', workorder.sequence - 1), + ('state', 'in', ['done', 'rework'])]): + workorder.state = 'waiting' + continue + logging.info('工序:%s' % workorder.sequence) logging.info('工单最终状态:%s' % workorder.state) diff --git a/sf_tool_management/models/mrp_workorder.py b/sf_tool_management/models/mrp_workorder.py index f3fc3484..eb8db183 100644 --- a/sf_tool_management/models/mrp_workorder.py +++ b/sf_tool_management/models/mrp_workorder.py @@ -105,12 +105,12 @@ class CNCprocessing(models.Model): 'test_results': '返工', 'handle_result': '待处理' }) - if not production_id.is_rework: - production_id.write({ - 'is_rework': True - }) - production_id.workorder_ids.filtered( - lambda a: a.processing_panel == key and not a.is_rework).write({'is_rework': True}) + # if not production_id.is_rework: + # production_id.write({ + # 'is_rework': True + # }) + # production_id.workorder_ids.filtered( + # lambda a: a.processing_panel == key and not a.is_rework).write({'is_rework': True}) # 对缺刀信息进行处理 for key in data2: if data2.get(key): From 22a1ae11a6b6c882e12f9fd1990dfdd02d212690 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 26 Jul 2024 16:52:48 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=94=E5=B7=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 4 ++++ sf_manufacturing/wizard/rework_wizard.py | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 0bbda373..6eff353d 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -902,6 +902,10 @@ class MrpProduction(models.Model): if pre_workorder: pre_workorder.write( {'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())}) + # if production.state == 'rework' and production.programming_state == '已编程未下发': + # production.write( + # {'state': 'progress', 'programming_state': '已编程', 'is_rework': False}) + # logging.info('返工含有已编程未下发的程序更新完成:%s' % production.name) logging.info('更新程序完成:%s' % production.name) else: diff --git a/sf_manufacturing/wizard/rework_wizard.py b/sf_manufacturing/wizard/rework_wizard.py index bf1224fb..a52c5093 100644 --- a/sf_manufacturing/wizard/rework_wizard.py +++ b/sf_manufacturing/wizard/rework_wizard.py @@ -165,6 +165,13 @@ class ReworkWizard(models.TransientModel): {'programming_state': '编程中', 'work_state': '编程中'}) if self.production_id.state == 'progress': self.production_id.write({'programming_state': '已编程', 'work_state': '已编程'}) + if self.reprogramming_num >= 1 and self.programming_state == '已编程': + productions_not_delivered = self.env['mrp.production'].search( + [('programming_no', '=', self.production_id.programming_no), + ('programming_state', '=', '已编程未下发')]) + if productions_not_delivered: + productions_not_delivered.write( + {'programming_state': '已编程', 'work_state': '已编程', 'is_rework': False}) @api.onchange('production_id') def onchange_processing_panel_id(self):