You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo10销售订单unlink方法重写及订单行验证移除问题咨询

Odoo 10 技术问题解答

1. 如何重写销售订单(Sale Order)的unlink方法?

重写销售订单的unlink方法其实很简单,你只需要在自定义模块里继承sale.order模型,重新定义unlink方法即可,步骤如下:

  • 准备自定义模块:确保你有一个可用的自定义模块(如果没有,先创建包含__manifest__.py等核心文件的模块)。
  • 继承目标模型:在模块的models目录下创建Python文件,导入必要模块后继承sale.order。
  • 重写unlink方法:用@api.multi装饰器(Odoo 10中unlink默认使用该装饰器)编写自定义逻辑,最后调用父类方法完成实际删除操作。

示例代码参考:

from odoo import models, api, exceptions, _

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    @api.multi
    def unlink(self):
        # 自定义验证逻辑:禁止删除金额超1000的已完成订单
        forbidden_orders = self.filtered(lambda x: x.state == 'done' and x.amount_total > 1000)
        if forbidden_orders:
            raise exceptions.UserError(_('无法删除金额超过1000的已完成订单!'))
        
        # 调用父类方法执行实际删除
        return super(SaleOrder, self).unlink()

你可以根据业务需求修改逻辑,比如跳过某些默认验证、添加删除前的清理操作等。


2. 重写销售订单行(Sale Order Line)的unlink方法时,函数已被调用,但无法移除原有的UserError验证

这个问题很常见,核心原因是你重写方法时依然调用了原sale.order.line的unlink方法,原方法的验证逻辑会被触发。先回顾Odoo默认的订单行unlink逻辑:

@api.multi
def unlink(self):
if self.filtered(lambda x: x.state in ('sale', 'done')):
raise UserError(_('You can not remove a sale order line.\nDiscard changes and try setting the quantity to 0.'))
return super(SaleOrderLine, self).unlink()

原方法会先检查订单行状态,若为sale或done则抛出错误。要移除这个验证,你需要跳过原方法的逻辑,或者完全替换验证规则,以下是两种解决方案:

方案1:完全移除原验证,允许删除任何状态的订单行

如果你想放开所有状态订单行的删除权限,可以直接调用最上层父类models.Model的unlink方法,跳过原sale.order.line的验证:

from odoo import models, api, exceptions, _

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'

    @api.multi
    def unlink(self):
        # 可添加自定义验证(比如仅允许管理员删除已确认订单行)
        # if self.filtered(lambda x: x.state in ('sale', 'done')) and not self.env.user.has_group('base.group_system'):
        #     raise exceptions.UserError(_('仅管理员可删除已确认的订单行!'))
        
        # 跳过原SaleOrderLine的验证,直接执行底层删除逻辑
        return super(models.Model, self).unlink()

方案2:修改原验证逻辑,保留部分限制

如果你只想调整验证条件(比如禁止删除已发货的订单行,但允许删除未发货的),可以替换原有的过滤规则:

from odoo import models, api, exceptions, _

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'

    @api.multi
    def unlink(self):
        # 自定义过滤:禁止删除已发货的订单行
        forbidden_lines = self.filtered(lambda x: x.state in ('sale', 'done') and x.qty_delivered > 0)
        if forbidden_lines:
            raise exceptions.UserError(_('无法删除已发货的订单行!'))
        
        # 调用父类方法完成删除(此时原验证逻辑已被覆盖)
        return super(SaleOrderLine, self).unlink()

这样修改后,原有的UserError就不会再触发了,验证逻辑完全由你自定义。


内容的提问来源于stack exchange,提问作者Pawan Kumar Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:22:59