How to fix ValueError: Expected singleton sale.order(41,...)
How to fix ValueError: Expected singleton sale.order(41,...)
我写了一个自定义的odoo模块,当我安装它时,它抛出了一个单例错误。
当我注释掉 _compute_margin(self) 和 return 0.0 中的所有内容时,模块安装正常。
然后,当我将 _compute_margin 函数改回原来的状态并更新模块时,它更新正常。
我需要做哪些更改才能使模块安装正常并使用 _compute_margin 函数的内容?
class MyCompanyintercompanyMargin(models.Model):
_name = 'my_companyintercompany.margin'
name = fields.Char()
x_marginsplitmodel = fields.Char()
x_marginsplitdescription = fields.Char()
class ResPartner(models.Model):
_name = 'res.partner'
_inherit = 'res.partner'
x_my_companyintercompany = fields.Boolean()
x_my_companyintercompany_marginsplit = fields.Many2one(
'my_companyintercompany.margin',
string='Margin Split Model'
)
class SaleOrder(models.Model):
_name = 'sale.order'
_inherit = 'sale.order'
x_endcustomer = fields.Many2one(
comodel_name='res.partner',
string='Customer'
)
x_my_companyintercompany_marginsplit = fields.Many2one(string='Margin Split', related="partner_id.x_my_companyintercompany_marginsplit")
x_my_companyintercompany_marginsplitid = fields.Char(related="x_my_companyintercompany_marginsplit.name", string="Margin Split")
x_prsmarginpercentage = fields.Float(string="Marge %")
@api.depends('order_line.margin')
def _compute_margin(self):
amount_untaxed = self.amount_untaxed
if self.x_my_companyintercompany_marginsplit:
try:
if self.x_my_companyintercompany_marginsplitid == "Total -2,5%":
totalordercost = 0.0
for line in self.order_line:
totalordercost += line.purchase_price * line.product_uom_qty
intercompanymargin = amount_untaxed * 0.025
self.x_prsmargin = amount_untaxed - totalordercost - intercompanymargin
elif self.x_my_companyintercompany_marginsplitid == "Marge 50/50":
self.x_prsmargin = self.margin / 2
else:
self.x_prsmargin = self.margin
except:
raise "Exception!"
else:
self.x_prsmargin = self.margin
if amount_untaxed > 0.0:
self.x_prsmarginpercentage = self.x_prsmargin / amount_untaxed * 100
else:
self.x_prsmarginpercentage = 0.0
x_prsmargin = fields.Monetary(compute='_compute_margin', store='true')
您需要用 @api.multi.
修饰您的计算方法
基本上,当 Odoo 尝试在数据库中初始化您的新字段时,它会同时计算许多记录。当前设置方法的方式一次只能支持一条记录,这就是为什么您会收到 Expected singleton 消息的原因。
尝试以下操作:
# First, include the @api.multi decorator
@api.multi
@api.depends('order_line.margin')
def _compute_margin(self):
# Second, use a for loop to loop over self
# because it's possible for self to be multiple records
for order in self:
# Finally, use your same method logic in the loop...
# Except that you must assign the result **per record**
# in the loop (with `order` in this example instead of `self`)
order.x_prsmarginpercentage = ...
将使用 self
中提供的多个记录调用计算方法。但是您尝试直接从 self
获取属性,这仅适用于单例(只有一条记录的记录集)。
所以您有两种选择来解决问题:
- 在
self
上将您的方法重写为 for 循环。您还应该使用 @api.multi
修饰该方法。简单示例:
@api.multi
@api.depends('field1', 'field2', 'fieldn')
def _compute_my_field(self):
for record in self:
record.my_field = 4711
- 只需使用
@api.one
装饰您的计算方法,让 Odoo 为 self
中的每条记录循环。 Odoo 将在 self
中的每条记录上循环,并将方法 return 值收集在列表中,该列表将是循环结束时的 return 值。您可以按照您已经使用的方式使用 self
:作为单例。
我写了一个自定义的odoo模块,当我安装它时,它抛出了一个单例错误。 当我注释掉 _compute_margin(self) 和 return 0.0 中的所有内容时,模块安装正常。 然后,当我将 _compute_margin 函数改回原来的状态并更新模块时,它更新正常。
我需要做哪些更改才能使模块安装正常并使用 _compute_margin 函数的内容?
class MyCompanyintercompanyMargin(models.Model):
_name = 'my_companyintercompany.margin'
name = fields.Char()
x_marginsplitmodel = fields.Char()
x_marginsplitdescription = fields.Char()
class ResPartner(models.Model):
_name = 'res.partner'
_inherit = 'res.partner'
x_my_companyintercompany = fields.Boolean()
x_my_companyintercompany_marginsplit = fields.Many2one(
'my_companyintercompany.margin',
string='Margin Split Model'
)
class SaleOrder(models.Model):
_name = 'sale.order'
_inherit = 'sale.order'
x_endcustomer = fields.Many2one(
comodel_name='res.partner',
string='Customer'
)
x_my_companyintercompany_marginsplit = fields.Many2one(string='Margin Split', related="partner_id.x_my_companyintercompany_marginsplit")
x_my_companyintercompany_marginsplitid = fields.Char(related="x_my_companyintercompany_marginsplit.name", string="Margin Split")
x_prsmarginpercentage = fields.Float(string="Marge %")
@api.depends('order_line.margin')
def _compute_margin(self):
amount_untaxed = self.amount_untaxed
if self.x_my_companyintercompany_marginsplit:
try:
if self.x_my_companyintercompany_marginsplitid == "Total -2,5%":
totalordercost = 0.0
for line in self.order_line:
totalordercost += line.purchase_price * line.product_uom_qty
intercompanymargin = amount_untaxed * 0.025
self.x_prsmargin = amount_untaxed - totalordercost - intercompanymargin
elif self.x_my_companyintercompany_marginsplitid == "Marge 50/50":
self.x_prsmargin = self.margin / 2
else:
self.x_prsmargin = self.margin
except:
raise "Exception!"
else:
self.x_prsmargin = self.margin
if amount_untaxed > 0.0:
self.x_prsmarginpercentage = self.x_prsmargin / amount_untaxed * 100
else:
self.x_prsmarginpercentage = 0.0
x_prsmargin = fields.Monetary(compute='_compute_margin', store='true')
您需要用 @api.multi.
修饰您的计算方法基本上,当 Odoo 尝试在数据库中初始化您的新字段时,它会同时计算许多记录。当前设置方法的方式一次只能支持一条记录,这就是为什么您会收到 Expected singleton 消息的原因。
尝试以下操作:
# First, include the @api.multi decorator
@api.multi
@api.depends('order_line.margin')
def _compute_margin(self):
# Second, use a for loop to loop over self
# because it's possible for self to be multiple records
for order in self:
# Finally, use your same method logic in the loop...
# Except that you must assign the result **per record**
# in the loop (with `order` in this example instead of `self`)
order.x_prsmarginpercentage = ...
将使用 self
中提供的多个记录调用计算方法。但是您尝试直接从 self
获取属性,这仅适用于单例(只有一条记录的记录集)。
所以您有两种选择来解决问题:
- 在
self
上将您的方法重写为 for 循环。您还应该使用@api.multi
修饰该方法。简单示例:
@api.multi
@api.depends('field1', 'field2', 'fieldn')
def _compute_my_field(self):
for record in self:
record.my_field = 4711
- 只需使用
@api.one
装饰您的计算方法,让 Odoo 为self
中的每条记录循环。 Odoo 将在self
中的每条记录上循环,并将方法 return 值收集在列表中,该列表将是循环结束时的 return 值。您可以按照您已经使用的方式使用self
:作为单例。