[FIX] stock: filter invalid input from domain

When the user tries to find the 'qty_available' of a product but gives
a string value instead of a float value in domain then the user will face error.

Steps to produce:
- Install `stocks`.
- Create a record rule for model `product.template`. In the domain of record
  rule keep [('qty_available', '<', '10')] as a domain,
  you can give any integral value in the domain but that value should be
  enterred as strings (with quotes).
- Inventory > Products > Products

Error: `TypeError: '<' not supported between instances of 'str' and 'float' `

After applying our commit, if the domain is Invalid then the user will face
`UserError`. There is a function named `_search_product_quantity`  which
initially checks if the domain is valid or not :
https://github.com/odoo/odoo/blob/5f1ad0c1e4c1e8ed41337ccd4c12e70c9c760c85/addons/stock/models/product.py#L342-L350
It will filter out all the invalid domain and clear search methods.
So now whenever `_search_qty_available` is called first the validity of domain
and operands of the expression will be checked.

sentry-4399815131

closes odoo/odoo#137367

X-original-commit: 92c232cca15517bd9a33a5100e7cdc42c3c25397
Signed-off-by: Tiffany Chang (tic) <tic@odoo.com>
This commit is contained in:
Saurabh Mishra
2023-10-03 16:55:47 +00:00
parent c23ab615d8
commit 75a1e2a2d3
2 changed files with 9 additions and 4 deletions
+3 -3
View File
@@ -3623,16 +3623,16 @@ msgstr ""
#. module: stock
#. odoo-python
#: code:addons/stock/models/product.py:0
#: code:addons/stock/models/product.py:0 code:addons/stock/models/product.py:0
#, python-format
msgid "Invalid domain operator %s"
msgstr ""
#. module: stock
#. odoo-python
#: code:addons/stock/models/product.py:0
#: code:addons/stock/models/product.py:0 code:addons/stock/models/product.py:0
#, python-format
msgid "Invalid domain right operand %s"
msgid "Invalid domain right operand '%s'. It must be of type Integer/Float"
msgstr ""
#. module: stock
+6 -1
View File
@@ -353,7 +353,7 @@ class Product(models.Model):
if operator not in ('<', '>', '=', '!=', '<=', '>='):
raise UserError(_('Invalid domain operator %s', operator))
if not isinstance(value, (float, int)):
raise UserError(_('Invalid domain right operand %s', value))
raise UserError(_("Invalid domain right operand '%s'. It must be of type Integer/Float", value))
# TODO: Still optimization possible when searching virtual quantities
ids = []
@@ -366,6 +366,11 @@ class Product(models.Model):
def _search_qty_available_new(self, operator, value, lot_id=False, owner_id=False, package_id=False):
''' Optimized method which doesn't search on stock.moves, only on stock.quants. '''
if operator not in ('<', '>', '=', '!=', '<=', '>='):
raise UserError(_('Invalid domain operator %s', operator))
if not isinstance(value, (float, int)):
raise UserError(_("Invalid domain right operand '%s'. It must be of type Integer/Float", value))
product_ids = set()
domain_quant = self._get_domain_locations()[0]
if lot_id: