Skip to content

[ADD] website_sale_stock_variant_preselect: preselect variant with stock - #482

Open
ALopez-Adhoc wants to merge 1 commit into
ingadhoc:19.0from
adhoc-dev:19.0-t-72834-loa
Open

[ADD] website_sale_stock_variant_preselect: preselect variant with stock#482
ALopez-Adhoc wants to merge 1 commit into
ingadhoc:19.0from
adhoc-dev:19.0-t-72834-loa

Conversation

@ALopez-Adhoc

Copy link
Copy Markdown
Contributor

Nuevo módulo website_sale_stock_variant_preselect.

Problema

En la ficha de un producto con variantes, cuando el visitante entra sin elegir atributos, Odoo preselecciona siempre la primera combinación en el orden de configuración (_get_first_possible_combination), sin mirar stock. Si esa primera variante está agotada, la ficha se renderiza como sin stock y el visitante puede creer que todo el producto lo está, aunque haya otros talles o colores disponibles.

Solución

Cuando la ficha resuelve la combinación por defecto, se prefiere la primera variante con stock siguiendo el mismo orden configurado de atributos. Si ninguna tiene stock, se mantiene el comportamiento actual.

Diseño

  • product.template._get_first_available_combination() recorre _get_possible_combinations() —que respeta el orden de attribute_line_ids y sus valores, el mismo que ve el visitante en el selector— y lo cruza contra el conjunto de variantes con stock. No se usa el orden de product_variant_ids, cuyo _order (default_code, name, id) no tiene relación con el orden configurado.
  • La disponibilidad se resuelve con website._get_product_available_qty(), no leyendo free_qty directo: así se respetan el almacén del sitio y la sucursal de sesión de website_sale_collect. El cálculo se batchea sobre product_variant_ids aprovechando el prefetch del recordset, de modo que _compute_quantities_dict se resuelve en un _read_group y no en una query por variante.
  • El enganche es _get_combination_info, pero acotado por contexto: el controller marca website_sale_preselect_available_variant sobre el registro del producto, no sobre el request. Así llega solo al _get_combination_info() de la ficha y no al del listado ni al de los bloques de producto del sitio, que quedan con el comportamiento de core. Es el mismo patrón que usa website_sale_stock con website_sale_stock_get_quantity.
  • Se sale temprano cuando la disponibilidad no dice nada: template no almacenable, allow_out_of_stock_order activo (que es el default), una sola variante, o ninguna variante con stock.
  • Módulo aparte en vez de extender website_sale_ux, que hoy depende solo de website_sale: sumarle website_sale_stock le impondría stock a todos los que ya lo usan.
  • Parámetro de sistema website_sale_stock_variant_preselect.enabled, encendido por default, como interruptor interno para apagarlo en una base puntual sin esperar un release. No se expone en ninguna pantalla de configuración: no es una opción del cliente.

Test plan

tests/test_variant_preselect.py, 9 casos sobre WebsiteSaleStockCommon (producto de tres talles, stock solo en el segundo):

  • preselecciona la primera con stock cuando la primera en secuencia está agotada
  • con dos variantes con stock, gana la primera en el orden configurado
  • no cambia nada cuando la primera en secuencia ya tiene stock
  • cae al comportamiento de core sin stock en ninguna variante
  • se saltea con allow_out_of_stock_order y con templates no almacenables
  • el parámetro de sistema en False restaura el comportamiento de core
  • el controller preselecciona en la ficha y respeta attribute_values explícito
0 failed, 0 error(s) of 9 tests

Probado además contra una base local: la ficha renderiza el radio de la variante con stock ya marcado en el primer response HTML, sin round-trip JS.

Tarea: https://www.adhoc.inc/odoo/project.task/72834

- Add product.template._get_first_available_combination, walking
  _get_possible_combinations in the configured attribute order and matching it
  against the set of variants that have stock
- Override _get_combination_info to use it when the caller passed no
  combination, product_id nor only_template, guarded by the
  website_sale_preselect_available_variant context key
- Override WebsiteSale._prepare_product_values to set that key on the product
  record only, so the shop grid and the website product blocks keep core
  behaviour
- Resolve availability through website._get_product_available_qty, batched over
  product_variant_ids, to honour the website warehouse and the
  website_sale_collect session branch
- Fall back to core when the template is not storable, allows out-of-stock
  orders, has a single variant, or when no variant has stock
- Add the website_sale_stock_variant_preselect.enabled system parameter as an
  internal kill switch, enabled by default
- Add tests for preselection, configured order, every fallback, the kill switch
  and both controller paths

Change note: En la ficha de un producto con variantes, la tienda ahora abre
mostrando una variante que tenga stock en lugar de la primera configurada.
Antes, si la primera variante estaba agotada, la ficha se veía como sin stock y
muchos visitantes creian que todo el producto lo estaba, aunque hubiera otros
talles o colores disponibles. Si el visitante elige atributos, se respeta
siempre su eleccion, y el listado de la tienda no cambia.
Copilot AI lite review requested due to automatic review settings September 4, 2026 18:39
@roboadhoc

Copy link
Copy Markdown
Contributor

Pull request status dashboard

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Hay ajustes menores pero concretos por resolver (robustez del helper de tests y consistencia de metadatos en el manifest) antes de aprobar.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Este PR agrega el módulo website_sale_stock_variant_preselect para mejorar la UX en la ficha de producto con variantes: cuando el visitante entra sin seleccionar atributos, se preselecciona la primera combinación con stock respetando el orden configurado de atributos, y si ninguna tiene stock se mantiene el comportamiento estándar.

Changes:

  • Override de product.template._get_combination_info() para usar una combinación “stock-aware” solo cuando el controller lo solicita por contexto.
  • Implementación de _get_first_available_combination() para elegir la primera variante disponible según el orden de atributos.
  • Suite de tests (9 casos) que valida preselección, fallback a core, kill-switch y respeto de attribute_values.
File summaries
File Description
website_sale_stock_variant_preselect/models/product_template.py Lógica principal de preselección por stock y kill-switch vía ir.config_parameter.
website_sale_stock_variant_preselect/controllers/main.py Inyecta el contexto para limitar el comportamiento a la ficha de producto.
website_sale_stock_variant_preselect/tests/test_variant_preselect.py Casos de prueba para validar preselección, fallback y control por parámetro/contexto.
website_sale_stock_variant_preselect/tests/init.py Registro del módulo de tests.
website_sale_stock_variant_preselect/models/init.py Registro de modelos.
website_sale_stock_variant_preselect/controllers/init.py Registro de controllers.
website_sale_stock_variant_preselect/manifest.py Manifest del nuevo módulo y dependencia con website_sale_stock.
website_sale_stock_variant_preselect/init.py Carga de controllers y models del módulo.
Review details
  • Files reviewed: 8/8 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +21 to +25
"name": "Website Sale Stock Variant Preselect",
"version": "19.0.1.0.0",
"author": "ADHOC SA",
"website": "www.adhoc.com.ar",
"license": "AGPL-3",
Comment on lines +62 to +66
@classmethod
def _variant_for(cls, attribute_value):
return cls.product.product_variant_ids.filtered(
lambda variant: attribute_value in variant.product_template_attribute_value_ids.product_attribute_value_id
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants