Odoo 11:如何根据条件隐藏报价视图中的“创建发票”按钮?
解决Odoo报价视图中“创建发票”按钮的隐藏问题
你的代码逻辑刚好和需求相反,还可能存在字段判断的场景偏差,我们一步步来修正:
问题分析
你的需求是当订单行包含任务/服务时隐藏“创建发票”按钮,但原代码里的('task_ids', '=', [])条件,是在task_ids为空时隐藏按钮——这完全和你的需求背道而驰。另外还要注意:如果“任务/服务”是关联在订单行(sale.order.line)上的,直接在sale.order视图里判断子行字段是无法生效的,因为视图的attrs只能直接使用当前模型的字段。
解决方案分两种场景:
场景1:任务直接关联在订单(sale.order)上
如果你的订单模型本身有task_ids(one2many关联到project.task),只需要把原条件里的('task_ids', '=', [])改成('task_ids', '!=', []),同时保留原有的其他隐藏逻辑(状态不是sale、发票状态不是no)即可:
<button name="%(sale.action_view_sale_advance_payment_inv)d" string="Create Invoice" type="action" context="{'default_advance_payment_method': 'percentage'}" attrs="{'invisible': ['|','|', ('task_ids', '!=', []), ('invoice_status', '!=', 'no'), ('state', '!=', 'sale')]}"/>
场景2:任务关联在订单行(sale.order.line)上
如果任务是挂在每个订单行的task_id字段,或者订单行是服务类产品(product_id.type == 'service'),需要先在sale.order模型上新增一个计算字段,用来判断是否存在这类订单行:
- 先在Python代码里新增计算字段:
from odoo import models, fields class SaleOrder(models.Model): _inherit = 'sale.order' has_service_or_task = fields.Boolean(compute='_compute_has_service_or_task', string="Has Service/Task") def _compute_has_service_or_task(self): for order in self: # 判断是否有订单行关联了任务,或是服务类产品 order.has_service_or_task = any( line.task_id or (line.product_id and line.product_id.type == 'service') for line in order.order_line )
- 然后在视图中用这个字段控制按钮隐藏:
<button name="%(sale.action_view_sale_advance_payment_inv)d" string="Create Invoice" type="action" context="{'default_advance_payment_method': 'percentage'}" attrs="{'invisible': ['|','|','|', ('has_service_or_task', '=', True), ('invoice_status', '!=', 'no'), ('state', '!=', 'sale')]}"/>
额外检查点
- 确认你正确继承了
sale.order的对应视图,按钮所在的视图确实是报价/订单视图。 - 验证
task_ids或order_line.task_id字段有真实数据,避免因字段为空导致条件不触发。 - 如果是服务类产品,确认
product_id.type的取值确实是'service'(Odoo默认是这个值,若有自定义改动需对应调整)。
内容的提问来源于stack exchange,提问作者Nabil Taleb
相关产品推荐
相关产品推荐

