From 38c4aba45c7d2bbfe8fc68db91efe77f1fcdb465 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 8 Nov 2024 18:01:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E5=B7=A5=E5=BA=8F=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=B7=A5=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/common.py | 3 +- sf_manufacturing/__manifest__.py | 1 + sf_manufacturing/models/__init__.py | 1 + sf_manufacturing/models/model_type.py | 51 ------ sf_manufacturing/models/mrp_production.py | 152 +++++++----------- sf_manufacturing/models/mrp_workorder.py | 62 ++----- .../models/sf_production_common.py | 16 ++ .../models/sf_technology_design.py | 9 +- sf_manufacturing/security/ir.model.access.csv | 4 + .../views/mrp_production_addional_change.xml | 2 + sf_manufacturing/wizard/__init__.py | 1 + .../wizard/production_technology_wizard.py | 25 +++ .../production_technology_wizard_views.xml | 34 ++++ 13 files changed, 167 insertions(+), 194 deletions(-) create mode 100644 sf_manufacturing/models/sf_production_common.py create mode 100644 sf_manufacturing/wizard/production_technology_wizard.py create mode 100644 sf_manufacturing/wizard/production_technology_wizard_views.xml diff --git a/sf_base/models/common.py b/sf_base/models/common.py index 95572631..257eb2d4 100644 --- a/sf_base/models/common.py +++ b/sf_base/models/common.py @@ -100,6 +100,7 @@ class MrsProductionProcess(models.Model): travel_day = fields.Float('路途天数/d') sequence = fields.Integer('排序') + # class MrsProcessingTechnology(models.Model): # _name = 'sf.processing.technology' # _description = '加工工艺' @@ -157,7 +158,7 @@ class MrsProductionProcessParameter(models.Model): for parameter in self: if parameter.process_id: name = parameter.process_id.name + '-' + parameter.name - result.append((parameter.id, name)) + result.append((parameter.id, name)) return result # 获取表面工艺的获取方式 diff --git a/sf_manufacturing/__manifest__.py b/sf_manufacturing/__manifest__.py index 5106dcb1..3320f943 100644 --- a/sf_manufacturing/__manifest__.py +++ b/sf_manufacturing/__manifest__.py @@ -21,6 +21,7 @@ 'wizard/workpiece_delivery_views.xml', 'wizard/rework_wizard_views.xml', 'wizard/production_wizard_views.xml', + 'wizard/production_technology_wizard_views.xml', 'views/mrp_views_menus.xml', 'views/agv_scheduling_views.xml', 'views/stock_lot_views.xml', diff --git a/sf_manufacturing/models/__init__.py b/sf_manufacturing/models/__init__.py index 234d208e..b0c295f5 100644 --- a/sf_manufacturing/models/__init__.py +++ b/sf_manufacturing/models/__init__.py @@ -12,3 +12,4 @@ from . import agv_setting from . import agv_scheduling from . import res_config_setting from . import sf_technology_design +from . import sf_production_common diff --git a/sf_manufacturing/models/model_type.py b/sf_manufacturing/models/model_type.py index 10157f63..27ebfb03 100644 --- a/sf_manufacturing/models/model_type.py +++ b/sf_manufacturing/models/model_type.py @@ -24,24 +24,7 @@ class ProductModelTypeRoutingSort(models.Model): route_workcenter_id = fields.Many2one('mrp.routing.workcenter', domain=[('routing_type', 'in', ['装夹预调', 'CNC加工', '解除装夹'])]) is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat') - - # routing_type = fields.Selection([ - # ('获取CNC加工程序', '获取CNC加工程序'), - # ('装夹', '装夹'), - # ('前置三元定位检测', '前置三元定位检测'), - # ('CNC加工', 'CNC加工'), - # ('后置三元质量检测', '后置三元质量检测'), - # ('解除装夹', '解除装夹'), ('切割', '切割'), ('表面工艺', '表面工艺') - # ], string="工序类型", compute='_compute_route_workcenter_id') - # - # @api.depends('route_workcenter_id') - # def _compute_route_workcenter_id(self): - # for record in self: - # if record: - # record.routing_type = record.route_workcenter_id.routing_type - routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type') - workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids') product_model_type_id = fields.Many2one('sf.model.type') @@ -57,24 +40,7 @@ class EmbryoModelTypeRoutingSort(models.Model): sequence = fields.Integer('Sequence') route_workcenter_id = fields.Many2one('mrp.routing.workcenter', domain=[('routing_type', 'in', ['切割'])]) is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat') - - # routing_type = fields.Selection([ - # ('获取CNC加工程序', '获取CNC加工程序'), - # ('装夹', '装夹'), - # ('前置三元定位检测', '前置三元定位检测'), - # ('CNC加工', 'CNC加工'), - # ('后置三元质量检测', '后置三元质量检测'), - # ('解除装夹', '解除装夹'), ('切割', '切割'), ('表面工艺', '表面工艺') - # ], string="工序类型", compute='_compute_route_workcenter_id') - # - # @api.depends('route_workcenter_id') - # def _compute_route_workcenter_id(self): - # for record in self: - # if record: - # record.routing_type = record.route_workcenter_id.routing_type - routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type') - workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids') embryo_model_type_id = fields.Many2one('sf.model.type') @@ -90,24 +56,7 @@ class SurfaceTechnicsModelTypeRoutingSort(models.Model): sequence = fields.Integer('Sequence') route_workcenter_id = fields.Many2one('mrp.routing.workcenter', domain=[('routing_type', 'in', ['表面工艺'])]) is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat') - - # routing_type = fields.Selection([ - # ('获取CNC加工程序', '获取CNC加工程序'), - # ('装夹', '装夹'), - # ('前置三元定位检测', '前置三元定位检测'), - # ('CNC加工', 'CNC加工'), - # ('后置三元质量检测', '后置三元质量检测'), - # ('解除装夹', '解除装夹'), ('切割', '切割'), ('表面工艺', '表面工艺') - # ], string="工序类型", compute='_compute_route_workcenter_id') - # - # @api.depends('route_workcenter_id') - # def _compute_route_workcenter_id(self): - # for record in self: - # if record: - # record.routing_type = record.route_workcenter_id.routing_type - routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type') - workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids') surface_technics_model_type_id = fields.Many2one('sf.model.type') diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 54b1a61c..ad08be25 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -216,8 +216,9 @@ class MrpProduction(models.Model): precision_rounding=move.product_uom.rounding or move.product_id.uom_id.rounding) for move in production.move_raw_ids if move.product_id): production.state = 'progress' - - # # 新添加的状态逻辑 + elif not production.technology_design_ids: + production.state = 'technology_to_confirmed' + # 新添加的状态逻辑 if ( production.state == 'to_close' or production.state == 'progress') and production.schedule_state == '未排': production.state = 'confirmed' @@ -254,42 +255,45 @@ class MrpProduction(models.Model): if production.tool_state == '2': production.state = 'rework' + # 工艺确认 def technology_confirm(self): # 判断同一个加工面的标准工序的顺序是否依次排序 - technology_design = self.technology_design_ids.sorted(key=lambda m: m.sequence) - current_design_index = None - for index, design in enumerate(technology_design.filtered(lambda a: a.routing_tag == 'standard')): - if design == current_design: - current_design_index = index - break # 找到了 current_design,跳出循环 - - # 现在我们有了 current_design 的索引,我们可以找到下一条设计 - if current_design_index is not None and current_design_index + 1 < len(technology_design): - next_design = technology_design[current_design_index + 1] - # 下一条设计是 next_design - else: - # 如果 current_design_index 为 None 或者没有下一条设计,则 next_design 为 None - next_design = None - for design in technology_design.filtered(lambda a: a.routing_tag == 'standard'): + technology_design = self.technology_design_ids.filtered(lambda a: a.routing_tag == 'standard').sorted( + key=lambda m: m.sequence) + error_panel = [] + for index, design in enumerate(technology_design): routing_type = design.route_id.routing_type - if routing_type in ['装夹预调', 'CNC加工', '解除装夹']: - # standard_designs = [d for d in technology_design_ids if d.routing_tag == 'standard'] - # last_design = technology_design[technology_design.index(design) - 1] - next_design = technology_design[2] - for next_design in technology_design: - next_design_routing_type = next_design.route_id.routing_type - logging.info('next_design:%s' % next_design.route_id.name) - logging.info('next_design面:%s' % next_design.panel) - logging.info('design:%s' % design.route_id.name) - logging.info('design面:%s' % design.panel) - if next_design == design: - break - if design.panel != next_design.panel and routing_type not in ['解除装夹']: + if index < len(technology_design) - 1: + next_index = index + 1 + next_design = technology_design[next_index] + next_design_routing_type = next_design.route_id.routing_type + logging.info('当前工序和加工面: %s-%s' % (design.route_id.name, design.panel)) + logging.info('下一个工序和加工面: %s-%s' % (next_design.route_id.name, next_design.panel)) + if design.panel != next_design.panel: + if index == 0: raise UserError('【加工面】为%s的标准工序里含有其他加工面的工序,请调整后重试' % design.panel) - if design.panel == next_design.panel: - if (routing_type == '装夹预调' and next_design_routing_type == '解除装夹') or ( - routing_type == 'CNC加工' and next_design_routing_type == '装夹预调'): - raise UserError('【加工面】为%s的标准工序顺序有误,请调整后重试' % design.panel) + if routing_type not in ['解除装夹']: + raise UserError('【加工面】为%s的标准工序顺序有误,请调整后重试' % design.panel) + if design.panel == next_design.panel: + if (routing_type == '装夹预调' and next_design_routing_type == '解除装夹') or ( + routing_type == 'CNC加工' and next_design_routing_type == '装夹预调'): + if design.panel not in error_panel: + error_panel.append(design.panel) + else: + if not error_panel: + return { + 'name': _('工艺确认'), + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'sf.production.technology.wizard', + 'target': 'new', + 'context': { + 'default_production_id': self.id, + 'default_origin': self.origin, + }} + if error_panel: + raise UserError(_("【加工面】为%s的标准工序顺序有误,请调整后重试", ", ".join(error_panel))) + return True def action_check(self): @@ -530,73 +534,33 @@ class MrpProduction(models.Model): 'state': 'pending', }] if production.product_id.categ_id.type == '成品': - # # 根据加工面板的面数及对应的工序模板生成工单 - i = 0 - processing_panel_len = len(production.product_id.model_processing_panel.split(',')) - for k in (production.product_id.model_processing_panel.split(',')): - product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search( - [('product_model_type_id', '=', production.product_id.product_model_type_id.id)], - order='sequence asc' - ) - i += 1 - for route in product_routing_workcenter: - if route.is_repeat is True: - workorders_values.append( - self.env['mrp.workorder'].json_workorder_str(k, production, route, item)) - # if i == processing_panel_len and route.routing_type == '解除装夹': - # workorders_values.append( - # self.env['mrp.workorder'].json_workorder_str(k, production, route)) - # 表面工艺工序 - # 获取表面工艺id - # 工序id - surface_technics_arr = [] - route_workcenter_arr = [] - for item in production.product_id.product_model_type_id.surface_technics_routing_tmpl_ids: - if item.route_workcenter_id.surface_technics_id.id: - for process_param in production.product_id.model_process_parameters_ids: - logging.info('process_param:%s%s' % (process_param.id, process_param.name)) - if item.route_workcenter_id.surface_technics_id == process_param.process_id: - logging.info( - 'surface_technics_id:%s%s' % (item.route_workcenter_id.surface_technics_id.id, - item.route_workcenter_id.surface_technics_id.name)) - surface_technics_arr.append(item.route_workcenter_id.surface_technics_id.id) - route_workcenter_arr.append(item.route_workcenter_id.id) - if surface_technics_arr: - production_process = self.env['sf.production.process'].search( - [('id', 'in', surface_technics_arr)], - order='sequence asc' - ) - for p in production_process: - logging.info('production_process:%s' % p.name) - # if production_process: - process_parameter = production.product_id.model_process_parameters_ids.filtered( - lambda pm: pm.process_id.id == p.id) - if process_parameter: - # 产品为表面工艺服务的供应商 - product_production_process = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', process_parameter.id)]) - if product_production_process: - route_production_process = self.env[ - 'mrp.routing.workcenter'].search( - [('surface_technics_id', '=', p.id), - ('id', 'in', route_workcenter_arr)]) - if route_production_process: - workorders_values.append( - self.env[ - 'mrp.workorder']._json_workorder_surface_process_str( - production, route_production_process, - process_parameter, - product_production_process.seller_ids[0].partner_id.id)) + # # 根据工序设计生成工单 + for route in item.technology_design_ids: + if route.route_id.routing_type not in ['表面工艺']: + workorders_values.append( + self.env['mrp.workorder'].json_workorder_str(production, route)) + else: + product_production_process = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', route.process_parameters_id.id)]) + # if product_production_process: + # route_production_process = self.env[ + # 'mrp.routing.workcenter'].search( + # [('surface_technics_id', '=', p.id), + # ('id', 'in', route_workcenter_arr)]) + # if route_production_process: + workorders_values.append( + self.env[ + 'mrp.workorder']._json_workorder_surface_process_str( + production, route, product_production_process.seller_ids[0].partner_id.id)) elif production.product_id.categ_id.type == '坯料': embryo_routing_workcenter = self.env['sf.embryo.model.type.routing.sort'].search( [('embryo_model_type_id', '=', production.product_id.embryo_model_type_id.id)], order='sequence asc' ) - for route in embryo_routing_workcenter: + for route_embryo in embryo_routing_workcenter: workorders_values.append( - self.env['mrp.workorder'].json_workorder_str('', production, route)) + self.env['mrp.workorder'].json_workorder_str('', production, route_embryo)) production.workorder_ids = workorders_values - # for production_item in productions: process_parameter_workorder = self.env['mrp.workorder'].search( [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id), ('is_subcontract', '=', True)]) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 649d51bc..5c71d5bc 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -669,35 +669,14 @@ class ResMrpWorkOrder(models.Model): }} # 拼接工单对象属性值 - def json_workorder_str(self, k, production, route, item): + def json_workorder_str(self, production, route): # 计算预计时长duration_expected routing_types = ['切割', '装夹预调', 'CNC加工', '解除装夹'] - if route.routing_type in routing_types: + if route.route_id.routing_type in routing_types: routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search( - [('name', '=', route.routing_type)]) + [('name', '=', route.route_id.routing_type)]) duration_expected = routing_workcenter.time_cycle reserved_duration = routing_workcenter.reserved_duration - # if route.routing_type == '切割': - # duration_expected = self.env['mrp.routing.workcenter'].sudo().search( - # [('name', '=', '切割')]).time_cycle - # # elif route.routing_type == '获取CNC加工程序': - # # duration_expected = self.env['mrp.routing.workcenter'].sudo().search( - # # [('name', '=', '获取CNC加工程序')]).time_cycle - # elif route.routing_type == '装夹预调': - # duration_expected = self.env['mrp.routing.workcenter'].sudo().search( - # [('name', '=', '装夹预调')]).time_cycle - # # elif route.routing_type == '前置三元定位检测': - # # duration_expected = self.env['mrp.routing.workcenter'].sudo().search( - # # [('name', '=', '前置三元定位检测')]).time_cycle - # elif route.routing_type == 'CNC加工': - # duration_expected = self.env['mrp.routing.workcenter'].sudo().search( - # [('name', '=', 'CNC加工')]).time_cycle - # # elif route.routing_type == '后置三元质量检测': - # # duration_expected = self.env['mrp.routing.workcenter'].sudo().search( - # # [('name', '=', '后置三元质量检测')]).time_cycle - # elif route.routing_type == '解除装夹': - # duration_expected = self.env['mrp.routing.workcenter'].sudo().search( - # [('name', '=', '解除装夹')]).time_cycle else: duration_expected = 60 reserved_duration = 30 @@ -705,26 +684,19 @@ class ResMrpWorkOrder(models.Model): 'product_uom_id': production.product_uom_id.id, 'qty_producing': 0, 'operation_id': False, - 'name': route.route_workcenter_id.name, - 'processing_panel': k, - 'quality_point_ids': route.route_workcenter_id.quality_point_ids, - 'routing_type': route.routing_type, - # 'work_state': '待发起', - 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids, - route.routing_type, + 'name': route.route_id.name, + 'processing_panel': route.panel, + 'quality_point_ids': route.route_id.quality_point_ids, + 'routing_type': route.route_id.routing_type, + 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.route_id.workcenter_ids.ids, + route.route_id.routing_type, production.product_id), # 设定初始化值,避免出现变成bool问题 'date_planned_start': datetime.now(), 'date_planned_finished': datetime.now() + timedelta(days=1), 'duration_expected': duration_expected, 'duration': 0, - 'tag_type': '重新加工' if item is False else False, - 'cnc_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cnc.processing']._json_cnc_processing( - k, item), - 'cmm_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cmm.program']._json_cmm_program(k, - item), - # 'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list( - # production) + # 'tag_type': '重新加工' if item is False else False, 'reserved_duration': reserved_duration, }] return workorders_values_str @@ -755,22 +727,22 @@ class ResMrpWorkOrder(models.Model): ] # 拼接工单对象属性值(表面工艺) - def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id): + def _json_workorder_surface_process_str(self, production, route, supplier_id): workorders_values_str = [0, '', { 'product_uom_id': production.product_uom_id.id, 'qty_producing': 0, 'operation_id': False, - 'name': '%s-%s' % (route.name, process_parameter.name), + 'name': route.process_parameters_id.display_name, 'processing_panel': '', 'routing_type': '表面工艺', - 'surface_technics_parameters_id': process_parameter.id, + 'surface_technics_parameters_id': route.process_parameters_id.id, 'work_state': '', 'supplier_id': supplier_id, - 'is_subcontract': True if process_parameter.gain_way == '外协' else False, + 'is_subcontract': True if route.process_parameters_id.gain_way == '外协' else False, 'workcenter_id': self.env[ - 'mrp.workcenter'].get_process_outsourcing_workcenter() if process_parameter.gain_way == '外协' else - self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids, - route.routing_type, + 'mrp.workcenter'].get_process_outsourcing_workcenter() if route.process_parameters_id.gain_way == '外协' else + self.env['mrp.routing.workcenter'].get_workcenter(route.route_id.workcenter_ids.ids, + route.route_id.routing_type, production.product_id), 'date_planned_start': datetime.now(), 'date_planned_finished': datetime.now() + timedelta(days=1), diff --git a/sf_manufacturing/models/sf_production_common.py b/sf_manufacturing/models/sf_production_common.py new file mode 100644 index 00000000..234996da --- /dev/null +++ b/sf_manufacturing/models/sf_production_common.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +import logging +from odoo import fields, models, api +from odoo.exceptions import UserError + + +class SfProductionProcessParameter(models.Model): + _inherit = 'sf.production.process.parameter' + + @api.model + def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): + if self._context.get('route_id'): + routing = self.env['mrp.routing.workcenter'].search([('id', '=', self._context.get('route_id'))]) + domain = [('process_id', '=', routing.surface_technics_id.id)] + return self._search(domain, limit=limit, access_rights_uid=name_get_uid) + return super()._name_search(name, args, operator, limit, name_get_uid) diff --git a/sf_manufacturing/models/sf_technology_design.py b/sf_manufacturing/models/sf_technology_design.py index e5ce0c69..6aa49f5a 100644 --- a/sf_manufacturing/models/sf_technology_design.py +++ b/sf_manufacturing/models/sf_technology_design.py @@ -6,9 +6,10 @@ class sf_technology_design(models.Model): _name = 'sf.technology.design' _description = "工艺设计" - route_id = fields.Many2one('mrp.routing.workcenter', '工序') - panel = fields.Char('加工面') sequence = fields.Integer('序号') + route_id = fields.Many2one('mrp.routing.workcenter', '工序') + process_parameters_id = fields.Many2one('sf.production.process.parameter', string='表面工艺参数') + panel = fields.Char('加工面') routing_tag = fields.Selection(related='route_id.routing_tag', string='标签', store=True) time_cycle_manual = fields.Float(related='route_id.time_cycle_manual', string='预计时长') production_id = fields.Many2one('mrp.production') @@ -19,10 +20,12 @@ class sf_technology_design(models.Model): workorders_values_str = [0, '', { 'route_id': route.id, 'panel': k, + 'process_parameters_id': False if route.routing_type.id != '表面工艺' else self.env[ + 'sf.production.process.parameter'].search( + [('process_id', '=', route.surface_technics_id.id)]).id, 'sequence': i, 'is_auto': True}] return workorders_values_str def unlink_technology_design(self): self.active = False - diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv index 270c0f18..21386995 100644 --- a/sf_manufacturing/security/ir.model.access.csv +++ b/sf_manufacturing/security/ir.model.access.csv @@ -168,5 +168,9 @@ access_sf_agv_scheduling_group_sf_equipment_user,sf_agv_scheduling_group_sf_equi access_sf_technology_design_group_plan_dispatch,sf_technology_design_group_plan_dispatch,model_sf_technology_design,sf_base.group_plan_dispatch,1,1,1,0 access_sf_technology_design_group_sf_mrp_manager,sf_technology_design_group_sf_mrp_manager,model_sf_technology_design,sf_base.group_sf_mrp_manager,1,1,1,0 access_sf_technology_design_group_production_engineer,sf_technology_design_group_production_engineer,model_sf_technology_design,sf_base.group_production_engineer,1,1,1,0 +access_sf_production_technology_wizard_group_plan_dispatch,sf_production_technology_wizard_group_plan_dispatch,model_sf_production_technology_wizard,sf_base.group_plan_dispatch,1,1,1,0 +access_sf_production_technology_wizard_group_sf_mrp_manager,sf_production_technology_wizard_group_sf_mrp_manager,model_sf_production_technology_wizard,sf_base.group_sf_mrp_manager,1,1,1,0 +access_sf_production_technology_wizard_group_production_engineer,sf_production_technology_wizard_group_production_engineer,model_sf_production_technology_wizard,sf_base.group_production_engineer,1,1,1,0 + diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 1899aad2..fea04fe6 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -349,6 +349,8 @@ + + + + sf.production.technology.wizard.form.view + sf.production.technology.wizard + +
+ + + +
+ + 对当前制造订单,同一销售订单相同产品所生成的制造订单统一进行工艺调整与确认 +
+
+
+
+
+
+
+ + + 工艺确认 + sf.production.technology.wizard + form + + + + new + + +
\ No newline at end of file