Use name_search in odoo 9 - odoo

I want use name search but below example not working.
Tag 1 1234
Tag 2 2568
Tag 3 0369
After type 036 I want get Tag 3!
class MyTags(models.Model):
_name = "my.tags"
_description = "Tags"
name = fields.Char(required=True)
color = fields.Integer(string='Color Index')
#api.multi
def name_get(self):
result = []
for record in self:
name = '[' + str(record.color) + ']' + ' ' + record.name
result.append((record.id, name))
return result
#api.model
def name_search(self, name, args=None, operator='ilike', limit=100):
args = args or []
recs = self.browse()
if name:
recs = self.search([('color', '=', name)] + args, limit=limit)
if not recs:
recs = self.search([('name', operator, name)] + args, limit=limit)
return recs.name_get()
Note
Above example work fine after type or scan exactly eg. 0369 return Tag 3, but after type eg. 036 not return.

You have to use the like or ilike operator to get such searches to work. It has to be [('color', 'ilike', name)] then. If you want a more specific search pattern, you could also use =like or =ilike, but i have no example for them right now, so look into Odoo doc to find out, what they are doing.
Edit: it's also helpful to get search wildcards around the search team:
name would be '%' + name + '%' so [('name', 'ilike', '%036%')] should find 0369 tag.

Related

How to extend search record to also look at custom Many2Many field(s)?

In this image, there is a product search record that will search for name and default_code. I need to make it so that it will also look at my custom Many2Many field.
This is the field in the inherited model.
product_list = fields.Many2many("product.list", string="Product List")
The custom model only has _name, _description, and name variables.
The question is how to make the search to also look at all of the possible Many2Many data of this field.
I have tried this in the inherited model:
#api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
res = super(product_template_inherit, self).name_search(name='', args=None, operator='ilike', limit=100)
ids = self.search(args + [(name, 'in', 'product_list.name')], limit=limit)
if ids:
return ids.name_get()
return res
Nothing happens to the search. It still searches using the same behavior regardless of the code above.
Summary: I need to be able to search product by product list (custom Many2Many field inherited in the product.template model)
=============================================
UPDATE
Current code from what I have been trying is now this.
#api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
args = args or []
if operator == 'ilike' and not (name or '').strip():
domain = []
else:
domain = ['|', ('name', 'ilike', name), ('product_list.name', 'ilike', name)]
product_ids = self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)
return self.browse(product_ids).name_get()
However, it looks like it still searches using the same old fields. It does not change to behave as my function is written.
You can compute the search domain then return the result of the _search method.
The fleet module already uses the same logic to search vehicles using the driver name, you have just to replace the driver_id with product_list:
class ProductProduct(models.Model):
_inherit = 'product.product'
#api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
args = args or []
if operator == 'ilike' and not (name or '').strip():
domain = []
else:
domain = ['|', ('name', operator, name), ('product_list.name', operator, name)]
return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)

What does the path /shop/get_suggest mean?

I found a module that autocomplete search in a Website e-commerce with high-light match words and image. But I did not really understand what each command do .
Can you please explain to me how this code work, and why they did /shop/get_suggest?
class WebsiteSale(http.Controller):
#http.route(['/shop/get_suggest'], type='http', auth="public", methods=['GET'], website=True)
def get_suggest_json(self, **kw):
query = kw.get('query')
names = query.split(' ')
domain = ['|' for k in range(len(names) - 1)] + [('name', 'ilike', name) for name in names]
products = request.env['product.template'].search(domain, limit=15)
products = sorted(products, key=lambda x: SequenceMatcher(None, query.lower(), x.name.lower()).ratio(),
reverse=True)
results = []
for product in products:
results.append({'value': product.name, 'data': {'id': product.id, 'after_selected': product.name}})
return json.dumps({
'query': 'Unit',
'suggestions': results
})
This controller function will be activated when you load page your_domain/shop/get_suggest.
The function just searches for products with similar name of the query given in the search.
Please go through this documentation to learn basics of building a website

how get id with onchange for filtering

how can i retrieve the value of a many2one field or its ID from another model
for exemple:
class Contrat(models.Model):
_name = 'facturation.contrat'
contrat_parent_id = fields.Many2one('facturation.contrat', string='Numéro Contrat Client',
domain=[('is_prestataire', '=', False)])
class Lot(models.Model):
contrat_id = fields.Many2one('facturation.contrat', ondelete='cascade')
articlecontrat_ids = fields.Many2many('facturation.articleouvrage',string='Article Lot')
91/5000
i want that when i change contrat_parent_id i get it back to use it and filter my articles for field 'articlecontrat_ids'
here you need to use onchange event i'm assuming that facturation.articleouvrage have a m2o field named contrat_id
# in onchange event always put the name of the field that trigger the event
#api.onchange('contrat_parent_id ')
def onchange_contrat(self):
"""update the domain when we change the contrat"""
if self.contrat_parent_id :
# always check if the field is not empty
# return the domain like this but i don't know what you need exactly
return {'domain': {'articlecontrat_ids ' : [('contrat_id ', '=', self.contrat_parent_id.contract.id)]}}
else: # remove the domain
return {'domain': {'articlecontrat_ids ' : []}}
if you want to remove all records when user change the contrat_id but i think you make the user ungry
to reselect all this records.
self.articlecontrat_ids = [(5, 0, 0)]

Two value in Many2one field odoo 9

In Many2one field I Want view invoice name and invoice ammount_total how add this?
customer_invoice = fields.Many2one('account.invoice', 'Customer Inv', select=True)
Now after open customer_invoice field I view eg. INV/2017/0001, INV/2017/0002 I want INV/2017/0001 100€, INV/2017/0002 200€
Is it possible?
This methode change the default name, just add it in invoice class
#api.multi
def name_get(self):
result = []
for record in self:
name = record.name
if record.ammount_total :
name = record.name + ' ' + str(record.ammount_total)
result.append((record.id, name))
return result

Django auth.models.User query by full name but Chinese name

In Chinese, the name format is 'LastnameFirstname' (number of characters for both Lastname and Firstname are varied), while in English, it is 'Firstname LastName'. We can see that in Chinese, the first name last name is swapped (which is not a problem in query here), and the first name last name is NOT separated by whitespace (which caused me this problem).
In SQL, we can do this:
SELECT *
FROM USER
WHERE Concat(last_name, first_name) = 'LastnameFirstName';
But how can I do this in Django? Given a FULLNAME string as 'LastnameFirstname', how can I do:
User.objects.filter(last_name+firstname=FULLNAME)
Another solution is to create a custom User model and create a new field called "full name", but this solution disables me to use other django built-in functions:
class User( models.Model ):
first_name = models.CharField( max_length=64 )
last_name = models.CharField( max_length=64 )
full_name = models.CharField( max_length=128 )
def save( self, *args, **kw ):
self.full_name = '{0}{1}'.format( first_name, last_name )
super( User, self ).save( *args, **kw )
I guess there would be a better solution.
Thanks. :)
You can either link to the User model and create your own class:
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
def full_name(self):
return self.user.last_name + self.user.first_name
....
or you could subclass the AbstractUser model to define your own custom user attributes there:
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def full_name(self):
return self.last_name + self.first_name
Then in your settings set the default user model to your new class:
AUTH_USER_MODEL = 'myapp.MyUser'
The AbstractUser model only has 3 attributes: password,last_login and is_active. You can define the rest yourself.