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

基于crm.lead的product_quantity字段创建多销售订单报错求助

解决Odoo创建多个销售订单时的“重复关注”报错问题

我刚帮你分析了这个报错的根源:你遇到的Error, a partner cannot follow twice the same object,是因为Odoo默认的联动逻辑在搞事情——当你创建关联同一个CRM商机(也就是你的crm.lead记录)的销售订单时,系统会自动尝试把商机的合作伙伴添加为该商机的关注者。但这个伙伴本来就已经是商机的关注者了,你循环创建多个订单时,每次都会触发这个重复添加的操作,自然就报错了。

另外还要提一句:你的代码用了@api.multi装饰器,但直接写self.id是隐患——如果当前操作的是多个lead记录,self.id会返回列表,直接赋值会出错,所以一定要循环处理每个lead。

下面给你几个可行的解决办法,你可以根据自己的需求选:

方案一:先创建订单再批量关联商机

这个方法是跳过创建时的自动订阅触发,先把销售订单都创建好,再一次性关联商机,避免重复触发订阅逻辑:

@api.multi
def create_sale(self):
    # 循环处理每一条lead记录(适配@api.multi)
    for lead in self:
        base_values = {
            'state': 'draft',
            'date_order': fields.Datetime.now(),
            'partner_id': lead.partner_id.id
        }
        created_sales = []
        # 批量创建不关联商机的销售订单
        for _ in range(lead.product_quantity):
            sale_order = self.env['sale.order'].create(base_values)
            created_sales.append(sale_order)
        # 一次性给所有订单关联商机
        if created_sales:
            self.env['sale.order'].browse([sale.id for sale in created_sales]).write({
                'opportunity_id': lead.id
            })

方案二:临时禁用自动订阅逻辑

如果不想调整创建流程,可以临时替换掉Odoo的自动订阅方法,创建完成后再恢复,从根源上避免重复订阅:

from odoo import api, fields, models
from odoo.addons.mail.models.mail_thread import MailThread

@api.multi
def create_sale(self):
    for lead in self:
        # 先备份原始的订阅方法
        original_subscribe = MailThread.message_subscribe
        # 临时替换成空方法,阻止自动订阅
        MailThread.message_subscribe = lambda self, *args, **kwargs: None
        
        try:
            sale_values = {
                'opportunity_id': lead.id,
                'state': 'draft',
                'date_order': fields.Datetime.now(),
                'partner_id': lead.partner_id.id
            }
            # 循环创建订单
            for _ in range(lead.product_quantity):
                self.env['sale.order'].create(sale_values)
        finally:
            # 一定要恢复原始方法,不影响其他逻辑
            MailThread.message_subscribe = original_subscribe

方案三:提前确保伙伴已订阅商机

这个方法最轻量化,提前检查并确保伙伴已经是商机的关注者,这样系统创建订单时就不会再尝试重复添加了:

@api.multi
def create_sale(self):
    for lead in self:
        # 检查伙伴是否已经是商机的关注者,不是的话就添加一次
        follower_partners = lead.message_follower_ids.mapped('partner_id')
        if lead.partner_id not in follower_partners:
            lead.message_subscribe(partner_ids=[lead.partner_id.id])
        
        sale_values = {
            'opportunity_id': lead.id,
            'state': 'draft',
            'date_order': fields.Datetime.now(),
            'partner_id': lead.partner_id.id
        }
        # 现在循环创建订单就不会触发重复订阅报错了
        for _ in range(lead.product_quantity):
            self.env['sale.order'].create(sale_values)

内容的提问来源于stack exchange,提问作者NinjaBat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:09:27