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