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
相关产品推荐
相关产品推荐

