From 07c07ef37c78048d20fdb4978250240a27434cf9 Mon Sep 17 00:00:00 2001
From: mgw <1392924357@qq.com>
Date: Thu, 27 Feb 2025 16:00:29 +0800
Subject: [PATCH 1/5] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=B8=8B=E6=B8=B8?=
=?UTF-8?q?=E5=8D=95=E6=8D=AE=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/security/ir.model.access.csv | 4 +-
sf_manufacturing/wizard/sale_order_cancel.py | 311 ++++++++++++------
.../wizard/sale_order_cancel_views.xml | 27 ++
3 files changed, 233 insertions(+), 109 deletions(-)
diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv
index 246cce63..6661c9be 100644
--- a/sf_manufacturing/security/ir.model.access.csv
+++ b/sf_manufacturing/security/ir.model.access.csv
@@ -192,5 +192,5 @@ access_sf_programming_reason,sf_programming_reason,model_sf_programming_reason,b
access_sf_programming_record,sf_programming_record,model_sf_programming_record,base.group_user,1,1,1,0
access_sf_work_individuation_page,sf_work_individuation_page,model_sf_work_individuation_page,sf_base.group_sf_mrp_user,1,1,1,0
access_sf_work_individuation_page_group_plan_dispatch,sf_work_individuation_page_group_plan_dispatch,model_sf_work_individuation_page,sf_base.group_plan_dispatch,1,1,0,0
-access_sf_sale_order_cancel_wizard,sf_sale_order_cancel_wizard,model_sf_sale_order_cancel_wizard,sf_base.group_sf_order_user,1,1,1,0
-access_sf_sale_order_cancel_line,sf_sale_order_cancel_line,model_sf_sale_order_cancel_line,sf_base.group_sf_order_user,1,1,1,0
\ No newline at end of file
+access_sf_sale_order_cancel_wizard,sf_sale_order_cancel_wizard,model_sf_sale_order_cancel_wizard,sf_base.group_sf_order_user,1,0,1,0
+access_sf_sale_order_cancel_line,sf_sale_order_cancel_line,model_sf_sale_order_cancel_line,sf_base.group_sf_order_user,1,0,1,0
\ No newline at end of file
diff --git a/sf_manufacturing/wizard/sale_order_cancel.py b/sf_manufacturing/wizard/sale_order_cancel.py
index c726d5d6..1f7cf306 100644
--- a/sf_manufacturing/wizard/sale_order_cancel.py
+++ b/sf_manufacturing/wizard/sale_order_cancel.py
@@ -209,29 +209,169 @@ class SFSaleOrderCancelLine(models.TransientModel):
lines.append(self.create(vals))
sequence += 1
+ # # 成品质检单
+ # fin_quality_checks = self.env['quality.check'].search([
+ # ('picking_id', '=', picking.id)
+ # ])
+ # if fin_quality_checks:
+ # b1 = 0
+ # for fin_qc in fin_quality_checks:
+ # b1 += 1
+ # vals = {
+ # 'wizard_id': wizard_id,
+ # 'sequence': sequence,
+ # 'category': '制造',
+ # 'doc_name': '质检单',
+ # 'operation_type': '',
+ # 'doc_number': fin_qc.name,
+ # 'line_number': b1,
+ # 'product_name': f'[{fin_qc.product_id.default_code}] {fin_qc.product_id.name}',
+ # 'quantity': 1,
+ # 'doc_state': map_dict.get(fin_qc.quality_state, fin_qc.quality_state),
+ # 'cancel_reason': '已有异动' if fin_qc.quality_state not in ['none', 'cancel', 'waiting'] else ''
+ # }
+ # lines.append(self.create(vals))
+
+ # 检查所有的质检单
+ quality_checks = self.env['quality.check'].search([
+ ('product_id.name', 'like', f'%{order.name}%')])
+ if quality_checks:
+ b1 = 0
+ for quality_check in quality_checks:
+ b1 += 1
+ vals = {
+ 'wizard_id': wizard_id,
+ 'sequence': sequence,
+ 'category': '质量',
+ 'doc_name': '质检单',
+ 'operation_type': '',
+ 'doc_number': f'{quality_check.name}-{quality_check.title}',
+ 'line_number': 1,
+ 'product_name': f'[{quality_check.product_id.default_code}] {quality_check.product_id.name}' if quality_check.product_id.default_code else quality_check.product_id.name,
+ 'quantity': 1,
+ 'doc_state': map_dict.get(quality_check.quality_state, quality_check.quality_state),
+ 'cancel_reason': '已有异动' if quality_check.quality_state not in ['none', 'cancel', 'waiting'] else ''
+ }
+ lines.append(self.create(vals))
+
+ # 检查组件的制造单
+ # component_mos = self.env['mrp.production'].search([
+ # ('origin', '=', mo.name)])
+ component_mos = self.env['mrp.production'].search([
+ ('product_id.name', 'like', f'%R-{order.name}%')])
+ h = 0
+ if component_mos:
+ for comp_mo in component_mos:
+ h += 1
+ vals = {
+ 'wizard_id': wizard_id,
+ 'sequence': sequence,
+ 'category': '制造',
+ 'doc_name': '组件制造单',
+ 'operation_type': '',
+ 'doc_number': comp_mo.name,
+ 'line_number': h,
+ 'product_name': f'{comp_mo.product_id.name}',
+ 'quantity': comp_mo.product_qty,
+ 'doc_state': map_dict.get(comp_mo.state, comp_mo.state),
+ 'cancel_reason': '已有异动' if comp_mo.state not in ['technology_to_confirmed',
+ 'cancel'] else ''
+ }
+ lines.append(self.create(vals))
+ sequence += 1
+
+ for pinking_id in comp_mo.picking_ids:
+ y = 0
+ for move in pinking_id.move_ids:
+ y += 1
+ vals = {
+ 'wizard_id': wizard_id,
+ 'sequence': sequence,
+ 'category': '子制造调拨',
+ 'doc_name': '库存移动',
+ 'doc_number': f'{comp_mo.name}-{pinking_id.name}',
+ 'line_number': y,
+ 'operation_type': pinking_id.picking_type_id.name,
+ 'product_name': move.product_id.name if move.product_id else '',
+ 'quantity': move.product_uom_qty,
+ 'doc_state': map_dict.get(pinking_id.state, pinking_id.state),
+ 'cancel_reason': '已有异动' if pinking_id.state not in ['cancel', 'waiting',
+ 'assigned'] else ''
+ }
+ lines.append(self.create(vals))
+
# 检查销售订单直接关联的采购单
purchase_orders = self.env['purchase.order'].search([
- ('origin', '=', order.name)
+ ('origin', 'like', f'%{order.name}%')
])
if purchase_orders:
c = 0
for po in purchase_orders:
- c += 1
- vals = {
- 'wizard_id': wizard_id,
- 'sequence': sequence,
- 'category': '采购',
- 'doc_name': '询价单',
- 'operation_type': '',
- 'doc_number': po.name,
- 'line_number': c,
- 'product_name': po.order_line[0].product_id.name if po.order_line else '',
- 'quantity': po.order_line[0].product_qty if po.order_line else 0,
- 'doc_state': map_dict.get(po.state, po.state),
- 'cancel_reason': '已有异动' if po.state not in ['draft', 'cancel'] else ''
- }
- lines.append(self.create(vals))
- sequence += 1
+ for order_line in po.order_line:
+ c += 1
+ vals = {
+ 'wizard_id': wizard_id,
+ 'sequence': sequence,
+ 'category': '采购',
+ 'doc_name': '询价单',
+ 'operation_type': '',
+ 'doc_number': po.name,
+ 'line_number': c,
+ 'product_name': f'[{order_line.product_id.default_code}] {order_line.product_id.name}',
+ 'quantity': order_line.product_qty if order_line else 0,
+ 'doc_state': map_dict.get(po.state, po.state),
+ 'cancel_reason': '已有异动' if po.state not in ['draft', 'cancel'] else ''
+ }
+ lines.append(self.create(vals))
+ sequence += 1
+
+ # 客供料的入库单
+ for pod in purchase_orders:
+ pkds = self.env['stock.picking'].search([
+ ('origin', '=', pod.name)
+ ])
+ if pkds:
+ for pkd in pkds:
+ x3 = 0
+ for move in pkd.move_ids:
+ x3 += 1
+ vals = {
+ 'wizard_id': wizard_id,
+ 'sequence': sequence,
+ 'category': '库存',
+ 'doc_name': '库存移动',
+ 'doc_number': pkd.name,
+ 'line_number': x3,
+ 'operation_type': pkd.picking_type_id.name,
+ 'product_name': f'[{move.product_id.default_code}] {move.product_id.name}',
+ 'quantity': move.product_uom_qty,
+ 'doc_state': map_dict.get(pkd.state, pkd.state),
+ 'cancel_reason': '已有异动' if pkd.state not in ['waiting', 'cancel', 'confirmed'] else ''
+ }
+ lines.append(self.create(vals))
+
+ #
+ for child_pkd in self.env['stock.picking'].search([
+ ('origin', '=', pkd.name)
+ ]):
+ x4 = 0
+ for child_move in child_pkd.move_ids:
+ x4 += 1
+ vals = {
+ 'wizard_id': wizard_id,
+ 'sequence': sequence,
+ 'category': '库存',
+ 'doc_name': '库存移动',
+ 'doc_number': child_pkd.name,
+ 'line_number': x4,
+ 'operation_type': child_pkd.picking_type_id.name,
+ 'product_name': child_move.product_id.name if child_move.product_id else '',
+ 'quantity': child_move.product_uom_qty,
+ 'doc_state': map_dict.get(child_pkd.state, child_pkd.state),
+ 'cancel_reason': '已有异动' if child_pkd.state not in ['waiting',
+ 'cancel', 'confirmed'] else ''
+ }
+ lines.append(self.create(vals))
# 检查制造订单
manufacturing_orders = self.env['mrp.production'].search([
@@ -262,7 +402,7 @@ class SFSaleOrderCancelLine(models.TransientModel):
# 检查制造订单关联的采购单
purchase_orders = self.env['purchase.order'].search([
- ('origin', '=', mo.name)
+ ('origin', 'like', f'%{mo.name}%')
])
if purchase_orders:
e = 0
@@ -323,7 +463,7 @@ class SFSaleOrderCancelLine(models.TransientModel):
'category': '坯料外协',
'doc_name': '库存移动',
'doc_number': child_pkd.name,
- 'line_number': x1,
+ 'line_number': x2,
'operation_type': child_pkd.picking_type_id.name,
'product_name': child_move.product_id.name if child_move.product_id else '',
'quantity': child_move.product_uom_qty,
@@ -404,95 +544,52 @@ class SFSaleOrderCancelLine(models.TransientModel):
}
lines.append(self.create(vals))
- # 检查制造订单组件的采购单和制造单
- for move in mo.move_raw_ids:
- # # 检查组件的采购单
- # component_pos = self.env['purchase.order'].search([
- # ('origin', '=', mo.name),
- # ('order_line.product_id', '=', move.product_id.id)
- # ])
- # for po in component_pos:
- # vals = {
- # 'wizard_id': wizard_id,
- # 'sequence': sequence,
- # 'category': '制造',
- # 'doc_name': '组件采购单',
- # 'operation_type': '组件采购',
- # 'doc_number': po.name,
- # 'product_name': move.product_id.name,
- # 'quantity': po.order_line[0].product_qty if po.order_line else 0,
- # 'doc_state': po.state,
- # 'cancel_reason': '已有异动' if po.state not in ['draft', 'cancel'] else ''
- # }
- # lines.append(self.create(vals))
- # sequence += 1
+ # # 检查制造订单组件的采购单和制造单
+ # for move in mo.move_raw_ids:
+ # # 检查组件的采购单
+ # component_pos = self.env['purchase.order'].search([
+ # ('origin', '=', mo.name),
+ # ('order_line.product_id', '=', move.product_id.id)
+ # ])
+ # for po in component_pos:
+ # vals = {
+ # 'wizard_id': wizard_id,
+ # 'sequence': sequence,
+ # 'category': '制造',
+ # 'doc_name': '组件采购单',
+ # 'operation_type': '组件采购',
+ # 'doc_number': po.name,
+ # 'product_name': move.product_id.name,
+ # 'quantity': po.order_line[0].product_qty if po.order_line else 0,
+ # 'doc_state': po.state,
+ # 'cancel_reason': '已有异动' if po.state not in ['draft', 'cancel'] else ''
+ # }
+ # lines.append(self.create(vals))
+ # sequence += 1
- # 检查组件的制造单
- component_mos = self.env['mrp.production'].search([
- ('origin', '=', mo.name)])
- h = 0
- if component_mos:
- for comp_mo in component_mos:
- h += 1
- vals = {
- 'wizard_id': wizard_id,
- 'sequence': sequence,
- 'category': '制造',
- 'doc_name': '组件制造单',
- 'operation_type': '',
- 'doc_number': comp_mo.name,
- 'line_number': h,
- 'product_name': move.product_id.name,
- 'quantity': comp_mo.product_qty,
- 'doc_state': map_dict.get(comp_mo.state, comp_mo.state),
- 'cancel_reason': '已有异动' if comp_mo.state not in ['technology_to_confirmed',
- 'cancel'] else ''
- }
- lines.append(self.create(vals))
- sequence += 1
-
- for pinking_id in comp_mo.picking_ids:
- y = 0
- for move in pinking_id.move_ids:
- y += 1
- vals = {
- 'wizard_id': wizard_id,
- 'sequence': sequence,
- 'category': '子制造调拨',
- 'doc_name': '库存移动',
- 'doc_number': f'{comp_mo.name}-{pinking_id.name}',
- 'line_number': y,
- 'operation_type': pinking_id.picking_type_id.name,
- 'product_name': move.product_id.name if move.product_id else '',
- 'quantity': move.product_uom_qty,
- 'doc_state': map_dict.get(pinking_id.state, pinking_id.state),
- 'cancel_reason': '已有异动' if pinking_id.state not in ['cancel', 'waiting'] else ''
- }
- lines.append(self.create(vals))
-
- # 检查制造订单的质检单
- quality_checks = self.env['quality.check'].search([
- ('production_id', '=', mo.id)
- ])
- if quality_checks:
- i = 0
- for check in quality_checks:
- i += 1
- vals = {
- 'wizard_id': wizard_id,
- 'sequence': sequence,
- 'category': '制造',
- 'doc_name': '质检单',
- 'operation_type': '',
- 'doc_number': check.name,
- 'line_number': i,
- 'product_name': f'[{check.product_id.default_code}] {check.product_id.name}',
- 'quantity': 1,
- 'doc_state': map_dict.get(check.quality_state, check.quality_state),
- 'cancel_reason': '已有异动' if check.quality_state not in ['none', 'cancel', 'waiting'] else ''
- }
- lines.append(self.create(vals))
- sequence += 1
+ # # 检查制造订单的质检单
+ # quality_checks = self.env['quality.check'].search([
+ # ('production_id', '=', mo.id)
+ # ])
+ # if quality_checks:
+ # i = 0
+ # for check in quality_checks:
+ # i += 1
+ # vals = {
+ # 'wizard_id': wizard_id,
+ # 'sequence': sequence,
+ # 'category': '制造',
+ # 'doc_name': '质检单',
+ # 'operation_type': '',
+ # 'doc_number': check.name,
+ # 'line_number': i,
+ # 'product_name': f'[{check.product_id.default_code}] {check.product_id.name}',
+ # 'quantity': 1,
+ # 'doc_state': map_dict.get(check.quality_state, check.quality_state),
+ # 'cancel_reason': '已有异动' if check.quality_state not in ['none', 'cancel', 'waiting'] else ''
+ # }
+ # lines.append(self.create(vals))
+ # sequence += 1
# 检查制造订单的编程单
cloud_programming = mo._cron_get_programming_state()
diff --git a/sf_manufacturing/wizard/sale_order_cancel_views.xml b/sf_manufacturing/wizard/sale_order_cancel_views.xml
index 299af9e6..134c524b 100644
--- a/sf_manufacturing/wizard/sale_order_cancel_views.xml
+++ b/sf_manufacturing/wizard/sale_order_cancel_views.xml
@@ -39,4 +39,31 @@
+
+
+ sf.sale.order.cancel.line.form
+ sf.sale.order.cancel.line
+
+
+
+
+
\ No newline at end of file
From c24f53919742c947303e91f79930abe47d338ff1 Mon Sep 17 00:00:00 2001
From: mgw <1392924357@qq.com>
Date: Fri, 28 Feb 2025 16:04:49 +0800
Subject: [PATCH 2/5] =?UTF-8?q?=E5=8F=96=E6=B6=88=E9=94=80=E5=94=AE?=
=?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=97=B6=E7=9A=84=E4=B8=8B=E6=B8=B8=E5=8D=95?=
=?UTF-8?q?=E6=8D=AE=E6=B8=85=E5=8D=95=E3=80=90=E5=A4=A7=E7=B1=BB=E3=80=81?=
=?UTF-8?q?=E5=8D=95=E6=8D=AE=E5=90=8D=E7=A7=B0=E3=80=81=E4=BD=9C=E4=B8=9A?=
=?UTF-8?q?=E7=B1=BB=E5=9E=8B=E3=80=91=E6=98=BE=E7=A4=BA=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/mrp_workorder.py | 1 +
sf_manufacturing/models/quality_check.py | 1 +
sf_manufacturing/security/ir.model.access.csv | 4 +-
sf_manufacturing/wizard/sale_order_cancel.py | 92 +++++++++++++------
4 files changed, 67 insertions(+), 31 deletions(-)
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 8470530c..2149023f 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -20,6 +20,7 @@ from odoo.addons.sf_mrs_connect.models.ftp_operate import FtpController
class ResMrpWorkOrder(models.Model):
_inherit = 'mrp.workorder'
_order = 'sequence asc'
+ _description = '工单'
product_tmpl_name = fields.Char('坯料产品名称', related='production_bom_id.bom_line_ids.product_id.name')
diff --git a/sf_manufacturing/models/quality_check.py b/sf_manufacturing/models/quality_check.py
index 291e598e..990dce23 100644
--- a/sf_manufacturing/models/quality_check.py
+++ b/sf_manufacturing/models/quality_check.py
@@ -3,5 +3,6 @@ from odoo import fields, models, api
class QualityCheck(models.Model):
_inherit = "quality.check"
+ _description = "质量检查"
is_inspect = fields.Boolean('需送检')
diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv
index 6661c9be..982506a5 100644
--- a/sf_manufacturing/security/ir.model.access.csv
+++ b/sf_manufacturing/security/ir.model.access.csv
@@ -192,5 +192,5 @@ access_sf_programming_reason,sf_programming_reason,model_sf_programming_reason,b
access_sf_programming_record,sf_programming_record,model_sf_programming_record,base.group_user,1,1,1,0
access_sf_work_individuation_page,sf_work_individuation_page,model_sf_work_individuation_page,sf_base.group_sf_mrp_user,1,1,1,0
access_sf_work_individuation_page_group_plan_dispatch,sf_work_individuation_page_group_plan_dispatch,model_sf_work_individuation_page,sf_base.group_plan_dispatch,1,1,0,0
-access_sf_sale_order_cancel_wizard,sf_sale_order_cancel_wizard,model_sf_sale_order_cancel_wizard,sf_base.group_sf_order_user,1,0,1,0
-access_sf_sale_order_cancel_line,sf_sale_order_cancel_line,model_sf_sale_order_cancel_line,sf_base.group_sf_order_user,1,0,1,0
\ No newline at end of file
+access_sf_sale_order_cancel_wizard,sf_sale_order_cancel_wizard,model_sf_sale_order_cancel_wizard,sf_base.group_sf_order_user,1,1,1,0
+access_sf_sale_order_cancel_line,sf_sale_order_cancel_line,model_sf_sale_order_cancel_line,sf_base.group_sf_order_user,1,0,1,1
\ No newline at end of file
diff --git a/sf_manufacturing/wizard/sale_order_cancel.py b/sf_manufacturing/wizard/sale_order_cancel.py
index 1f7cf306..5c24b9c8 100644
--- a/sf_manufacturing/wizard/sale_order_cancel.py
+++ b/sf_manufacturing/wizard/sale_order_cancel.py
@@ -1,4 +1,5 @@
from odoo import models, fields, api
+from odoo.exceptions import UserError
class SFSaleOrderCancelWizard(models.TransientModel):
@@ -47,6 +48,23 @@ class SFSaleOrderCancelWizard(models.TransientModel):
def action_confirm_cancel(self):
self.ensure_one()
+ # 删除现有关联单据行
+ self.related_docs.unlink()
+
+ # 重新生成最新关联单据行
+ self.env['sf.sale.order.cancel.line'].create_from_order(self.id, self.order_id)
+
+ # 强制重新计算校验字段
+ self._compute_has_movement()
+ self._compute_display_message()
+
+ # 检查是否存在异动
+ if self.has_movement:
+ raise UserError(
+ "存在下游单据异动,无法取消订单!\n"
+ "请关闭向导重新进入,查看最新状态再操作!"
+ )
+
# 取消销售订单关联的采购单
purchase_orders = self.env['purchase.order'].search([
('origin', '=', self.order_id.name)
@@ -165,6 +183,20 @@ class SFSaleOrderCancelLine(models.TransientModel):
'assigned': '就绪'
}
+ module_name_dict = {
+ 'purchase': '采购',
+ 'quality': '质检',
+ 'mrp': '制造',
+ 'stock': '库存',
+ 'account': '会计',
+ 'hr': '员工',
+ 'project': '项目',
+ 'crm': '销售',
+ 'point_of_sale': '销售',
+ 'website': '网站',
+ 'sf_plan': '计划',
+ }
+
# 检查销售订单
if order.invoice_ids:
a = 0
@@ -195,9 +227,11 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '库存',
- 'doc_name': '交货单',
- 'operation_type': '调拨',
+ # 'category': '库存',
+ 'category': module_name_dict[picking._original_module],
+ # 'doc_name': '交货单',
+ 'doc_name': picking._description,
+ 'operation_type': picking.picking_type_id.name,
'doc_number': picking.name,
'line_number': b,
'product_name': f'[{move.product_id.default_code}] {move.product_id.name}' if move else '',
@@ -242,8 +276,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '质量',
- 'doc_name': '质检单',
+ 'category': module_name_dict[quality_check._original_module],
+ 'doc_name': quality_check._description,
'operation_type': '',
'doc_number': f'{quality_check.name}-{quality_check.title}',
'line_number': 1,
@@ -266,8 +300,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '制造',
- 'doc_name': '组件制造单',
+ 'category': module_name_dict[comp_mo._original_module],
+ 'doc_name': comp_mo._description,
'operation_type': '',
'doc_number': comp_mo.name,
'line_number': h,
@@ -287,8 +321,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '子制造调拨',
- 'doc_name': '库存移动',
+ 'category': module_name_dict[pinking_id._original_module],
+ 'doc_name': pinking_id._description,
'doc_number': f'{comp_mo.name}-{pinking_id.name}',
'line_number': y,
'operation_type': pinking_id.picking_type_id.name,
@@ -312,8 +346,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '采购',
- 'doc_name': '询价单',
+ 'category': module_name_dict[po._original_module],
+ 'doc_name': po._description,
'operation_type': '',
'doc_number': po.name,
'line_number': c,
@@ -338,8 +372,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '库存',
- 'doc_name': '库存移动',
+ 'category': module_name_dict[pkd._original_module],
+ 'doc_name': pkd._description,
'doc_number': pkd.name,
'line_number': x3,
'operation_type': pkd.picking_type_id.name,
@@ -360,8 +394,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '库存',
- 'doc_name': '库存移动',
+ 'category': module_name_dict[child_pkd._original_module],
+ 'doc_name': child_pkd._description,
'doc_number': child_pkd.name,
'line_number': x4,
'operation_type': child_pkd.picking_type_id.name,
@@ -387,8 +421,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '制造',
- 'doc_name': '制造订单',
+ 'category': module_name_dict[mo._original_module],
+ 'doc_name': mo._description,
'doc_number': mo.name,
'operation_type': '',
'line_number': d,
@@ -412,8 +446,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '制造',
- 'doc_name': '询价单',
+ 'category': module_name_dict[po._original_module],
+ 'doc_name': po._description,
'doc_number': po.name,
'line_number': e,
'operation_type': '',
@@ -438,8 +472,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '坯料收货',
- 'doc_name': '库存移动',
+ 'category': module_name_dict[pkd._original_module],
+ 'doc_name': pkd._description,
'doc_number': pkd.name,
'line_number': x1,
'operation_type': pkd.picking_type_id.name,
@@ -460,8 +494,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '坯料外协',
- 'doc_name': '库存移动',
+ 'category': module_name_dict[child_pkd._original_module],
+ 'doc_name': child_pkd._description,
'doc_number': child_pkd.name,
'line_number': x2,
'operation_type': child_pkd.picking_type_id.name,
@@ -487,8 +521,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '制造',
- 'doc_name': '库存移动',
+ 'category': module_name_dict[picking._original_module],
+ 'doc_name': picking._description,
'doc_number': picking.name,
'line_number': f,
'operation_type': picking.picking_type_id.name,
@@ -509,8 +543,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '制造',
- 'doc_name': '工单',
+ 'category': module_name_dict[workorder._original_module],
+ 'doc_name': workorder._description,
'doc_number': f'{mo.name}-{workorder.processing_panel}-{workorder.name}' if workorder.processing_panel else f'{mo.name}-{workorder.name}',
'line_number': g,
'operation_type': '',
@@ -532,8 +566,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
vals = {
'wizard_id': wizard_id,
'sequence': sequence,
- 'category': '工艺外协',
- 'doc_name': '库存移动',
+ 'category': module_name_dict[pkd._original_module],
+ 'doc_name': pkd._description,
'doc_number': f'{mo.name}-{workorder.name}-{pkd.name}',
'line_number': z,
'operation_type': pkd.picking_type_id.name,
From 98b4c532137d577ea01043d484f652a9a4086efd Mon Sep 17 00:00:00 2001
From: mgw <1392924357@qq.com>
Date: Fri, 28 Feb 2025 17:35:32 +0800
Subject: [PATCH 3/5] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=90=8D=E7=A7=B0?=
=?UTF-8?q?=E4=B8=8E=E6=8F=90=E7=A4=BA=E8=AF=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/wizard/sale_order_cancel.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sf_manufacturing/wizard/sale_order_cancel.py b/sf_manufacturing/wizard/sale_order_cancel.py
index 5c24b9c8..516f8804 100644
--- a/sf_manufacturing/wizard/sale_order_cancel.py
+++ b/sf_manufacturing/wizard/sale_order_cancel.py
@@ -62,7 +62,7 @@ class SFSaleOrderCancelWizard(models.TransientModel):
if self.has_movement:
raise UserError(
"存在下游单据异动,无法取消订单!\n"
- "请关闭向导重新进入,查看最新状态再操作!"
+ "请关闭向导重新进入,以查看最新状态!"
)
# 取消销售订单关联的采购单
@@ -185,7 +185,7 @@ class SFSaleOrderCancelLine(models.TransientModel):
module_name_dict = {
'purchase': '采购',
- 'quality': '质检',
+ 'quality': '质量',
'mrp': '制造',
'stock': '库存',
'account': '会计',
From 7e93586f69b700d0541726459af9308c3f6b87b0 Mon Sep 17 00:00:00 2001
From: mgw <1392924357@qq.com>
Date: Tue, 4 Mar 2025 11:40:39 +0800
Subject: [PATCH 4/5] =?UTF-8?q?=E4=BA=BA=E5=B7=A5=E5=BB=BA=E7=AB=8B?=
=?UTF-8?q?=E9=94=80=E5=94=AE=E5=8D=95=E5=8F=96=E7=AC=AC=E4=B8=80=E4=BB=BD?=
=?UTF-8?q?bom?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/mrp_production.py | 26 +++++++++++++----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py
index 8b629440..17c1803e 100644
--- a/sf_manufacturing/models/mrp_production.py
+++ b/sf_manufacturing/models/mrp_production.py
@@ -684,7 +684,6 @@ class MrpProduction(models.Model):
logging.info('change_programming_state error:%s' % e)
raise UserError("修改编程单状态失败,请联系管理员")
-
# cnc程序获取
def fetchCNC(self, production_names):
cnc = self.env['mrp.production'].search([('id', '=', self.id)])
@@ -714,9 +713,9 @@ class MrpProduction(models.Model):
[('id', '=', cnc.product_id.materials_type_id.id)]).materials_no,
'machining_processing_panel': cnc.product_id.model_processing_panel,
'machining_precision': '',
- 'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.length,
- 'embryo_height': cnc.product_id.bom_ids.bom_line_ids.product_id.height,
- 'embryo_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width,
+ 'embryo_long': cnc.product_id.bom_ids[0].bom_line_ids.product_id.length,
+ 'embryo_height': cnc.product_id.bom_ids[0].bom_line_ids.product_id.height,
+ 'embryo_width': cnc.product_id.bom_ids[0].bom_line_ids.product_id.width,
'order_no': cnc.origin,
'model_order_no': cnc.product_id.default_code,
'user': cnc.env.user.name,
@@ -1298,12 +1297,14 @@ class MrpProduction(models.Model):
'target': 'new',
'context': {
'default_production_id': self.id,
- 'default_is_clamping': True if self.workorder_ids.filtered(lambda wk: wk.routing_type == '装夹预调') else False,
+ 'default_is_clamping': True if self.workorder_ids.filtered(
+ lambda wk: wk.routing_type == '装夹预调') else False,
'default_workorder_ids': workorder_ids.ids if workorder_ids.ids != [] else self.workorder_ids.ids,
'default_hidden_workorder_ids': ','.join(map(str, work_id_list)) if work_id_list != [] else '',
'default_reprogramming_num': cloud_programming.get('reprogramming_num') if cloud_programming else '',
'default_programming_state': cloud_programming.get('programming_state') if cloud_programming else '',
- 'default_is_reprogramming': True if cloud_programming and (cloud_programming.get('programming_state') in ['已下发']) else False
+ 'default_is_reprogramming': True if cloud_programming and (
+ cloud_programming.get('programming_state') in ['已下发']) else False
}
}
@@ -1337,7 +1338,8 @@ class MrpProduction(models.Model):
for rework_item in rework_workorder:
pending_workorder = production.workorder_ids.filtered(
lambda m1: m1.state in [
- 'pending'] and m1.processing_panel == rework_item.processing_panel and m1.routing_type in ['CNC加工', '人工线下加工'])
+ 'pending'] and m1.processing_panel == rework_item.processing_panel and m1.routing_type in [
+ 'CNC加工', '人工线下加工'])
if not pending_workorder.cnc_ids:
production.get_new_program(rework_item.processing_panel)
# production.write({'state': 'progress', 'programming_state': '已编程', 'is_rework': False})
@@ -1380,8 +1382,9 @@ class MrpProduction(models.Model):
if productions:
for production in productions:
panel_workorder = production.workorder_ids.filtered(lambda
- pw: pw.processing_panel == processing_panel and pw.routing_type in ['CNC加工', '人工线下加工'] and pw.state not in (
- 'rework', 'done'))
+ pw: pw.processing_panel == processing_panel and pw.routing_type in [
+ 'CNC加工', '人工线下加工'] and pw.state not in (
+ 'rework', 'done'))
if panel_workorder:
if panel_workorder.cmm_ids:
panel_workorder.cmm_ids.sudo().unlink()
@@ -1406,8 +1409,9 @@ class MrpProduction(models.Model):
'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
logging.info('len(cnc_worksheet):%s' % len(panel_workorder.cnc_worksheet))
pre_workorder = production.workorder_ids.filtered(lambda
- ap: ap.routing_type in ['装夹预调', '人工线下加工'] and ap.processing_panel == processing_panel and ap.state not in (
- 'rework', 'done'))
+ ap: ap.routing_type in ['装夹预调',
+ '人工线下加工'] and ap.processing_panel == processing_panel and ap.state not in (
+ 'rework', 'done'))
if pre_workorder:
pre_workorder.write(
{'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
From 7d4314abc764dcfbcda2b63b6570bdd2f65e67e1 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Wed, 5 Mar 2025 11:24:48 +0800
Subject: [PATCH 5/5] =?UTF-8?q?=E5=AE=8C=E6=88=90=20=E5=B7=A5=E5=8D=95?=
=?UTF-8?q?=E5=AD=90=E9=A1=B5=E7=AD=BE=E5=8F=AF=E5=85=A8=E9=87=8F=E9=85=8D?=
=?UTF-8?q?=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../views/mrp_workorder_views.xml | 2 +-
sf_dlm/views/product_workorder.xml | 2 +-
sf_machine_connect/views/delivery_record.xml | 2 +-
.../views/machine_info_present.xml | 2 +-
.../data/sf_work_individuation_page.xml | 58 +++++++++++++++++++
sf_manufacturing/models/mrp_production.py | 2 +-
sf_manufacturing/models/mrp_workorder.py | 13 +++--
sf_manufacturing/views/mrp_workorder_view.xml | 37 +++++++-----
sf_quality/models/quality.py | 4 +-
sf_quality/views/quality_check_view.xml | 2 +-
10 files changed, 94 insertions(+), 30 deletions(-)
diff --git a/jikimo_workorder_exception/views/mrp_workorder_views.xml b/jikimo_workorder_exception/views/mrp_workorder_views.xml
index 55ee0aa7..1ce168dc 100644
--- a/jikimo_workorder_exception/views/mrp_workorder_views.xml
+++ b/jikimo_workorder_exception/views/mrp_workorder_views.xml
@@ -8,7 +8,7 @@
-
+
diff --git a/sf_dlm/views/product_workorder.xml b/sf_dlm/views/product_workorder.xml
index 4c5f2a10..769e2369 100644
--- a/sf_dlm/views/product_workorder.xml
+++ b/sf_dlm/views/product_workorder.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/sf_machine_connect/views/delivery_record.xml b/sf_machine_connect/views/delivery_record.xml
index b614a7bb..d3d84cec 100644
--- a/sf_machine_connect/views/delivery_record.xml
+++ b/sf_machine_connect/views/delivery_record.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/sf_machine_connect/views/machine_info_present.xml b/sf_machine_connect/views/machine_info_present.xml
index b25a3515..78571a47 100644
--- a/sf_machine_connect/views/machine_info_present.xml
+++ b/sf_machine_connect/views/machine_info_present.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/sf_manufacturing/data/sf_work_individuation_page.xml b/sf_manufacturing/data/sf_work_individuation_page.xml
index 89bf333b..0b23324d 100644
--- a/sf_manufacturing/data/sf_work_individuation_page.xml
+++ b/sf_manufacturing/data/sf_work_individuation_page.xml
@@ -4,5 +4,63 @@
PTD
后置三元检测
+
+ WCP
+ 工件装夹
+
+
+ ITD_PP
+ 前置三元检测定位参数
+
+
+ 2D_MD
+ 2D加工图纸
+
+
+ QIS
+ 质检标准
+
+
+ WD
+ 工件配送
+
+
+ CNC_P
+ CNC程序
+
+
+ CMM_P
+ CMM程序
+
+
+ MTI
+ 机床信息
+
+
+ HDR
+ 下发记录
+
+
+ ER
+ 异常记录
+
+
+ DCP
+ 解除装夹
+
+
+ CMR
+ 开料要求
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py
index 17c1803e..4f9571c8 100644
--- a/sf_manufacturing/models/mrp_production.py
+++ b/sf_manufacturing/models/mrp_production.py
@@ -365,7 +365,7 @@ class MrpProduction(models.Model):
and production.schedule_state == '已排' and production.is_rework is False):
production.state = 'pending_cam'
if any((wo.test_results == '返工' and wo.state == 'done' and
- (production.programming_state in ['已编程'] or wo.individuation_page_PTD is True))
+ (production.programming_state in ['已编程'] or 'PTD' in wo.individuation_page_list))
or (wo.is_rework is True and wo.state == 'done' and production.programming_state in ['编程中', '已编程'])
for wo in production.workorder_ids) or production.is_rework is True:
production.state = 'rework'
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index a2bae378..728123e0 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -1442,7 +1442,7 @@ class ResMrpWorkOrder(models.Model):
record.production_id.process_state = '待加工'
# 生成工件配送单
record.workpiece_delivery_ids = record._json_workpiece_delivery_list()
- if record.routing_type == 'CNC加工' or record.individuation_page_PTD is True:
+ if record.routing_type == 'CNC加工' or 'PTD' in record.individuation_page_list:
if record.routing_type == 'CNC加工':
record.process_state = '待解除装夹'
# record.write({'process_state': '待加工'})
@@ -1676,10 +1676,10 @@ class ResMrpWorkOrder(models.Model):
# ==============================配置化页签--个性化记录===================================
routing_workcenter_id = fields.Many2one('mrp.routing.workcenter', compute='_compute_routing_workcenter_id',
- store=True)
+ store=True, string='工序作业')
individuation_page_ids = fields.Many2many('sf.work.individuation.page', string='个性化记录', store=True,
compute='_compute_individuation_page_ids')
- individuation_page_PTD = fields.Boolean('个性化记录(是否显示后置三元检测[PTD]页签)', default=False)
+ individuation_page_list = fields.Char('个性化记录', default=None)
@api.depends('name')
def _compute_routing_workcenter_id(self):
@@ -1695,10 +1695,11 @@ class ResMrpWorkOrder(models.Model):
if mw.routing_workcenter_id:
mw.individuation_page_ids = mw.routing_workcenter_id.individuation_page_ids.ids
# 初始化页签配置
- mw.individuation_page_PTD = False
+ mw.individuation_page_list = None
# 根据工单对应的【作业_个性化记录】配置页签
- if any(item.code == 'PTD' for item in mw.routing_workcenter_id.individuation_page_ids):
- mw.individuation_page_PTD = True
+ individuation_page_list = [item.code for item in mw.routing_workcenter_id.individuation_page_ids]
+ if individuation_page_list:
+ mw.individuation_page_list = list(set(individuation_page_list))
# =============================================================================================
diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml
index ff6b0a20..23c67c71 100644
--- a/sf_manufacturing/views/mrp_workorder_view.xml
+++ b/sf_manufacturing/views/mrp_workorder_view.xml
@@ -227,8 +227,7 @@
-
+
@@ -325,7 +324,7 @@
-
+
@@ -347,7 +346,7 @@
placeholder="如有预调程序信息请在此处输入....."/>
-
+
左面: