Odoo ricerca su campi calcolati o relazionati
ORM e API nelle varie versioni
Nelle varie versioni di Odoo sono state effettuate diverse modifiche al modello di oggetti ORM (object relational mapping)e alle relative API di accesso.
A causa del sistema di accessi ai dati, alcune operazioni sono agevolate ma altre risultano di difficile accesso nelle viste.
E’ il caso della ricerca sui campi calcolati o sui campi di relazione.Nello specifico il codice di seguito è applicato a Odoo 12.
Prendiamo ad esempio il caso in cui è necessario avere una particolare logica su un campo.
LA FUNZIONE PER IL CAMPO CALCOLATO
Nel mio caso devo riportare un fornitore in base a un elenco ordinato per sequenza, quindi definisco un campo calcolato supplier (nel caso specifico dipendente dal campo supplier_category):
supplier = fields.Char(string='FORNITORE', compute='_compute_supplier') @api.depends('supplier_category') def _compute_supplier(self): for record in self: supplier = None category = record.product_id.supplier_category if category: supplier_ids = self.env['category.supplier'].search([('supplier_category', '=', category)],order='sequence') if supplier_ids: supplier = supplier_ids[0].partner_id record.supplier = supplier.name
Avremo quindi il campo popolato correttamente ma di fatto non ricercabile in un’eventuale vista.
LA FUNZIONE DI RICERCA
Affinchè sia ricercabile possiamo utilizzare l’attributo search del campo e creare una funzione personalizzata per la ricerca:
supplier = fields.Char(string='FORNITORE', compute='_compute_supplier', search='_search_supplier') @api.depends('supplier_category') def _compute_supplier(self): for record in self: supplier = None category = record.product_id.supplier_category if category: supplier_ids = self.env['category.supplier'].search([('supplier_category', '=', category)],order='sequence') if supplier_ids: supplier = supplier_ids[0].partner_id record.supplier = supplier.name def _search_supplier(self, operator, value): recs = self.search([]) res = [] for i in recs: if i.supplier: if value in i.supplier or value.upper() in i.supplier: res.append(i) if res: return [('id', 'in', [x.id for x in res])]
LA SEARCH VIEW
A questo punto ci si potra riferire al campo, semplicemente tramite il nome, nella vista di ricerca dell’XML:
<record id="stock_move_bom_lines_search" model="ir.ui.view"> <field name="name">stock.move.line.mod.search</field> <field name="model">stock.move</field> <field name="arch" type="xml"> <search string="Ricerca categoria fornitora"> <field name="product_id" string="Prodotto" filter_domain="['|',('product_id','ilike',self),('name','ilike',self)]"/> <field name="supplier" string="Fornitore"/> <field name="supplier_category" string="Categoria fornitura"/> </search> </field> </record>
Altre soluzioni (in lingua inglese):
https://stackoverflow.com/questions/40819280/how-can-i-search-by-a-computed-field-in-odoo
https://www.odoo.com/it_IT/forum/help-1/question/calculated-fields-in-search-filter-possible-118501