【问题标题】:Odoo 14, triggering a function upon stock.quant.write(), but only onceOdoo 14,在 stock.quant.write() 上触发一个函数,但只有一次
【发布时间】:2021-08-08 12:42:16
【问题描述】:

我想在写入 stock.quant 时触发操作,即当产品的总库存发生变化时。我目前的做法是这样的:

class StockQuantInherit(models.Model):
_inherit = "stock.quant"

def write(self, vals):
    res = super(StockQuantInherit, self).write(vals)
    available = self.product_id.product_tmpl_id.mapped('virtual_available')[0]
    log(available) # see result below
    api_call_to_external_site(self.product_id.default_code, available)
    return res

当产品的库存发生变化时,会导致 stock.quant 被写入 3 次,如下所示。 (它显示为错误,所以我可以很容易地在信息流中发现它)

2021-08-08 12:25:44,278 11335 ERROR odoo odoo.addons.stock_enhanced.models.stock_move: 87.0 
2021-08-08 12:25:44,281 11335 ERROR odoo odoo.addons.stock_enhanced.models.stock_move: 87.0 
2021-08-08 12:25:44,299 11335 ERROR odoo odoo.addons.stock_enhanced.models.stock_move: 96.0 

或者它也可能看起来像这样:

2021-08-08 12:32:43,987 11335 ERROR odoo odoo.addons.stock_enhanced.models.stock_move: 100.0 
2021-08-08 12:32:43,990 11335 ERROR odoo odoo.addons.stock_enhanced.models.stock_move: 100.0 
2021-08-08 12:32:44,009 11335 ERROR odoo odoo.addons.stock_enhanced.models.stock_move: 100.0 

前两个值我不感兴趣,因为它们可能正确或不正确。只有最后一个是有趣的。所以以效率的名义而不是调用同一个函数,这将在瞬间调用外部API 3次,我想只在最后一次写入事件之后触发该函数。

现在我的问题来了,我该怎么做?只在第一次触发它很容易,但我不知道如何只在最后一次触发它。

【问题讨论】:

    标签: python odoo odoo-14


    【解决方案1】:

    好的,我设法解决了这个问题。我一直在寻找的是“事件去抖动”。

    我尝试复制粘贴此装饰器:https://gist.github.com/walkermatt/2871026

    然而,这并没有奏效,因为显然每次都创建了一个去抖动函数的新实例(?),导致三个线程都成功等待了 1 秒。

    所以我在我的模块中实现了这个函数,以确保它总是被调用的是同一个函数。如果我对装饰器为什么不起作用的解释不正确,请道歉。

    无论如何,这个解决方案现在解决了我的问题:

    from threading import Timer
    
    def call_api(sku, quantity_available):
        def call_it():
            log(quantity_available)
        try:
            call_api.t.cancel()
        except(AttributeError):
            pass
        call_api.t = Timer(1, call_it)
        call_api.t.start()
    
    
    class StockQuantInherit(models.Model):
        _inherit = "stock.quant"
    
        def write(self, vals):
            res = super(StockQuantInherit, self).write(vals)
            if self.product_id.default_code: 
                available = self.product_id.product_tmpl_id.mapped('virtual_available')[0]
                call_api(self.product_id.default_code, available)
            return res
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      相关资源
      最近更新 更多