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/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py
index 0ba4d5cc..7bfc0abb 100644
--- a/sf_manufacturing/models/mrp_production.py
+++ b/sf_manufacturing/models/mrp_production.py
@@ -403,16 +403,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):
@@ -466,16 +487,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
@@ -1543,7 +1585,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:
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..972d77c7
--- /dev/null
+++ b/sf_manufacturing/views/mrp_workorder_batch_replan.xml
@@ -0,0 +1,18 @@
+
+
+
+ >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..5f5d5261
--- /dev/null
+++ b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard.py
@@ -0,0 +1,70 @@
+# -*- 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:
+ 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)
+
+ workorder_count = fields.Integer(string='工单数量',
+ default=_get_default_workorder_count,
+ readonly=True)
+
+ workorder_id = fields.Many2many('mrp.workorder', string=u'工单')
+
+ def confirm(self):
+ 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
new file mode 100644
index 00000000..37d26ac7
--- /dev/null
+++ b/sf_manufacturing/wizard/mrp_workorder_batch_replan_wizard_views.xml
@@ -0,0 +1,31 @@
+
+
+
+ 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
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
+
+