This time I will tell you about my experience with one of the most strange, most unique, and most confusing errors that I have experienced during my career as an Odoo developer. For almost 5 years (when this article was written) I have only encountered this issue once, and it just happened a few months ago. The issue is like this.
Suppose we have a product with the “Stainless Steel Table” name, like in the image below.
In the ERP (backend), if we search the product with “Stainless”, “Steel”, or “Table” keyword, the product is found. Please take a look at the pictures below.
A strange thing happens when we open the Point of Sale (POS) page. Please take a look at the image below.
In the image above we do not search with any keywords, and the product appears on the POS page.
If we search the product with the “Stainless” keyword the result will look like this.
If we search the product with the “Steel” or “Table” keyword, the result will look like these.
It’s strange, right? Why is the “Stainless Steel Table” product suddenly can’t be found?
After spending quite some time, I found out that this error occurs because the product name contains a line break or a new line. I suspect that the user added this product by importing from a spreadsheet file, and coincidentally the product name in the file contains a line break or a new line. I didn’t have the chance to interview the user directly, so I don’t know the real reason. But from the simulation I did, importing from the spreadsheet file is the most plausible reason.
We can reproduce this issue with this action: after we type the “Stainless” word in the Name column in Libre Office, press the CTRL + ENTER key on the keyboard. I don’t know what keys you need to press if you using the Microsoft Excel, please try to googling it with the excel insert new line in cell keyword. Please do the same action with the “Steel” and the “Table” word. The result will look like this.
After importing the spreadsheet file, the data in the database will look like the image below.
From the image above, it is very clear between the product whose names contain the line break and those that do not. Unfortunately, this is not visible if we look at the product name in Odoo, either on the backend or POS, except in the PDF report.
The solution to overcome this error is of course by changing the product name, so it no longer contains the line break or the new line. Or by changing the search logic in Odoo POS. I’ll discuss this issue later, let’s discuss why the search results on the Odoo backend and Odoo POS are different first.
Odoo POS is designed to keep running if the internet or the server is down, so the search functionality is purely done locally with Javascript and the help of regex (regular expression). Meanwhile, in the backend, the search functionality is done by executing a SQL query to the database, so the search results on these 2 pages are different.
Now let’s take a look at the code that handles the search process. Please take a look at search_product_in_category method in Odoo v13 source code here. Actually, I found this error in Odoo v13 and never tried it out in Odoo v14 or in Odoo v15. Please write a comment if you know that this error also occurs in both versions and whether the solution written in this article can be applied there or not.
search_product_in_category: function(category_id, query){ try { query = query.replace(/[\[\]\(\)\+\*\?\.\-\!\&\^\$\|\~\_\{\}\:\,\\\/]/g,'.'); query = query.replace(/ /g,'.+'); var re = RegExp("([0-9]+):.*?"+utils.unaccent(query),"gi"); }catch(e){ return []; } var results = []; for(var i = 0; i < this.limit; i++){ var r = re.exec(this.category_search_string[category_id]); if(r){ var id = Number(r[1]); results.push(this.get_product_by_id(id)); }else{ break; } } return results; },
From the code above, it can be seen that Odoo will search with regex on the category_search_string variable. Now let’s see the value of the category_search_string variable by adding the console.log code like in the code below.
search_product_in_category: function(category_id, query){ console.log(this.category_search_string[category_id]) try { query = query.replace(/[\[\]\(\)\+\*\?\.\-\!\&\^\$\|\~\_\{\}\:\,\\\/]/g,'.'); query = query.replace(/ /g,'.+'); var re = RegExp("([0-9]+):.*?"+utils.unaccent(query),"gi"); }catch(e){ return []; } var results = []; for(var i = 0; i < this.limit; i++){ var r = re.exec(this.category_search_string[category_id]); if(r){ var id = Number(r[1]); results.push(this.get_product_by_id(id)); }else{ break; } } return results; },
The result looks like this.
21:cabinet with doors|e-com11 34:large meeting table|furn_6741|conference room table 53:stainless steel table 54:titanium chair
The [21,34,53,54] text above can be concluded as the id of the product (id of the product.product model not the id of the product.template model). Please execute the following query to make sure.
select p_template.name, p_product.id from product_product as p_product join product_template as p_template on p_template.id = p_product.product_tmpl_id where p_product.id in (21,34,53,54);
Because the product with the name of “Stainless Steel Table” contains the line break or the new line, the product name is separated into several lines. Therefore, when we search with the “Stainless” keyword, on that line it still has the id of the product we are looking for, so the product appears in the search result.
But, if we search with the “Steel” or the “Table” keyword, on that line there is no id of the product we are looking for, so the product does not appear in search result.
There are several solutions that we can try to solve this issue, one of it is to delete the line break directly in the database, by writing an SQL code. Personally, I prefer to remove it with the Javascript code. For this reason: I don’t need to write the SQL code again if the user adds a new product, or if the user intentionally adds the line break to format the product name in the PDF report.
We can also override the create and the write method to remove the line break. Or just ignore it, and ask the user to sell the product in POS using a barcode scanner, because this error does not occur if we search for the product with a barcode scanner. Please talk to your team/client, about which is the most ideal solution for them.
Here is the code that I use to remove the line break with Javascript when the POS page is loaded.
odoo.define('remove_linebreak_in_product_name.pos_db', function (require) { "use strict"; var PosDB = require('point_of_sale.DB'); PosDB.include({ _product_search_string: function(product){ var result = this._super.apply(this, arguments); return result.replace(/(\r\n|\n|\r)/gm, ' ') + '\n'; }, }); });