From 9a1cde6abcef47f36cfe2c795faa3dd63c796e88 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Wed, 4 Dec 2024 10:45:46 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E8=A1=A8=E9=9D=A2=E5=B7=A5=E8=89=BA?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=8D=95=E4=B8=8E=E8=B0=83=E6=8B=A8=E5=8D=95?= =?UTF-8?q?=E6=8B=86=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 38 ++++------------------- sf_manufacturing/models/mrp_workorder.py | 14 ++++----- sf_sale/models/sale_order.py | 3 +- 3 files changed, 14 insertions(+), 41 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 9156dc38..f24eb6b9 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -729,40 +729,14 @@ class MrpProduction(models.Model): sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence) for i, workorder in enumerate(sorted_workorders): # 检查当前工作订单和下一个工作订单是否连续,并且供应商相同 - if i == 0: - consecutive_workorders.append(workorder) - elif workorder.sequence == sorted_workorders[ - i - 1].sequence + 1 and workorder.supplier_id.id == sorted_workorders[i - 1].supplier_id.id: - consecutive_workorders.append(workorder) - else: - # 处理连续组,如果它不为空 - if consecutive_workorders: - # 创建外协出入库单和采购订单 - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) - self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, - product_id_to_production_names) - if i < len(sorted_workorders) - 1: - # 重置连续组,并添加当前工作订单 - consecutive_workorders = [workorder] - else: - # 判断最后一笔: - if workorder.sequence == sorted_workorders[ - i - 1].sequence and workorder.supplier_id.id == sorted_workorders[ - i - 1].supplier_id.id: - consecutive_workorders = [workorder] - else: - # 立即创建外协出入库单和采购订单 - self.env['stock.picking'].create_outcontract_picking(workorder, production) - self.env['purchase.order'].get_purchase_order(workorder, production, - product_id_to_production_names) - consecutive_workorders = [] - - # 处理最后一个组,即使它可能只有一个工作订单 - if consecutive_workorders: - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) - self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, + if not workorder.picking_ids: + self.env['stock.picking'].create_outcontract_picking(workorder, production) + # if not workorder. + if not workorder.purchase_id: + self.env['purchase.order'].get_purchase_order(workorder, production, product_id_to_production_names) + # 工单排序 def _reset_work_order_sequence1(self, k): for rec in self: diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 4ea08f94..a55523a0 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -135,7 +135,7 @@ class ResMrpWorkOrder(models.Model): is_subcontract = fields.Boolean(string='是否外协') surface_technics_parameters_id = fields.Many2one('sf.production.process.parameter', string="表面工艺可选参数") picking_ids = fields.Many2many('stock.picking', string='外协出入库单') - # purchase_id = fields.Many2one('purchase.order', string='外协采购单') + purchase_id = fields.Many2many('purchase.order', string='外协采购单') surface_technics_picking_count = fields.Integer("外协出入库", compute='_compute_surface_technics_picking_ids') surface_technics_purchase_count = fields.Integer("外协采购", compute='_compute_surface_technics_purchase_ids') @@ -239,13 +239,11 @@ class ResMrpWorkOrder(models.Model): previous_workorder = self.env['mrp.workorder'].search( [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'), ('production_id', '=', workorder.production_id.id)]) - if previous_workorder: - if previous_workorder.supplier_id != workorder.supplier_id: - # process_product = self.env['product.template']._get_process_parameters_product( - # previous_workorder.surface_technics_parameters_id) - domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] - else: - domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] + # if previous_workorder: + # if previous_workorder.supplier_id != workorder.supplier_id: + # domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] + # else: + domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] picking_ids = self.env['stock.picking'].search(domain, order='id asc') workorder.surface_technics_picking_count = len(picking_ids) workorder.picking_ids = picking_ids.ids diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index e225c274..3879860e 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -280,12 +280,13 @@ class RePurchaseOrder(models.Model): })) if server_product_process: - self.env['purchase.order'].sudo().create({ + purchase_order = self.env['purchase.order'].sudo().create({ 'partner_id': server_template.seller_ids[0].partner_id.id, 'origin': production.name, 'state': 'draft', 'purchase_type': 'consignment', 'order_line': server_product_process}) + consecutive_process_parameters.purchase_id = [(6, 0, [purchase_order.id])] # self.env.cr.commit() @api.onchange('order_line') From e260ef01f0788374b24eb82c8dd81ade7089112f Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Wed, 4 Dec 2024 11:43:02 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E9=9A=90=E8=97=8F=E9=94=80=E5=94=AE?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=9A=84=20=E5=BF=AB=E9=80=9F=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=20=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/views/quick_easy_order_view.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sf_sale/views/quick_easy_order_view.xml b/sf_sale/views/quick_easy_order_view.xml index 3b386062..89792a49 100644 --- a/sf_sale/views/quick_easy_order_view.xml +++ b/sf_sale/views/quick_easy_order_view.xml @@ -128,9 +128,9 @@ - + + + + \ No newline at end of file From 5b43cceb94d8bd1669cc956760a7fd70b50f9620 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Wed, 4 Dec 2024 11:56:38 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E8=AE=A1=E5=88=92=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E7=9A=84=E3=80=90=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95=E7=94=9F?= =?UTF-8?q?=E4=BA=A7=E8=AE=A1=E5=88=92=E3=80=91=E9=A1=B5=E9=9D=A2=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E5=90=8D=E7=A7=B0=E6=94=B9=E4=B8=BA=E3=80=90CNC?= =?UTF-8?q?=E4=BA=A7=E7=BA=BF=E8=AE=A1=E5=88=92=E6=8E=92=E7=A8=8B=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_plan/views/view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_plan/views/view.xml b/sf_plan/views/view.xml index fad3d779..47e1dd54 100644 --- a/sf_plan/views/view.xml +++ b/sf_plan/views/view.xml @@ -257,7 +257,7 @@ - 制造订单生产计划 + CNC产线计划排程 ir.actions.act_window sf.production.plan gantt,tree,form From 6366904c91e0312844553ae1332e4744c304dfac Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Wed, 4 Dec 2024 15:37:58 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AE=A2=E4=BE=9B?= =?UTF-8?q?=E6=96=99=E5=85=A5=E5=BA=93=E5=8D=95=E7=9A=84=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 0c01a57c..898bec06 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -957,7 +957,7 @@ class ReStockMove(models.Model): 合并制造订单的完成move单据 """ res = super(ReStockMove, self)._merge_moves_fields() - if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨', '生产入库']: + if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨', '生产入库', '客供料入库']: production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc') productions = self.env['mrp.production'].search( [('origin', '=', production.origin), ('product_id', '=', production.product_id.id)]) From 27ec5b1b74f02a3f6d803dee8930afd76ed48f95 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Wed, 4 Dec 2024 16:13:55 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E5=88=B6=E9=80=A0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E8=8F=9C=E5=8D=95=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/views/mrp_production_addional_change.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 5f9a7ef3..fd0a5ead 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -738,7 +738,7 @@ - Date: Wed, 4 Dec 2024 16:41:42 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E5=9D=AF=E6=96=99=E9=95=BF=E5=AE=BD?= =?UTF-8?q?=E9=AB=98=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 0750313b..cb8d37ee 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -23,12 +23,15 @@ class ResMrpWorkOrder(models.Model): product_tmpl_name = fields.Char('坯料产品名称', related='production_bom_id.bom_line_ids.product_id.name') - product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True, - string="坯料长度(mm)") - product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True, - string="坯料宽度(mm)") - product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True, - string="坯料高度(mm)") + product_tmpl_id_length = fields.Float(string='坯料长度(mm)', related='material_length', readonly=True, store=False) + product_tmpl_id_width = fields.Float(string='坯料宽度(mm)', related='material_width', readonly=True, store=False) + product_tmpl_id_height = fields.Float(string='坯料高度(mm)', related='material_height', readonly=True, store=False) + # product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True, + # string="坯料长度(mm)") + # product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True, + # string="坯料宽度(mm)") + # product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True, + # string="坯料高度(mm)") product_tmpl_id_materials_id = fields.Many2one(related='production_id.product_tmpl_id.materials_id', readonly=True, store=True, check_company=True, string="材料") product_tmpl_id_materials_type_id = fields.Many2one(related='production_id.product_tmpl_id.materials_type_id', From ef60f36c90d16263766203a536c43c9e25f678c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Wed, 4 Dec 2024 20:42:34 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=B7=A5=E8=89=BA?= =?UTF-8?q?=E5=A4=96=E5=8D=8F=E5=B7=A5=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 26 ++-- sf_manufacturing/models/mrp_workorder.py | 168 +++++++++++++--------- sf_manufacturing/models/stock.py | 88 ++++++------ sf_sale/views/quick_easy_order_view.xml | 4 +- 4 files changed, 163 insertions(+), 123 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 9156dc38..d1349671 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -721,6 +721,7 @@ class MrpProduction(models.Model): for product_id, pd in grouped_product_ids.items(): product_id_to_production_names[product_id] = [p.name for p in pd] for production in production_all: + proc_workorders = [] process_parameter_workorder = self.env['mrp.workorder'].search( [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id), ('is_subcontract', '=', True)], order='sequence asc') @@ -737,10 +738,11 @@ class MrpProduction(models.Model): else: # 处理连续组,如果它不为空 if consecutive_workorders: + proc_workorders.append(consecutive_workorders) # 创建外协出入库单和采购订单 - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) - self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, - product_id_to_production_names) + # self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production, sorted_workorders) + # self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, + # product_id_to_production_names) if i < len(sorted_workorders) - 1: # 重置连续组,并添加当前工作订单 consecutive_workorders = [workorder] @@ -751,18 +753,22 @@ class MrpProduction(models.Model): i - 1].supplier_id.id: consecutive_workorders = [workorder] else: + proc_workorders.append([workorder]) # 立即创建外协出入库单和采购订单 - self.env['stock.picking'].create_outcontract_picking(workorder, production) - self.env['purchase.order'].get_purchase_order(workorder, production, - product_id_to_production_names) + # self.env['stock.picking'].create_outcontract_picking(workorder, production) + # self.env['purchase.order'].get_purchase_order(workorder, production, + # product_id_to_production_names) consecutive_workorders = [] # 处理最后一个组,即使它可能只有一个工作订单 if consecutive_workorders: - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) - self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, - product_id_to_production_names) - + proc_workorders.append(consecutive_workorders) + # self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) + # self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, + # product_id_to_production_names) + for workorders in reversed(proc_workorders): + self.env['stock.picking'].create_outcontract_picking(workorders, production, sorted_workorders) + self.env['purchase.order'].get_purchase_order(workorders, production, product_id_to_production_names) # 工单排序 def _reset_work_order_sequence1(self, k): for rec in self: diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 7bd9d1c8..ee5a034b 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -313,14 +313,7 @@ class ResMrpWorkOrder(models.Model): # if technology_design.is_auto is False: # domain = [('origin', '=', self.production_id.name)] # else: - domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment')] - purchase_orders = self.env['purchase.order'].search(domain) - purchase_orders_id = None - for po in purchase_orders: - for line in po.order_line: - if line.product_id.server_product_process_parameters_id == self.surface_technics_parameters_id: - if line.product_qty == 1: - purchase_orders_id = line.order_id.id + purchase_orders_id = self._get_surface_technics_purchase_ids() result = { "type": "ir.actions.act_window", "res_model": "purchase.order", @@ -330,6 +323,17 @@ class ResMrpWorkOrder(models.Model): 'view_mode': 'form', } return result + + def _get_surface_technics_purchase_ids(self): + domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment')] + purchase_orders = self.env['purchase.order'].search(domain) + purchase_orders_id = None + for po in purchase_orders: + for line in po.order_line: + if line.product_id.server_product_process_parameters_id == self.surface_technics_parameters_id: + if line.product_qty == 1: + purchase_orders_id = line.order_id.id + return purchase_orders_id supplier_id = fields.Many2one('res.partner', string='外协供应商') equipment_id = fields.Many2one('maintenance.equipment', string='加工设备', tracking=True) @@ -1027,47 +1031,47 @@ class ResMrpWorkOrder(models.Model): 'production_id.programming_state') def _compute_state(self): # super()._compute_state() - for workorder in self: - if workorder.sequence != 1: - previous_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', workorder.production_id.id), - ('sequence', '=', workorder.sequence - 1)]) - if workorder.state == 'pending': - if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): - if workorder.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排': - if ((workorder.sequence == 1 and not workorder.blocked_by_workorder_ids) - or (workorder.blocked_by_workorder_ids.state in ('done', 'cancel') - and workorder.blocked_by_workorder_ids.test_results not in ['报废', '返工']) - or (previous_workorder.state in ('done', 'cancel') - and not workorder.blocked_by_workorder_ids - and previous_workorder.test_results not in ['报废', '返工']) - ): - workorder.state = 'ready' - continue - if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'): - if workorder.sequence != 1: - workorder.state = 'pending' - continue - if workorder.state not in ('waiting', 'ready'): - continue - if workorder.state in ( - 'waiting') and workorder.sequence == 1 and workorder.production_id.schedule_state == '已排': - workorder.state = 'ready' - continue - if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): - workorder.state = 'pending' - if workorder.state in ['waiting']: - if previous_workorder.state == 'waiting': - workorder.state = 'pending' - if workorder.sequence == 1 and workorder.state == 'pending': - workorder.state = 'waiting' - continue - if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'): - continue - if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting' and workorder.production_id.schedule_state == '已排': - workorder.state = 'ready' - elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready': - workorder.state = 'waiting' + # for workorder in self: + # if workorder.sequence != 1: + # previous_workorder = self.env['mrp.workorder'].search( + # [('production_id', '=', workorder.production_id.id), + # ('sequence', '=', workorder.sequence - 1)]) + # if workorder.state == 'pending': + # if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): + # if workorder.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排': + # if ((workorder.sequence == 1 and not workorder.blocked_by_workorder_ids) + # or (workorder.blocked_by_workorder_ids.state in ('done', 'cancel') + # and workorder.blocked_by_workorder_ids.test_results not in ['报废', '返工']) + # or (previous_workorder.state in ('done', 'cancel') + # and not workorder.blocked_by_workorder_ids + # and previous_workorder.test_results not in ['报废', '返工']) + # ): + # workorder.state = 'ready' + # continue + # if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'): + # if workorder.sequence != 1: + # workorder.state = 'pending' + # continue + # if workorder.state not in ('waiting', 'ready'): + # continue + # if workorder.state in ( + # 'waiting') and workorder.sequence == 1 and workorder.production_id.schedule_state == '已排': + # workorder.state = 'ready' + # continue + # if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): + # workorder.state = 'pending' + # if workorder.state in ['waiting']: + # if previous_workorder.state == 'waiting': + # workorder.state = 'pending' + # if workorder.sequence == 1 and workorder.state == 'pending': + # workorder.state = 'waiting' + # continue + # if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'): + # continue + # if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting' and workorder.production_id.schedule_state == '已排': + # workorder.state = 'ready' + # elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready': + # workorder.state = 'waiting' for workorder in self: # 如果工单的工序没有进行排序则跳出循环 @@ -1118,21 +1122,27 @@ class ResMrpWorkOrder(models.Model): if workorder.is_subcontract is False: workorder.state = 'ready' else: - production_programming = self.env['mrp.production'].search( - [('origin', '=', self.production_id.origin)], order='name asc') - production_no_remanufacture = production_programming.filtered( - lambda a: a.is_remanufacture is False) - production_list = [production.name for production in production_programming] - purchase_orders = self.env['purchase.order'].search( - [('origin', 'ilike', ','.join(production_list))]) - for line in purchase_orders.order_line: - if ( - line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id - and line.product_qty == len(production_no_remanufacture)): - if all(pur_order.state == 'purchase' for pur_order in purchase_orders): - workorder.state = 'ready' - else: - workorder.state = 'waiting' + # production_programming = self.env['mrp.production'].search( + # [('origin', '=', self.production_id.origin)], order='name asc') + # production_no_remanufacture = production_programming.filtered( + # lambda a: a.is_remanufacture is False) + # production_list = [production.name for production in production_programming] + # purchase_orders = self.env['purchase.order'].search( + # [('origin', 'ilike', ','.join(production_list))]) + # for line in purchase_orders.order_line: + # if ( + # line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id + # and line.product_qty == len(production_no_remanufacture)): + # if all(pur_order.state == 'purchase' for pur_order in purchase_orders): + # workorder.state = 'ready' + # else: + # workorder.state = 'waiting' + purchase_orders_id = self._get_surface_technics_purchase_ids() + if purchase_orders_id: + purchase_order = self.env['purchase.order'].browse(purchase_orders_id) + workorder.state = 'ready' if purchase_order.state == 'purchase' else 'waiting' + else: + workorder.state = 'waiting' # re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id), # ('processing_panel', '=', workorder.processing_panel), @@ -1241,12 +1251,13 @@ class ResMrpWorkOrder(models.Model): # 表面工艺外协出库单 if self.routing_type == '表面工艺': if self.is_subcontract is True: - move_out = self.env['stock.move'].search( - [('location_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), - ('location_dest_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'VL-SPOC')]).id), - ('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])]) + move_out = self.move_subcontract_workorder_ids[1] + # move_out = self.env['stock.move'].search( + # [('location_id', '=', self.env['stock.location'].search( + # [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), + # ('location_dest_id', '=', self.env['stock.location'].search( + # [('barcode', 'ilike', 'VL-SPOC')]).id), + # ('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])]) for mo in move_out: pick = self.env['stock.picking'].search([('id', '=', mo.picking_id.id), ('name', 'ilike', 'OCOUT'), ('partner_id', '=', self.supplier_id.id)]) @@ -1254,6 +1265,21 @@ class ResMrpWorkOrder(models.Model): if mo.state != 'done': mo.write({'state': 'assigned', 'production_id': False}) self.env['stock.move.line'].create(mo.get_move_line(self.production_id, self)) + product_qty = mo.product_uom._compute_quantity( + mo.product_uom_qty, mo.product_id.uom_id, rounding_method='HALF-UP') + available_quantity = self.env['stock.quant']._get_available_quantity( + mo.product_id, + mo.location_id, + lot_id=mo.move_line_ids.lot_id, + strict=False, + ) + mo._update_reserved_quantity( + product_qty, + available_quantity, + mo.location_id, + lot_id=mo.move_line_ids.lot_id, + strict=False, + ) # move_out._action_assign() if self.state == 'waiting' or self.state == 'ready' or self.state == 'progress': @@ -1526,6 +1552,8 @@ class ResMrpWorkOrder(models.Model): 'default_confirm_button': '确认解除', # 'default_feeder_station_start_id': feeder_station_start_id, }} + + move_subcontract_workorder_ids = fields.One2many('stock.move', 'subcontract_workorder_id', string='组件') class CNCprocessing(models.Model): diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 50c7e672..cfa35887 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -634,71 +634,74 @@ class StockPicking(models.Model): num = "%04d" % m return '%s%s' % (rescode, num) - def button_validate(self): - res = super().button_validate() - if res is True and self.picking_type_id.sequence_code == 'OCOUT': - # if self.id == move_out.picking_id.id: - # if move_out.move_line_ids.workorder_id.state == 'progress': - move_in = self.env['stock.move'].search( - [('location_dest_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), - ('location_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'VL-SPOC')]).id), - ('origin', '=', self.origin), ('state', 'not in', ['cancel', 'done'])]) - production = self.env['mrp.production'].search([('name', '=', self.origin)]) - for mi in move_in: - pick = self.env['stock.picking'].search([('id', '=', mi.picking_id.id), ('name', 'ilike', 'OCIN'), - ('partner_id', '=', self.partner_id.id)]) - # if pick: - # if mi.state != 'done': - # mi.write({'state': 'assigned'}) - # self.env['stock.move.line'].create(mi.get_move_line(production, None)) + # def button_validate(self): + # res = super().button_validate() + # if res is True and self.picking_type_id.sequence_code == 'OCOUT': + # # if self.id == move_out.picking_id.id: + # # if move_out.move_line_ids.workorder_id.state == 'progress': + # move_in = self.env['stock.move'].search( + # [('location_dest_id', '=', self.env['stock.location'].search( + # [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), + # ('location_id', '=', self.env['stock.location'].search( + # [('barcode', 'ilike', 'VL-SPOC')]).id), + # ('origin', '=', self.origin), ('state', 'not in', ['cancel', 'done'])]) + # production = self.env['mrp.production'].search([('name', '=', self.origin)]) + # for mi in move_in: + # pick = self.env['stock.picking'].search([('id', '=', mi.picking_id.id), ('name', 'ilike', 'OCIN'), + # ('partner_id', '=', self.partner_id.id)]) + # if pick: + # if mi.state != 'done': + # mi.write({'state': 'assigned'}) + # self.env['stock.move.line'].create(mi.get_move_line(production, None)) - return res + # return res # 创建 外协出库入单 - def create_outcontract_picking(self, sorted_workorders_arr, item): + def create_outcontract_picking(self, workorders, item, sorted_workorders): domain = [('origin', '=', item.name), ('name', 'ilike', 'OCOUT')] - if len(sorted_workorders_arr) > 1: - sorted_workorders_arr = sorted_workorders_arr[0] + if len(workorders) > 1: + workorders = workorders[0] else: domain += [ - ('surface_technics_parameters_id', '=', sorted_workorders_arr[0].surface_technics_parameters_id.id)] + ('surface_technics_parameters_id', '=', workorders[0].surface_technics_parameters_id.id)] stock_picking = self.env['stock.picking'].search(domain) if not stock_picking: - for sorted_workorders in sorted_workorders_arr: + for workorder in workorders: # pick_ids = [] - if not sorted_workorders.picking_ids: + if not workorder.picking_ids: # outcontract_stock_move = self.env['stock.move'].search([('production_id', '=', item.id)]) # if not outcontract_stock_move: # 创建一个新的补货组 procurement_group_id = self.env['procurement.group'].create({ - 'name': sorted_workorders.name, + 'name': workorder.name, 'partner_id': self.partner_id.id, }) + move_dest_id = False + # 如果当前工单是制造订单的最后一个工单 + # if workorder == item.workorder_ids[-1]: + # # 找到制造订单对应的move + # move_dest_id = item.move_raw_ids[0].move_orig_ids[0].id + # else: + # # 从sorted_workorders中找到上一工单的move + # move_dest_id = sorted_workorders[sorted_workorders.index(workorder) - 1].move_subcontract_workorder_ids[1].id new_picking = True - location_id = self.env['stock.location'].search( - [('barcode', 'ilike', 'VL-SPOC')]).id, - location_dest_id = self.env['stock.location'].search( - [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id, outcontract_picking_type_in = self.env.ref( 'sf_manufacturing.outcontract_picking_in').id, outcontract_picking_type_out = self.env.ref( 'sf_manufacturing.outcontract_picking_out').id, moves_in = self.env['stock.move'].sudo().create( - self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id, - outcontract_picking_type_in, procurement_group_id.id)) + self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_in, procurement_group_id.id, move_dest_id)) picking_in = self.create( - moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/')) + moves_in._get_new_picking_values_Res(item, workorder, 'WH/OCIN/')) # pick_ids.append(picking_in.id) moves_in.write( {'picking_id': picking_in.id, 'state': 'waiting'}) moves_in._assign_picking_post_process(new=new_picking) moves_out = self.env['stock.move'].sudo().create( - self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id, - outcontract_picking_type_out, procurement_group_id.id, moves_in.id)) + self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_out, procurement_group_id.id, moves_in.id)) + workorder.write({'move_subcontract_workorder_ids': [(6, 0, [moves_in.id, moves_out.id])]}) picking_out = self.create( - moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/')) + moves_out._get_new_picking_values_Res(item, workorder, 'WH/OCOUT/')) # pick_ids.append(picking_out.id) moves_out.write( {'picking_id': picking_out.id, 'state': 'waiting'}) @@ -713,16 +716,17 @@ class ReStockMove(models.Model): materiel_width = fields.Float(string='物料宽度', digits=(16, 4)) materiel_height = fields.Float(string='物料高度', digits=(16, 4)) - def _get_stock_move_values_Res(self, item, location_src_id, location_dest_id, picking_type_id, group_id, move_dest_ids=False): - route = self.env['stock.route'].sudo().search([('name', '=', '表面工艺外协')]) + def _get_stock_move_values_Res(self, item, picking_type_id, group_id, move_dest_ids=False): + route_id = self.env.ref('sf_manufacturing.route_surface_technology_outsourcing').id + stock_rule = self.env['stock.rule'].sudo().search([('route_id', '=', route_id), ('picking_type_id', '=', picking_type_id)]) move_values = { 'name': '推', 'company_id': item.company_id.id, 'product_id': item.bom_id.bom_line_ids.product_id.id, 'product_uom': item.bom_id.bom_line_ids.product_uom_id.id, 'product_uom_qty': 1.0, - 'location_id': location_src_id, - 'location_dest_id': location_dest_id, + 'location_id': stock_rule.location_src_id.id, + 'location_dest_id': stock_rule.location_dest_id.id, 'origin': item.name, 'group_id': group_id, 'move_dest_ids': [(6, 0, [move_dest_ids])] if move_dest_ids else False, @@ -991,6 +995,8 @@ class ReStockMove(models.Model): res['origin'] = ','.join(productions.mapped('name')) res['retrospect_ref'] = production.product_id.name return res + + subcontract_workorder_id = fields.Many2one('mrp.workorder', '外协工单组件', check_company=True, index='btree_not_null') class ReStockQuant(models.Model): diff --git a/sf_sale/views/quick_easy_order_view.xml b/sf_sale/views/quick_easy_order_view.xml index 3b386062..e0fa6dbd 100644 --- a/sf_sale/views/quick_easy_order_view.xml +++ b/sf_sale/views/quick_easy_order_view.xml @@ -128,9 +128,9 @@ - + groups="sales_team.group_sale_salesman,sf_base.group_sale_salemanager,sf_base.group_sale_director"/> --> \ No newline at end of file From 5f12976d8f78f7c0a4ce500ca85b2602c22aa57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Thu, 5 Dec 2024 01:33:46 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A1=A8=E9=9D=A2?= =?UTF-8?q?=E5=B7=A5=E8=89=BA=E5=A4=96=E5=8D=8F=E5=B7=A5=E5=8D=95=E6=B5=81?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 59 +++++++++++---------- sf_manufacturing/models/stock.py | 66 +++++++++++++----------- 2 files changed, 69 insertions(+), 56 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index ee5a034b..35238598 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -317,7 +317,7 @@ class ResMrpWorkOrder(models.Model): result = { "type": "ir.actions.act_window", "res_model": "purchase.order", - "res_id": purchase_orders_id, + "res_id": purchase_orders_id.id, # "domain": [['id', 'in', self.purchase_id]], "name": _("Purchase Orders"), 'view_mode': 'form', @@ -332,7 +332,7 @@ class ResMrpWorkOrder(models.Model): for line in po.order_line: if line.product_id.server_product_process_parameters_id == self.surface_technics_parameters_id: if line.product_qty == 1: - purchase_orders_id = line.order_id.id + purchase_orders_id = line.order_id return purchase_orders_id supplier_id = fields.Many2one('res.partner', string='外协供应商') @@ -1139,8 +1139,7 @@ class ResMrpWorkOrder(models.Model): # workorder.state = 'waiting' purchase_orders_id = self._get_surface_technics_purchase_ids() if purchase_orders_id: - purchase_order = self.env['purchase.order'].browse(purchase_orders_id) - workorder.state = 'ready' if purchase_order.state == 'purchase' else 'waiting' + workorder.state = 'ready' if purchase_orders_id.state == 'purchase' else 'waiting' else: workorder.state = 'waiting' @@ -1205,6 +1204,10 @@ class ResMrpWorkOrder(models.Model): # 重写工单开始按钮方法 def button_start(self): + # 判断工单状态是否为等待组件 + if self.state in ['waiting', 'pending']: + raise UserError('制造订单【%s】缺少组件信息!' % self.production_id.name) + if self.routing_type == 'CNC加工': self.env['sf.production.plan'].sudo().search([('name', '=', self.production_id.name)]).write({ 'state': 'processing', @@ -1212,9 +1215,6 @@ class ResMrpWorkOrder(models.Model): }) if self.sequence == 1: - # 判断工单状态是否为等待组件 - if self.state == 'waiting': - raise UserError('制造订单【%s】缺少组件信息!' % self.production_id.name) # 判断是否有坯料的序列号信息 boolean = False if self.production_id.move_raw_ids: @@ -1259,27 +1259,25 @@ class ResMrpWorkOrder(models.Model): # [('barcode', 'ilike', 'VL-SPOC')]).id), # ('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])]) for mo in move_out: - pick = self.env['stock.picking'].search([('id', '=', mo.picking_id.id), ('name', 'ilike', 'OCOUT'), - ('partner_id', '=', self.supplier_id.id)]) - if pick: - if mo.state != 'done': - mo.write({'state': 'assigned', 'production_id': False}) + if mo.state != 'done': + mo.write({'state': 'assigned', 'production_id': False}) + if not mo.move_line_ids: self.env['stock.move.line'].create(mo.get_move_line(self.production_id, self)) - product_qty = mo.product_uom._compute_quantity( - mo.product_uom_qty, mo.product_id.uom_id, rounding_method='HALF-UP') - available_quantity = self.env['stock.quant']._get_available_quantity( - mo.product_id, - mo.location_id, - lot_id=mo.move_line_ids.lot_id, - strict=False, - ) - mo._update_reserved_quantity( - product_qty, - available_quantity, - mo.location_id, - lot_id=mo.move_line_ids.lot_id, - strict=False, - ) + # product_qty = mo.product_uom._compute_quantity( + # mo.product_uom_qty, mo.product_id.uom_id, rounding_method='HALF-UP') + # available_quantity = self.env['stock.quant']._get_available_quantity( + # mo.product_id, + # mo.location_id, + # lot_id=mo.move_line_ids.lot_id, + # strict=False, + # ) + # mo._update_reserved_quantity( + # product_qty, + # available_quantity, + # mo.location_id, + # lot_id=mo.move_line_ids.lot_id, + # strict=False, + # ) # move_out._action_assign() if self.state == 'waiting' or self.state == 'ready' or self.state == 'progress': @@ -1384,6 +1382,13 @@ class ResMrpWorkOrder(models.Model): picks = record.picking_ids.filtered(lambda p: p.state not in ('done')) if picks: raise UserError('请先完成该工单的工艺外协再进行操作') + # 表面工艺外协,最后一张工单 + workorders = self.production_id.workorder_ids + subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence') + if self == subcontract_workorders[-1]: + # 给下一个库存移动就绪 + self.move_subcontract_workorder_ids[0].move_dest_ids._action_done() + # self.production_id.button_mark_done() tem_date_planned_finished = record.date_planned_finished tem_date_finished = record.date_finished logging.info('routing_type:%s' % record.routing_type) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index cfa35887..45d90bb8 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -634,27 +634,23 @@ class StockPicking(models.Model): num = "%04d" % m return '%s%s' % (rescode, num) - # def button_validate(self): - # res = super().button_validate() - # if res is True and self.picking_type_id.sequence_code == 'OCOUT': - # # if self.id == move_out.picking_id.id: - # # if move_out.move_line_ids.workorder_id.state == 'progress': - # move_in = self.env['stock.move'].search( - # [('location_dest_id', '=', self.env['stock.location'].search( - # [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), - # ('location_id', '=', self.env['stock.location'].search( - # [('barcode', 'ilike', 'VL-SPOC')]).id), - # ('origin', '=', self.origin), ('state', 'not in', ['cancel', 'done'])]) - # production = self.env['mrp.production'].search([('name', '=', self.origin)]) - # for mi in move_in: - # pick = self.env['stock.picking'].search([('id', '=', mi.picking_id.id), ('name', 'ilike', 'OCIN'), - # ('partner_id', '=', self.partner_id.id)]) - # if pick: - # if mi.state != 'done': - # mi.write({'state': 'assigned'}) - # self.env['stock.move.line'].create(mi.get_move_line(production, None)) - - # return res + def button_validate(self): + res = super().button_validate() + picking_type_in = self.env.ref('sf_manufacturing.outcontract_picking_in').id + if res is True and self.picking_type_id.id == picking_type_in: + # 如果是最后一张外协入库单,则设置库存位置的预留数量 + move_in = self.move_ids + if move_in: + workorder = move_in.subcontract_workorder_id + workorders = workorder.production_id.workorder_ids + subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence') + if workorder == subcontract_workorders[-1]: + self.env['stock.quant']._update_reserved_quantity( + move_in.product_id, move_in.location_dest_id, move_in.product_uom_qty, lot_id=move_in.move_line_ids.lot_id, + package_id=False, owner_id=False, strict=False + ) + + return res # 创建 外协出库入单 def create_outcontract_picking(self, workorders, item, sorted_workorders): @@ -677,13 +673,12 @@ class StockPicking(models.Model): 'partner_id': self.partner_id.id, }) move_dest_id = False - # 如果当前工单是制造订单的最后一个工单 - # if workorder == item.workorder_ids[-1]: - # # 找到制造订单对应的move - # move_dest_id = item.move_raw_ids[0].move_orig_ids[0].id - # else: - # # 从sorted_workorders中找到上一工单的move - # move_dest_id = sorted_workorders[sorted_workorders.index(workorder) - 1].move_subcontract_workorder_ids[1].id + # 如果当前工单是是制造订单的最后一个工单 + if workorder == item.workorder_ids[-1]: + move_dest_id = item.move_raw_ids[0].id + else: + # 从sorted_workorders中找到上一工单的move + move_dest_id = sorted_workorders[sorted_workorders.index(workorder) - 1].move_subcontract_workorder_ids[1].id new_picking = True outcontract_picking_type_in = self.env.ref( 'sf_manufacturing.outcontract_picking_in').id, @@ -706,7 +701,20 @@ class StockPicking(models.Model): moves_out.write( {'picking_id': picking_out.id, 'state': 'waiting'}) moves_out._assign_picking_post_process(new=new_picking) + return moves_in, moves_out + @api.depends('move_type', 'immediate_transfer', 'move_ids.state', 'move_ids.picking_id') + def _compute_state(self): + super(StockPicking, self)._compute_state() + for picking in self: + # 外协出库单根据工单状态,采购单状态来确定 + picking_type_id = self.env.ref('sf_manufacturing.outcontract_picking_out').id + if picking.picking_type_id.id == picking_type_id: + if picking.move_ids: + workorder = picking.move_ids[0].subcontract_workorder_id + if picking.state == 'assigned': + if workorder.state in ['pending', 'waiting'] or workorder._get_surface_technics_purchase_ids().state in ['draft', 'sent']: + picking.state = 'waiting' class ReStockMove(models.Model): @@ -753,7 +761,7 @@ class ReStockMove(models.Model): 'picking_type_id': picking_type_id, 'location_id': self.mapped('location_id').id, 'location_dest_id': self.mapped('location_dest_id').id, - 'state': 'confirmed', + 'state': 'waiting', } def get_move_line(self, production_id, sorted_workorders): From e011e4cfd60be272f7f753d70644be4543a61f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=83=A1=E5=B0=A7?= Date: Thu, 5 Dec 2024 09:31:06 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E8=A1=A8=E9=9D=A2?= =?UTF-8?q?=E5=B7=A5=E8=89=BA=E5=B7=A5=E5=8D=95=E5=AE=8C=E6=88=90=E5=90=8E?= =?UTF-8?q?=EF=BC=8C=E7=94=9F=E4=BA=A7=E5=85=A5=E5=BA=93=E5=8D=95=E6=9C=AA?= =?UTF-8?q?=E5=B0=B1=E7=BB=AA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 14 +++++++------- sf_sale/models/sale_order.py | 16 ++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 4967b32d..24bad9e7 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1433,13 +1433,13 @@ class ResMrpWorkOrder(models.Model): move_raw_id.quantity_done = move_raw_id.product_uom_qty record.process_state = '已完工' record.production_id.process_state = '已完工' - if record.routing_type in ['表面工艺']: - raw_move = self.env['stock.move'].sudo().search( - [('origin', '=', record.production_id.name), - ('procure_method', 'in', ['make_to_order', 'make_to_stock']), - ('state', '!=', 'done')]) - if raw_move: - raw_move.write({'state': 'done'}) + # if record.routing_type in ['表面工艺']: + # raw_move = self.env['stock.move'].sudo().search( + # [('origin', '=', record.production_id.name), + # ('procure_method', 'in', ['make_to_order', 'make_to_stock']), + # ('state', '!=', 'done')]) + # if raw_move: + # raw_move.write({'state': 'done'}) record.production_id.button_mark_done1() # record.production_id.state = 'done' diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index 3879860e..6a1d3023 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -279,14 +279,14 @@ class RePurchaseOrder(models.Model): 'product_uom': server_template.uom_id.id })) - if server_product_process: - purchase_order = self.env['purchase.order'].sudo().create({ - 'partner_id': server_template.seller_ids[0].partner_id.id, - 'origin': production.name, - 'state': 'draft', - 'purchase_type': 'consignment', - 'order_line': server_product_process}) - consecutive_process_parameters.purchase_id = [(6, 0, [purchase_order.id])] + if server_product_process: + purchase_order = self.env['purchase.order'].sudo().create({ + 'partner_id': server_template.seller_ids[0].partner_id.id, + 'origin': production.name, + 'state': 'draft', + 'purchase_type': 'consignment', + 'order_line': server_product_process}) + pp.purchase_id = [(6, 0, [purchase_order.id])] # self.env.cr.commit() @api.onchange('order_line')