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

Odoo 18 企业版:如何通过编程方式过滤采购订单行analytic_distribution小部件中的分析账户

解决Odoo 18采购订单行analytic_distribution小部件的分析账户过滤问题

在Odoo 18中,analytic_distribution小部件确实采用了全新的OWL组件实现,它并不依赖传统的search或name_search方法来获取可选的分析账户——而是调用了account.analytic.account模型中专门为该小部件设计的_get_analytic_distribution_accounts方法。这就是你之前重写搜索方法无效的核心原因。

下面是具体的解决方案:

1. 重写_get_analytic_distribution_accounts方法

这个方法是小部件获取候选分析账户的入口,我们可以在这里加入基于采购订单关联预算的过滤逻辑。

from odoo import models, api

class AccountAnalyticAccount(models.Model):
    _inherit = 'account.analytic.account'

    @api.model
    def _get_analytic_distribution_accounts(self, domain=None):
        # 从上下文中获取允许的分析账户ID列表
        allowed_account_ids = self.env.context.get('allowed_analytic_account_ids', [])
        if allowed_account_ids:
            # 合并原域名与过滤条件
            domain = domain or []
            domain.append(('id', 'in', allowed_account_ids))
        
        # 调用父类方法获取结果
        return super()._get_analytic_distribution_accounts(domain=domain)

2. 确保上下文正确传递到小部件

你之前的XML上下文注入需要调整细节——Odoo 18采购订单行的视图是tree而非list,并且要确保上下文能正确继承父级采购订单的allowed_analytic_account_ids字段:

<record id="purchase_order_form_view_inherit" model="ir.ui.view">
    <field name="name">purchase.order.form.view.inherit</field>
    <field name="model">purchase.order</field>
    <field name="inherit_id" ref="purchase.purchase_order_form"/>
    <field name="arch" type="xml">
        <!-- 先在表单中引入允许的账户字段(隐藏) -->
        <xpath expr="//sheet" position="inside">
            <field name="allowed_analytic_account_ids" invisible="1"/>
        </xpath>
        <!-- 为订单行的analytic_distribution字段注入上下文 -->
        <xpath expr="//field[@name='order_line']/tree//field[@name='analytic_distribution']" position="attributes">
            <attribute name="context">{'allowed_analytic_account_ids': parent.allowed_analytic_account_ids}</attribute>
        </xpath>
    </field>
</record>

注意:需要确保purchase.order模型中的allowed_analytic_account_ids字段已正确定义,用于从关联的global.budget(模型A)中拉取允许的分析账户列表,例如:

class PurchaseOrder(models.Model):
    _inherit = 'purchase.order'

    allowed_analytic_account_ids = fields.Many2many(
        'account.analytic.account',
        compute='_compute_allowed_analytic_account_ids',
        store=False,
    )

    @api.depends('overall_budget_id')
    def _compute_allowed_analytic_account_ids(self):
        for order in self:
            order.allowed_analytic_account_ids = order.overall_budget_id.allowed_analytic_account_ids

3. 验证逻辑是否生效

在重写的_get_analytic_distribution_accounts方法中加入打印语句,确认小部件调用时上下文是否携带了正确的allowed_analytic_account_ids:

@api.model
def _get_analytic_distribution_accounts(self, domain=None):
    allowed_account_ids = self.env.context.get('allowed_analytic_account_ids', [])
    print("Allowed account IDs from context:", allowed_account_ids)
    # 后续逻辑...

当你打开采购订单行的analytic_distribution小部件时,应该能在Odoo日志中看到打印的ID列表,此时小部件的账户选择列表就会被过滤为仅显示预算允许的账户。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 09:27:33