优先考虑彼此依赖的计算字段

时间:2019-02-13 08:11:59

标签: python odoo odoo-9

在我的odoo实例中,我在分析帐户对象上有几个计算字段。计算这些字段是为了确保查看者始终具有最新的概述。

其中一些字段取决于其他字段,这些字段本身就是计算字段。本身的计算非常简单(字段A =字段B +字段C)。大多数字段还取决于基础子ID。例如,顶部对象上的字段A是子ID的所有字段A值的汇总。如上所述,子项上的字段A是根据他们自己的字段B和C组合得出的。

我目前遇到的情况是由于某种原因,字段似乎是按随机顺序计算的。我注意到了这一点,因为当我快速连续刷新时,同一条记录会得到不同的值。

示例: 字段B和C均为10。我希望A为20(B + C),但大多数情况下实际上为0,因为A的字段计算发生在B和C之前。有时是10,因为B或C都在A之前插入可以完成。在极少数情况下,实际上是20 ......

注意: -我无法存储这些字段,因为它们将取决于以惊人的速度创建的帐户移动行,并且数据库绝对会疯狂,每分钟左右重新计算所有记录。 -我已经添加了@ api.depends,但这仅在您使用存储的字段确定字段应触发它时才有用,这在我的情况下不适用。

有人知道解决方案吗?或对替代计算方式有建议吗?

[编辑]添加了代码

示例代码:

@api.multi
@api.depends('child_ids','costs_allowed','total_cost')
def _compute_production_result(self):
    for rec in self:
        rec_prod_cost = 0.0
        if rec.usage_type in ['contract','project']:
            for child in rec.child_ids:
                rec_prod_cost += child.production_result
        elif rec.usage_type in ['cost_control','planning']:
            rec_prod_cost = rec.costs_allowed - rec.total_cost
        rec.production_result = rec_prod_cost

如您所见,如果我们处于合同或项目中,则需要查看子项(cost_control帐户)的结果,并将它们一起添加。如果我们实际上是在cost_control帐户上,那么我们可以通过获取字段B和C并减去它们来获得实际值。

在评估cost_control帐户时,如果在cost_control之前处理合同记录,或者cost_allowed和total_cost字段为0.0,则会发生问题。

提醒您:costs_allowed和total_cost都是从各自方面考虑的计算字段!

3 个答案:

答案 0 :(得分:0)

您可能会发现python @properties很有帮助。不仅使用简单的字段,还允许您定义看起来像字段但被延迟计算的内容-即在``获取''时按需计算。这样我们可以保证它是最新的。一个例子:

import datetime

class Person(object):

    def __init__(self):
        self._born = datetime.datetime.now()

    @property
    def age(self):
        return  datetime.datetime.now() - self._born


p = Person()

# do some stuff...

# We can 'get' age just like a field, but it is lazy evaluated
# i.e. calculated on demand
# This way we can guarantee it's up to date
print(p.age)

答案 1 :(得分:0)

您可以像在Invoice中一样进行操作,许多计算字段取决于许多其他字段,并且它们为每个计算字段设置一个值。

@api.one
@api.depends('X', 'Y', ...)
def _compute_amounts(self):
    self.A = ...
    self.B = ...
    self.C = self.A + self.B

答案 2 :(得分:0)

所以我设法找到一个同事,我们一起解决了这个问题。 事实证明,当定义一种方法来为其自身记录以及根据子记录中的该字段计算字段时,您需要在依赖项中明确提及。

例如:

@api.multi
@api.depends('a', 'b', 'c')
def _compute_a(self):
    for rec in self:
        if condition:
            rec.a = sum(child_ids.a)
        else:
            rec.a = rec.b + rec.c

在此示例中,自身对象包含记录(1,2,3,4)。 如果您包含依赖项,但否则让代码保持不变,就像这样:

@api.multi
@api.depends('a', 'b', 'c', 'child_ids.a')
def _compute_a(self):
    for rec in self:
        if condition:
            rec.a = sum(child_ids.a)
        else:
            rec.a = rec.b + rec.c

从最低/最深候选开始,将运行此方法4次。因此,在这种情况下,自我将是(4),然后是(3),等等。

太糟糕了,这种逻辑似乎是隐含的,在任何地方(据我所知)都没有真正描述。