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="如有预调程序信息请在此处输入....."/> - +
左面:
@@ -504,17 +503,15 @@ - + - + - + @@ -542,11 +539,19 @@ attrs='{"invisible": ["|", ("state","!=","progress"), ("routing_type","!=","装夹预调")]}'/> + + + + + + + + - - + + --> - + - + - + @@ -601,7 +606,7 @@ - + @@ -614,7 +619,7 @@ - + diff --git a/sf_quality/models/quality.py b/sf_quality/models/quality.py index ebe30a71..498ec402 100644 --- a/sf_quality/models/quality.py +++ b/sf_quality/models/quality.py @@ -18,7 +18,7 @@ class QualityCheck(models.Model): ('cancel', '已取消'), ], string='状态', tracking=True, store=True, default='none', copy=False, compute='_compute_quality_state') - individuation_page_PTD = fields.Boolean('个性化记录(是否显示后置三元检测[PTD]页签)', related='workorder_id.individuation_page_PTD') + individuation_page_list = fields.Char('个性化记录', related='workorder_id.individuation_page_list') work_state = fields.Selection(related='workorder_id.state', string='工单状态') processing_panel = fields.Char(related='workorder_id.processing_panel', string='加工面') @@ -93,7 +93,7 @@ class QualityCheck(models.Model): raise ValidationError('请填写【判定结果】里的信息') if self.test_results == '合格': raise ValidationError('请重新选择【判定结果】-【检测结果】') - if self.workorder_id.routing_type != 'CNC加工' and self.workorder_id.individuation_page_PTD is False: + if self.workorder_id.routing_type != 'CNC加工' and 'PTD' not in self.workorder_id.individuation_page_list: self.workorder_id.production_id.write({'detection_result_ids': [(0, 0, { 'rework_reason': self.reason, 'detailed_reason': self.detailed_reason, diff --git a/sf_quality/views/quality_check_view.xml b/sf_quality/views/quality_check_view.xml index 00b139de..83ffcbca 100644 --- a/sf_quality/views/quality_check_view.xml +++ b/sf_quality/views/quality_check_view.xml @@ -8,7 +8,7 @@ - +