From 83e57b63ec2e50c5dad4bdca7b365b493eb5197d Mon Sep 17 00:00:00 2001 From: guanhuan Date: Tue, 10 Dec 2024 17:18:33 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=8A=A5=E5=BA=9F=E6=96=B0=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=9A=84=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95=E6=B2=A1?= =?UTF-8?q?=E5=85=B3=E8=81=94=E6=96=B0=E9=87=87=E8=B4=AD=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index f11a32ac..77b23e0a 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -1495,7 +1495,9 @@ class MrpProduction(models.Model): def action_view_purchase_orders(self): self.ensure_one() - if self.product_id.product_tmpl_id.single_manufacturing == True: + if self.is_remanufacture: + production = self + elif self.product_id.product_tmpl_id.single_manufacturing == True: production = self.env['mrp.production'].search( [('origin', '=', self.origin), ('product_id', '=', self.product_id.id)], limit=1, order='id asc') else: From c793089131da0f628d094b861d4dfc58809d83d9 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Thu, 12 Dec 2024 09:29:48 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=B7=A5=E8=89=BA=E7=A1=AE=E8=AE=A4?= =?UTF-8?q?=E5=BC=B9=E6=A1=86=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 85 ++++++++++++++----- ...tion_technology_re_adjust_wizard_views.xml | 20 +++++ .../production_technology_wizard_views.xml | 25 +++++- 3 files changed, 107 insertions(+), 23 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 77b23e0a..6643bfb1 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -378,16 +378,37 @@ class MrpProduction(models.Model): if process_parameters: raise UserError(_("【工艺设计】-【参数】为%s的在【产品】中不存在,请先创建", ", ".join(process_parameters))) if production_confirmed: - return { - 'name': _('退回调整'), - 'type': 'ir.actions.act_window', - 'view_mode': 'form', - 'res_model': 'sf.production.technology.re_adjust.wizard', - 'target': 'new', - 'context': { - 'default_production_id': self.id, - 'default_origin': self.origin, - }} + production_count = self.env['mrp.production'].search_count([ + ('origin', '=', self.origin), + ('product_id', '=', self.product_id.id), + ('state', '=', 'confirmed') + ]) + if production_count > 1: + return { + 'name': _('退回调整'), + 'type': 'ir.actions.act_window', + 'views': [(self.env.ref( + 'sf_manufacturing.sf_production_technology_re_adjust_wizard_form_view').id, + 'form')], + 'res_model': 'sf.production.technology.re_adjust.wizard', + 'target': 'new', + 'context': { + 'default_production_id': self.id, + 'default_origin': self.origin, + }} + else: + return { + 'name': _('退回调整'), + 'type': 'ir.actions.act_window', + 'views': [(self.env.ref( + 'sf_manufacturing.sf_production_technology_re_adjust_wizard_confirm_form_view').id, + 'form')], + 'res_model': 'sf.production.technology.re_adjust.wizard', + 'target': 'new', + 'context': { + 'default_production_id': self.id, + 'default_origin': self.origin, + }} # 工艺确认 def technology_confirm(self): @@ -441,16 +462,37 @@ class MrpProduction(models.Model): error_panel.append(design.panel) else: if not error_panel and not process_parameters: - 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, - }} + production_count = self.env['mrp.production'].search_count([ + ('origin', '=', self.origin), + ('product_id', '=', self.product_id.id), + ('state', '=', 'technology_to_confirmed') + ]) + if production_count > 1: + return { + 'name': _('工艺确认'), + 'type': 'ir.actions.act_window', + 'views': [(self.env.ref( + 'sf_manufacturing.sf_production_technology_wizard_form_view').id, + 'form')], + 'res_model': 'sf.production.technology.wizard', + 'target': 'new', + 'context': { + 'default_production_id': self.id, + 'default_origin': self.origin, + }} + else: + return { + 'name': _('工艺确认'), + 'type': 'ir.actions.act_window', + 'views': [(self.env.ref( + 'sf_manufacturing.sf_production_technology_wizard_confirm_form_view').id, + '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 @@ -762,7 +804,7 @@ class MrpProduction(models.Model): # 立即创建外协出入库单和采购订单 # self.env['stock.picking'].create_outcontract_picking(workorder, production) # self.env['purchase.order'].get_purchase_order(workorder, production, - # product_id_to_production_names) + # product_id_to_production_names) consecutive_workorders = [] # 处理最后一个组,即使它可能只有一个工作订单 @@ -774,6 +816,7 @@ class MrpProduction(models.Model): 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/wizard/production_technology_re_adjust_wizard_views.xml b/sf_manufacturing/wizard/production_technology_re_adjust_wizard_views.xml index 48346cb2..4ab7fc86 100644 --- a/sf_manufacturing/wizard/production_technology_re_adjust_wizard_views.xml +++ b/sf_manufacturing/wizard/production_technology_re_adjust_wizard_views.xml @@ -21,6 +21,26 @@ + + sf.production.technology.re_adjust.wizard.form.view + sf.production.technology.re_adjust.wizard + +
+ + + +
+ 是否确认退回调整 +
+
+
+
+
+
+
+ 工艺退回调整 sf.production.technology.re_adjust.wizard diff --git a/sf_manufacturing/wizard/production_technology_wizard_views.xml b/sf_manufacturing/wizard/production_technology_wizard_views.xml index 134fb8a9..8706ef83 100644 --- a/sf_manufacturing/wizard/production_technology_wizard_views.xml +++ b/sf_manufacturing/wizard/production_technology_wizard_views.xml @@ -1,6 +1,6 @@ - + sf.production.technology.wizard.form.view sf.production.technology.wizard @@ -13,7 +13,28 @@ 对当前制造订单,同一销售订单相同产品所生成的制造订单统一进行工艺调整与确认
-
+ + +
+
+ + + sf.production.technology.wizard.form.view + sf.production.technology.wizard + +
+ + + +
+ 是否确认工艺调整 +
+
+
From 01fa7bbe87380541817423d6a4bc47a17c376412 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Thu, 12 Dec 2024 14:39:10 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=89=B9=E9=87=8F=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E5=AE=89=E6=8E=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/__manifest__.py | 2 + sf_manufacturing/security/ir.model.access.csv | 2 + .../views/mrp_workorder_batch_replan.xml | 17 ++++++++ sf_manufacturing/wizard/__init__.py | 1 + .../mrp_workorder_batch_replan_wizard.py | 42 +++++++++++++++++++ ...rp_workorder_batch_replan_wizard_views.xml | 32 ++++++++++++++ 6 files changed, 96 insertions(+) create mode 100644 sf_manufacturing/views/mrp_workorder_batch_replan.xml create mode 100644 sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard.py create mode 100644 sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard_views.xml diff --git a/sf_manufacturing/__manifest__.py b/sf_manufacturing/__manifest__.py index 991b26ab..612577c2 100644 --- a/sf_manufacturing/__manifest__.py +++ b/sf_manufacturing/__manifest__.py @@ -24,6 +24,7 @@ 'wizard/production_wizard_views.xml', 'wizard/production_technology_wizard_views.xml', 'wizard/production_technology_re_adjust_wizard_views.xml', + 'wizard/mrp_workorder_batch_replan_wizard_views.xml', 'views/mrp_views_menus.xml', 'views/agv_scheduling_views.xml', 'views/stock_lot_views.xml', @@ -38,6 +39,7 @@ 'views/sf_maintenance_equipment.xml', 'views/res_config_settings_views.xml', 'views/sale_order_views.xml', + 'views/mrp_workorder_batch_replan.xml', ], 'assets': { diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv index 2880e662..f096b449 100644 --- a/sf_manufacturing/security/ir.model.access.csv +++ b/sf_manufacturing/security/ir.model.access.csv @@ -182,3 +182,5 @@ access_sf_manual_product_model_type_routing_sort_group_sf_mrp_user,sf_manual_pro access_sf_manual_product_model_type_routing_sort_manager,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1 access_sf_manual_product_model_type_routing_sort_group_plan_dispatch,sf_manual_product_model_type_routing_sort_group_plan_dispatch,model_sf_manual_product_model_type_routing_sort,sf_base.group_plan_dispatch,1,0,0,0 access_sf_detection_result_manager,sf_detection_result_manager,model_sf_detection_result,,1,1,1,1 + +access_mrp_workorder_batch_replan_wizard_group_plan_dispatch,mrp_workorder_batch_replan_wizard_group_plan_dispatch,model_mrp_workorder_batch_replan_wizard,sf_base.group_plan_dispatch,1,1,1,0 \ No newline at end of file diff --git a/sf_manufacturing/views/mrp_workorder_batch_replan.xml b/sf_manufacturing/views/mrp_workorder_batch_replan.xml new file mode 100644 index 00000000..a09b1a0e --- /dev/null +++ b/sf_manufacturing/views/mrp_workorder_batch_replan.xml @@ -0,0 +1,17 @@ + + + + >mrp.workorder.tree.editable.inherit + mrp.workorder + + + +
+
+
+
+
+
+
\ No newline at end of file diff --git a/sf_manufacturing/wizard/__init__.py b/sf_manufacturing/wizard/__init__.py index e2206a5f..89bdc09b 100644 --- a/sf_manufacturing/wizard/__init__.py +++ b/sf_manufacturing/wizard/__init__.py @@ -3,3 +3,4 @@ from . import rework_wizard from . import production_wizard from . import production_technology_wizard from . import production_technology_re_adjust_wizard +from . import mrp_workorder_batch_replan_wizard diff --git a/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard.py b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard.py new file mode 100644 index 00000000..f9511040 --- /dev/null +++ b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +import logging +from datetime import datetime, timedelta +from odoo import models, api, fields, _ + + +class MrpWorkorderBatchReplanWizard(models.TransientModel): + _name = 'mrp.workorder.batch.replan.wizard' + _description = '制造订单批量重新安排向导' + + def _get_date_planned_start(self): + planned_start_date = datetime.now() + timedelta(hours=2) + logging.info('计划开始加工时间: %s', planned_start_date) + return planned_start_date + + def _get_default_workorder_count(self): + active_ids = self.env.context.get('active_ids', []) + return len(active_ids) + + def _get_default_workorder_type(self): + active_ids = self.env.context.get('active_ids', []) + if active_ids: + workorders = self.env['mrp.workorder'].browse(active_ids) + if workorders: + unique_types = set(workorders.mapped('type')) + return '/'.join(sorted(unique_types)) if unique_types else None + return None + + workorder_type = fields.Char(string='工单类型', default=_get_default_workorder_type, readonly=True) + + date_planned_start = fields.Datetime(string='计划开始加工时间', index=True, copy=False, + default=_get_date_planned_start) + + workorder_count = fields.Integer(string='工单数量', + default=_get_default_workorder_count, + readonly=True) + + workorder_id = fields.Many2many('mrp.workorder', string=u'工单') + + def confirm(self): + print("ddd") + pass diff --git a/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard_views.xml b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard_views.xml new file mode 100644 index 00000000..e004cd6e --- /dev/null +++ b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard_views.xml @@ -0,0 +1,32 @@ + + + + mrp.workorder.batch.replan.wizard.form.view + mrp.workorder.batch.replan.wizard + + + + + + + +
+
+ +
+
+ + + + 重新安排 + ir.actions.act_window + mrp.workorder.batch.replan.wizard + form + + new + {'default_workorder_id': active_ids} + + +
\ No newline at end of file From b551777d49452f88aef71159c02468c3786e11c5 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Fri, 13 Dec 2024 16:24:25 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E9=80=BE=E6=9C=9F=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E6=89=B9=E9=87=8F=E9=87=8D=E6=96=B0=E5=AE=89?= =?UTF-8?q?=E6=8E=92=E7=9A=84=E4=BC=98=E5=8C=96=E9=9C=80=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/mrp_workorder_batch_replan.xml | 3 +- .../mrp_workorder_batch_replan_wizard.py | 42 +++++++++++++++---- ...rp_workorder_batch_replan_wizard_views.xml | 3 +- .../views/mrp_workcenter_views.xml | 2 +- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/sf_manufacturing/views/mrp_workorder_batch_replan.xml b/sf_manufacturing/views/mrp_workorder_batch_replan.xml index a09b1a0e..972d77c7 100644 --- a/sf_manufacturing/views/mrp_workorder_batch_replan.xml +++ b/sf_manufacturing/views/mrp_workorder_batch_replan.xml @@ -8,7 +8,8 @@
diff --git a/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard.py b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard.py index f9511040..5f5d5261 100644 --- a/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard.py +++ b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard.py @@ -22,15 +22,12 @@ class MrpWorkorderBatchReplanWizard(models.TransientModel): if active_ids: workorders = self.env['mrp.workorder'].browse(active_ids) if workorders: - unique_types = set(workorders.mapped('type')) - return '/'.join(sorted(unique_types)) if unique_types else None + routing_type = set(workorders.mapped('routing_type')) + return '/'.join(sorted(routing_type)) if routing_type else None return None workorder_type = fields.Char(string='工单类型', default=_get_default_workorder_type, readonly=True) - date_planned_start = fields.Datetime(string='计划开始加工时间', index=True, copy=False, - default=_get_date_planned_start) - workorder_count = fields.Integer(string='工单数量', default=_get_default_workorder_count, readonly=True) @@ -38,5 +35,36 @@ class MrpWorkorderBatchReplanWizard(models.TransientModel): workorder_id = fields.Many2many('mrp.workorder', string=u'工单') def confirm(self): - print("ddd") - pass + routing_type = set(self.workorder_id.mapped('routing_type')) + if len(routing_type) > 1: + raise models.ValidationError("批量重新安排工单类型必须一致。") + show_json_popover = self.workorder_id.mapped('show_json_popover') + if any(not value for value in show_json_popover): + raise models.ValidationError("所选工单必须都为逾期状态") + failed_workorders = {} + for workorder_info in self.workorder_id: + try: + workorder_info.action_replan() + except Exception as e: + reason = str(e) + if reason in failed_workorders: + failed_workorders[reason].append( + workorder_info.production_id.name) + else: + failed_workorders[reason] = [workorder_info.production_id.name] + if failed_workorders: + error_messages = "\n".join( + [f"制造订单: {', '.join(workorder_names)}, 原因: {reason}" for reason, workorder_names in + failed_workorders.items()]) + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'message': f"以下工单重新安排失败:\n{error_messages}", + 'sticky': False, + 'color': 'red', + 'next': { + 'type': 'ir.actions.act_window_close' + } + }, + } diff --git a/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard_views.xml b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard_views.xml index e004cd6e..37d26ac7 100644 --- a/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard_views.xml +++ b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard_views.xml @@ -7,7 +7,6 @@
-