odoo 為可編輯列表檢視欄位搜尋新增查詢過濾條件

2023-02-20 09:00:50

實踐環境

Odoo 14.0-20221212 (Community Edition)

需求描述

如下圖,列表網倉記錄詳情頁面(form檢視),編輯內聯檢視中的貨主記錄,為貨主倉庫欄位搜尋,新增過濾條件,具體如下:

  • 新增、編輯貨主時,下拉選單中只展示選取和當網倉記錄所屬公司關聯的貨主,點選搜尋更多,僅展示和當前網倉記錄所屬公司關聯的貨主
  • 新增、編輯貨主時,下拉選單中只展示選取和當網倉記錄關聯的倉庫(到 「倉庫」 Tab頁中新增的倉庫),點選搜尋更多,僅展示和當前網倉記錄關聯的倉庫。

模型設計

說明:為了更好的體現本文主題,部分非關鍵程式碼已省略,即做了適當的模型簡化處理

# 網倉
class OmsNetwork(models.Model):
    _name = 'oms.network'
    _description = 'OMS Network'

    company_id = fields.Many2one('res.company', '公司', index=True, tracking=3, readonly=True, default=lambda self: self.env.company)
    warehouse_ids = fields.Many2many('stock.warehouse', string="倉庫")
    line_ids = fields.One2many('oms.network.line', 'network_id', string='貨主')

# 貨主
class OmsNetworkLine(models.Model):
    _name = 'oms.network.line'
    _description = 'OMS Network Line'

    network_id = fields.Many2one('oms.network', string='倉網', required=True)
    partner_id = fields.Many2one('res.partner', string='貨主', required=True)
    warehouse_id = fields.Many2one('stock.warehouse', string="倉庫", required=True)
    company_id = fields.Many2one('res.company', '公司', store=True, related='network_id.company_id')

   

class ResPartner(models.Model):
    _inherit = ['res.partner']
    _name = 'res.partner'

    #...略
    def _get_default_company_id(self):
        if self.env.context.get('set_default_company', False):
            return self.env.company
        return False
    
    company_id = fields.Many2one( # 注意,這個欄位和OmsNetwork.company_id關聯了相同模型,所以下文可用這個欄位進行搜尋過濾
        'res.company', 'Company', index=True,
        check_company=False, tracking=3,
        default=lambda self: self._get_default_company_id())
   
    
     
# 倉庫
class StockWarehouse(models.Model):
    _inherit = 'stock.warehouse'

    # ...略
    # 注:沒有類似ResPartner的company_id欄位

檢視設計

<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
    <data>
        <!--此處程式碼已省略-->
        <record id="view_oms_network_form" model="ir.ui.view">
            <field name="name">oms.network.form</field>
            <field name="model">oms.network</field>
            <field name="priority" eval="0"/>
            <field name="arch" type="xml">
                <form string="OMS Network">
                    <!--此處程式碼已省略-->
                    <sheet>
                        <group>
                            <group>
                                <!--此處程式碼已省略-->
                            </group>
                            <group>
                                <field name="company_id"/>
                            </group>
                        </group>
                        <notebook>
                            <page string="貨主" name="line_ids" >
                                <field name="line_ids">
                                    <tree editable="bottom">
                                        <field name="partner_id"/>
                                        <field name="partner_code"/>
                                        <field name="warehouse_id"/>
                                        <!--此處程式碼已省略-->
                                    </tree>
                                </field>
                            </page>
                            <!--此處程式碼已省略-->
                        </notebook>
                    </sheet>
                    <!--此處程式碼已省略-->
                </form>
            </field>
        </record>
        <!--此處程式碼已省略-->
    </data>
</odoo>

新增過濾條件程式碼實現

修改檢視,給檢視新增context

<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
    <data>
        <!--此處程式碼已省略-->
        <record id="view_oms_network_form" model="ir.ui.view">
            <field name="name">oms.network.form</field>
            <field name="model">oms.network</field>
            <field name="priority" eval="0"/>
            <field name="arch" type="xml">
                <form string="OMS Network">
                    <!--此處程式碼已省略-->
                    <sheet>
                        <group>
                            <group>
                                <!--此處程式碼已省略-->
                            </group>
                            <group>
                                <field name="company_id"/>
                            </group>
                        </group>
                        <notebook>
                            <page string="貨主" name="line_ids" >
                                <field name="line_ids" context="{'oms_network_id':active_id, 'oms_network_company_id': company_id}">
                                    <tree editable="bottom">
                                        <field name="partner_id" context="{'oms_network_company_id':context.get('oms_network_company_id')}"/>
                                        <field name="partner_code"/>
                                        <field name="warehouse_id" context="{'oms_network_id':context.get('oms_network_id')}"/>
                                        <!--此處程式碼已省略-->
                                    </tree>
                                </field>
                            </page>
                            <!--此處程式碼已省略-->
                        </notebook>
                    </sheet>
                    <!--此處程式碼已省略-->
                </form>
            </field>
        </record>
        <!--此處程式碼已省略-->
    </data>
</odoo>

修改ResPartner,重寫模型name_search(編輯貨主欄位,彈出下拉選單時,會請求該模型函數),search_read(編輯貨主欄位,點選下拉選單時 搜尋更多開啟介面時,會請求該模型函數)

提示:分析OmsNetworkLine模型定義可知道,貨主欄位(partner_id)為多對一欄位,關聯ResPartner 模型

class ResPartner(models.Model):
    _inherit = ['res.partner']
    _name = 'res.partner'
    
    @api.model
    def name_search(self, name='', args=None, operator='ilike', limit=100):
        company_id = self.env.context.get('oms_network_company_id')
        if company_id:
            args = args or []
            args.append(('company_id', '=', company_id))
        res = super(ResPartner, self).name_search(name, args, operator, limit)

        return res

    @api.model
    def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
        company_id = self.env.context.get('oms_network_company_id')
        if company_id:
            domain = domain or []
            domain.append(('company_id', '=', company_id))

        return super(ResPartner, self).search_read(domain, fields, offset, limit, order)

修改StockWarehouse,重寫模型name_searchsearch_read

提示:分析OmsNetworkLine模型定義可知道,倉庫欄位(warehouse_id)為多對多欄位,關聯stock.warehouse 模型

class StockWarehouse(models.Model):
    _inherit = 'stock.warehouse'

    # ...略

    def _check_multiwarehouse_group(self):
        pass

    @api.model
    def name_search(self, name='', args=None, operator='ilike', limit=100):
        oms_network_id = self.env.context.get('oms_network_id')

        warehouse_ids = self.env['oms.network'].browse([oms_network_id]).warehouse_ids.ids
        if oms_network_id:
            args = args or []
            args.append(('id', 'in', warehouse_ids))
        res = super(StockWarehouse, self).name_search(name, args, operator, limit)
        return res


    @api.model
    def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
        oms_network_id = self.env.context.get('oms_network_id')
        warehouse_ids = self.env['oms.network'].browse([oms_network_id]).warehouse_ids.ids
        if warehouse_ids:
            domain = domain or []
            domain.append(('id', 'in', warehouse_ids))

        return super(StockWarehouse, self).search_read(domain, fields, offset, limit, order)