HI I have a customer field and the default search is by name, and I want to add a search by barcode as well to the customer field
I have tried adding a barcode(partner_id.barcode) on the domain as below, but it still doesn't work (model = sale.order)
@api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
if self._context.get('sale_show_partner_name'):
if operator == 'ilike' and not (name or '').strip():
domain = []
elif operator in ('ilike', 'like', '=', '=like', '=ilike'):
domain = expression.AND([
args or [],
['|', '|', ('name', operator, name), ('partner_id.name', operator, name), ('partner_id.barcode', operator, name)]
])
return self._search(domain, limit=limit, access_rights_uid=name_get_uid)
return super(SaleOrder, self)._name_search(name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid)
I have also tried in the (res.partner) model as below. it can search customer by barcode, but cannot search customer by name :
@api.model
def name_search(self, name, args=None, operator='ilike', limit=100):
if not self.env.context.get('display_barcode', True):
return super(ResPartnerInherit, self).name_search(name, args, operator, limit)
else:
args = args or []
recs = self.browse()
if not recs:
recs = self.search([('barcode', operator, name)] + args, limit=limit)
return recs.name_get()
What should I do if I want to find a customer by name and barcode?
If anyone knows, please let me know
Best Regards
The barcode field in res.partner is a property field and stored in ir.property model which name is Company Propeties in Odoo and you can access it with developer mode from Settings -> Technical -> Company Propeties.
The _name_search method for res.partner enable you to search in any Many2one partner relation field in any model by one of these fields display_name, email, reference and vat
and you can override it to add barcode as below:
from odoo import api, models
from odoo.osv.expression import get_unaccent_wrapper
import re
class ResPartner(models.Model):
_inherit = 'res.partner'
@api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
self = self.with_user(name_get_uid) if name_get_uid else self
# as the implementation is in SQL, we force the recompute of fields if necessary
self.recompute(['display_name'])
self.flush()
print(args)
if args is None:
args = []
order_by_rank = self.env.context.get('res_partner_search_mode')
if (name or order_by_rank) and operator in ('=', 'ilike', '=ilike', 'like', '=like'):
self.check_access_rights('read')
where_query = self._where_calc(args)
self._apply_ir_rules(where_query, 'read')
from_clause, where_clause, where_clause_params = where_query.get_sql()
from_str = from_clause if from_clause else 'res_partner'
where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE '
print(where_clause_params)
# search on the name of the contacts and of its company
search_name = name
if operator in ('ilike', 'like'):
search_name = '%%%s%%' % name
if operator in ('=ilike', '=like'):
operator = operator[1:]
unaccent = get_unaccent_wrapper(self.env.cr)
fields = self._get_name_search_order_by_fields()
query = """SELECT res_partner.id
FROM {from_str}
LEFT JOIN ir_property trust_property ON (
trust_property.res_id = 'res.partner,'|| {from_str}."id"
AND trust_property.name = 'barcode')
{where} ({email} {operator} {percent}
OR {display_name} {operator} {percent}
OR {reference} {operator} {percent}
OR {barcode} {operator} {percent}
OR {vat} {operator} {percent})
-- don't panic, trust postgres bitmap
ORDER BY {fields} {display_name} {operator} {percent} desc,
{display_name}
""".format(from_str=from_str,
fields=fields,
where=where_str,
operator=operator,
email=unaccent('res_partner.email'),
display_name=unaccent('res_partner.display_name'),
reference=unaccent('res_partner.ref'),
barcode=unaccent('trust_property.value_text'),
percent=unaccent('%s'),
vat=unaccent('res_partner.vat'), )
where_clause_params += [search_name] * 4 # for email / display_name, reference
where_clause_params += [re.sub('[^a-zA-Z0-9\-\.]+', '', search_name) or None] # for vat
where_clause_params += [search_name] # for order by
if limit:
query += ' limit %s'
where_clause_params.append(limit)
print(query)
print(where_clause_params)
self.env.cr.execute(query, where_clause_params)
return [row[0] for row in self.env.cr.fetchall()]
return super(ResPartner, self)._name_search(name, args, operator=operator, limit=limit, name_get_uid=name_get_uid)