1

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

1 Answers1

0

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)

Waleed Mohsen
  • 965
  • 6
  • 8