Group orders are not confirmed until the cutoff date, so draft/sent
sale.order lines never generate stock.moves and are invisible to
virtual_available. This change makes the shop aware of that demand.
- group.order._compute_draft_sale_demand: queries sale.order.line in
draft/sent state (mirroring sale_stock forecasted report logic) and
returns pending demand per product.id in the product's own UoM.
- _get_products_for_group_order: delegates to new _apply_stock_filter_and_sort
which excludes storable products whose forecasted net qty
(virtual_available − draft demand) <= 0, unless allow_out_of_stock_order.
- _compute_stock_ribbons: reads draft_demand_by_product from ORM context
so is_out_of_stock / is_low_stock / dynamic_ribbon_id reflect net qty.
- Controller: new _prepare_draft_stock_data helper calculates demand once
per request, injects context, and builds product_max_qty dict. Applied
in eskaera_shop, load_eskaera_page and load_products_ajax.
- Template: qty input gets max and data-max-qty from product_max_qty.
- JS: blocks add-to-cart if requested quantity exceeds data-max-qty.
- Fixes type check: type=='consu' → is_storable=True (Odoo 18 semantics).
- 21 new tests in test_forecasted_stock.py covering demand calculation,
ribbon logic with context, and group order filtering.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use forecasted quantity (virtual_available) instead of on-hand quantity
(qty_available) for out-of-stock and low-stock calculations, so pending
incoming/outgoing moves are taken into account.
Added website_sale_stock dependency and modified _compute_stock_ribbons
to respect the allow_out_of_stock_order field:
- If allow_out_of_stock_order=True: product can always be added to cart
- If allow_out_of_stock_order=False and qty<=0: add-to-cart is blocked
The JS logic already checks data-out-of-stock attribute from template,
so no frontend changes were needed.
Version bump: 18.0.1.7.0 -> 18.0.1.8.0
- Añadidos ribbons 'Sin Stock' (rojo) y 'Pocas Existencias' (amarillo)
- Nuevo campo configurable: umbral de stock bajo (default: 5.0)
- Campos computed en product.product:
* is_out_of_stock: True cuando qty_available <= 0
* is_low_stock: True cuando 0 < qty_available <= threshold
* dynamic_ribbon_id: ribbon automático según nivel de stock
- Ordenamiento mejorado: productos con stock primero, sin stock al final
- Template actualizado:
* Muestra ribbon de stock en tarjeta de producto
* Deshabilita botón add-to-cart cuando producto sin stock
* Cambia icono a 'fa-ban' en productos sin stock
- Vista de configuración: campo 'Low Stock Threshold' en Settings > Shop Performance
- Solo aplica a productos type='consu' (almacenables)
- Tests: 112 pasados, 0 fallos
- Remove redundant string= from 17 field definitions where name matches string value (W8113)
- Convert @staticmethod to instance methods in selection methods for proper self.env._() access
- Fix W8161 (prefer-env-translation) by using self.env._() instead of standalone _()
- Fix W8301/W8115 (translation-not-lazy) by proper placement of % interpolation outside self.env._()
- Remove unused imports of odoo._ from group_order.py and sale_order_extension.py
- All OCA linting warnings in website_sale_aplicoop main models are now resolved
Changes:
- website_sale_aplicoop/models/group_order.py: 21 field definitions cleaned
- website_sale_aplicoop/models/sale_order_extension.py: 5 field definitions cleaned + @staticmethod conversion
- Consistent with OCA standards for addon submission