Skip to content

[FIX] website_sale_product_minimal_price: crash on shop with lazy request.pricelist (Odoo 19) - #1273

Open
antoineAkyado wants to merge 1 commit into
OCA:19.0from
antoineAkyado:19.0-fix-wspmp-lazy-pricelist
Open

[FIX] website_sale_product_minimal_price: crash on shop with lazy request.pricelist (Odoo 19)#1273
antoineAkyado wants to merge 1 commit into
OCA:19.0from
antoineAkyado:19.0-fix-wspmp-lazy-pricelist

Conversation

@antoineAkyado

Copy link
Copy Markdown

Bug

On the eCommerce shop page, computing the cheapest variant of a product crashes with:

AttributeError: 'product.pricelist' object has no attribute '__ior__'
Traceback
File ".../website_sale/controllers/main.py", line 458, in shop
    variants = request.env['product.product'].sudo().browse(product._get_first_possible_variant_id() for product in products)
File ".../website_sale_product_minimal_price/models/product_template.py", line 111, in _get_first_possible_combination
    product = self._get_cheapest_info(pricelist)[0]
File ".../website_sale_product_minimal_price/models/product_template.py", line 72, in _get_cheapest_info
    variant_items = self._get_pricelist_variant_items(pricelist)
File ".../website_sale_product_minimal_price/models/product_template.py", line 55, in _get_pricelist_variant_items
    visited_pricelists |= pricelist
File ".../odoo/tools/func.py", line 235, in __ior__
    def __ior__(self, other): return self._value.__ior__(other)
AttributeError: 'product.pricelist' object has no attribute '__ior__'

Root cause

Two Odoo 19 changes combine to trigger this:

  1. request.pricelist is now a lazy() proxywebsite_sale/models/ir_http.py:
    request.pricelist = lazy(request.website._get_and_cache_current_pricelist)
    _get_website_current_pricelist() returns it as-is.
  2. Recordsets no longer implement in-place set operatorsBaseModel defines __or__ but not __ior__. For a plain recordset, x |= y falls back to __or__ (fine). For a lazy, lazy.__ior__ (in odoo/tools/func.py) delegates to product.pricelist.__ior__, which no longer exists -> AttributeError.

_get_pricelist_variant_items() does visited_pricelists |= pricelist, where visited_pricelists was initialised from the lazy request.pricelist.

How to reproduce

  • A product with more than one variant (product_variant_count > 1).
  • A pricelist with sub-pricelists (items with compute_price = 'formula', base = 'pricelist', base_pricelist_id set), so the while next_pricelists: loop actually runs and reaches visited_pricelists |= pricelist.
  • Open the shop page -> crash. (A flat pricelist never enters the loop, which is why it is not hit by everyone.)

Fix

_get_website_current_pricelist now materialises the pricelist into a real recordset, so downstream in-place set operations keep working. The existing test is updated to reproduce the lazy scenario as a regression test.

@OCA-git-bot

Copy link
Copy Markdown
Contributor

Hi @sergio-teruel,
some modules you are maintaining are being modified, check this out!

@OCA-git-bot OCA-git-bot added series:19.0 mod:website_sale_product_minimal_price Module website_sale_product_minimal_price labels Aug 3, 2026
…icelist (v19)

In Odoo 19 request.pricelist is a lazy() proxy (website_sale/models/ir_http.py).
_get_website_current_pricelist returned it as-is, so the in-place union in
_get_pricelist_variant_items (visited_pricelists |= pricelist) delegated to
product.pricelist.__ior__, removed from recordsets in v19, raising
AttributeError on the shop page for multi-variant products whose pricelist has
sub-pricelists. Materialise the pricelist into a real recordset.
@antoineAkyado
antoineAkyado force-pushed the 19.0-fix-wspmp-lazy-pricelist branch from fec7888 to 5a11429 Compare August 3, 2026 12:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mod:website_sale_product_minimal_price Module website_sale_product_minimal_price series:19.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants