# Changelog - Website Sale Aplicoop ## [18.0.1.9.0] - 2026-05-20 ### Added - **Category sequence**: New `sequence` field on `product.category` for controlling product display order on the web shop. Migration adds the column with default 10. - **Stock availability check on history orders**: When loading a historical order, products are validated against current stock (`virtual_available`). Out-of-stock items are flagged before adding to cart. ### Changed - **Cart disabled / redirected to /eskaera**: Standard `website_sale` cart is fully hidden — header cart icon removed, add-to-cart buttons removed from standard shop, `/cart` and `/shop` routes redirect to `/eskaera`. Customers interact exclusively through the group order flow. - **Product card UI overhaul**: Improved responsive layout, placeholder image for products without photo, better accessibility markup, and professional styling for mobile. - **Stock check uses `virtual_available`**: Replaces `qty_available` so forecasted quantity (including incoming moves) is considered. ### Fixed - Lint fixes: exception chaining (`raise ... from exc`), unused imports/vars, `disable attribute-string-redundant` annotations. --- ## [18.0.1.8.0] - 2026-04-08 ### Added - **Clear cart button**: New button in the sidebar to empty the current group order cart in one click (`eskaera_clear_cart` route). ### Changed - **Portal access restricted to consumer group**: Portal users can only see group orders belonging to their consumer group. Security rule `rule_group_order_company_read` updated with `user.share` guard. - **Controller filtering by consumer group**: `eskaera_list` and `eskaera_shop` routes filter orders by the logged-in user's consumer group, not just by company. ### Fixed - Stale cart invalidation: carts linked to closed/cancelled group orders are cleared on next access. - Home delivery draft flow: fixed state transition for home delivery orders. - Auto-confirm `sale.order` on cutoff day: fixed off-by-one (`>` vs `>=`) in cutoff guard so orders on the cutoff day are correctly confirmed. - Pickup dates frozen after cron confirm: cron no longer overwrites pickup dates on already-confirmed orders. - Cron hardened against missing/invalid group order configurations. - Cart layout: moved cart sidebar before product grid. - i18n: added missing ES/EU translations for checkout, cart labels, Save Draft button, and weekday strings. Removed legacy `week_draft` translation keys. --- ## [18.0.1.7.0] - 2026-03-06 ### Added - **Automatic batch picking creation**: After the cutoff cron confirms sale orders, picking batches are automatically created grouped by consumer group and pickup date. - **Consumer group propagation**: `consumer_group_id` is now propagated directly from the `group.order` to linked `sale.order` records, eliminating manual assignment. - **Out-of-stock blocking**: Add-to-cart button is hard-disabled for out-of-stock products. `allow_out_of_stock_order` flag on product is respected. ### Changed - **Cron auto-confirm sale orders**: Daily cron (`_cron_confirm_group_orders`) now confirms linked sale orders on the cutoff date instead of requiring manual action. - **Order card meta extracted**: Order card metadata (dates, state badge) moved to a reusable `_eskaera_order_card_meta` template for cleaner rendering. - Delivery toggle (reparto/envío a domicilio) wired directly from the cart sidebar. - Pricing alignment: theoretical price and displayed price reconciled for orders with home delivery. ### Fixed - Fixed broken `aplicoopShop` → `groupOrderShop` JS class reference. - Ensured add-to-cart event listeners are re-attached after infinite scroll loads new products. - i18n: translated weekday names (ES/EU). --- ## [18.0.1.6.0] - 2026-02-22 ### Added - **Category Blacklist Feature**: Category-based exclusion system for group orders - New field: `excluded_category_ids` (Many2many to product.category) - Recursive exclusion: Excludes products in selected categories AND all subcategories - Blacklist has absolute priority over all inclusion sources - Helper method: `get_all_excluded_descendants()` for recursive category tree traversal - Comprehensive test suite in `test_product_discovery.py` (TestCategoryBlacklist class with 9 tests) ### Changed - **Product Discovery Logic**: Extended to filter by category blacklist - `_get_products_for_group_order()` now applies `excluded_category_ids` filter recursively - Products in excluded categories and their subcategories are filtered out - `_compute_available_products_count()` now depends on `excluded_category_ids` - Detailed logging for excluded categories and affected products - **UI Updates**: "Productos Excluidos" section now includes three blacklist types: - `excluded_supplier_ids`: Blacklist suppliers - `excluded_category_ids`: Blacklist categories (recursive) - `excluded_product_ids`: Blacklist specific products ### Technical Details - New M2M relation: `group_order_excluded_category_rel` - Recursive logic: Walks category tree to find all descendants - Filter logic: `products.filtered(lambda p: p.categ_id not in all_excluded_categories)` - Works in combination with product and supplier blacklists (all filters apply) ### Use Case - Admin wants to exclude all products in a category and its subcategories - Example: Exclude "Fresh Produce" → automatically excludes "Fruits", "Vegetables", etc. - Add parent category to inclusion → add problematic subcategory to exclusion - Result: Fine-grained control over product catalog with minimal configuration ## [18.0.1.5.0] - 2026-02-22 ### Added - **Supplier Blacklist Feature**: New exclusion system by supplier for group orders - New field: `excluded_supplier_ids` (Many2many to res.partner) - Filters products by `main_seller_id` (from product_main_seller addon) - Blacklist has absolute priority over all inclusion sources - Products whose main supplier is blacklisted never appear - Comprehensive test suite in `test_product_discovery.py` (TestSupplierBlacklist class with 9 tests) ### Changed - **Product Discovery Logic**: Extended to filter by supplier blacklist - `_get_products_for_group_order()` now applies `excluded_supplier_ids` filter - Products with `main_seller_id` in excluded_supplier_ids are filtered out - `_compute_available_products_count()` now depends on `excluded_supplier_ids` - Detailed logging for excluded suppliers and affected products - **UI Updates**: "Productos Excluidos" section now includes both: - `excluded_supplier_ids`: Blacklist suppliers - `excluded_product_ids`: Blacklist specific products ### Technical Details - New M2M relation: `group_order_excluded_supplier_rel` - Filter logic: `products.filtered(lambda p: p.product_tmpl_id.main_seller_id not in excluded_supplier_ids)` - Works in combination with product blacklist (both filters apply) - Uses `main_seller_id` from product_main_seller addon (NOT default_supplier_id) ### Use Case - Admin wants to exclude all products from a specific supplier (e.g., temporary unavailability) - Add category with 100 products → add problematic supplier to excluded_supplier_ids - Result: All products from that supplier are excluded, even if directly included - Combined workflow: Category inclusion + supplier exclusion + individual product exclusion ## [18.0.1.4.0] - 2026-02-22 ### Added - **Product Blacklist Feature**: New exclusion system for group orders - New field: `excluded_product_ids` (Many2many to product.product) - Blacklist has absolute priority over all inclusion sources (product_ids, category_ids, supplier_ids) - Model method: Updated `_get_products_for_group_order()` with blacklist filter - Comprehensive test suite in `test_product_discovery.py` (TestProductBlacklist class) ### Changed - **UI Improvements**: Renamed "Associations" section to "Catálogo de Productos" for better user clarity - New subsection: "Productos Incluidos" (whitelist: suppliers, categories, direct products) - New subsection: "Productos Excluidos" (blacklist: explicit exclusions) - Updated help texts for all inclusion fields - Complete Spanish and Euskera translations - **Product Discovery Logic**: - `_get_products_for_group_order()` now applies `excluded_product_ids` filter at the end - Products in blacklist never appear, regardless of inclusion source - `_compute_available_products_count()` now depends on `excluded_product_ids` - Detailed logging for excluded product count ### Technical Details - New M2M relation: `group_order_excluded_product_rel` (separate from whitelist relations) - Blacklist filter uses set subtraction: `products = products - order.excluded_product_ids` - All tests validate absolute priority: direct products, category products, supplier products, and multi-source products all respect blacklist ### Use Case - Admin selects a category with 100 products → adds to category_ids - Admin identifies 5 unwanted products → adds to excluded_product_ids - Result: 95 products available in the order - Workflow: Bulk inclusion via categories/suppliers + fine-grained exclusion via blacklist ## [18.0.1.3.0] - 2026-02-16 ### Added - **Lazy Loading Feature**: Configurable product pagination for significantly faster page loads - New Settings: `Enable Lazy Loading`, `Products Per Page` - New endpoint: `GET /eskaera//load-page?page=N` - JavaScript method: `_attachLoadMoreListener()` - Model method: `group_order._get_products_paginated()` - **Configuration Parameters**: - `website_sale_aplicoop.lazy_loading_enabled` (Boolean, default: True) - `website_sale_aplicoop.products_per_page` (Integer, default: 20) - **Frontend Components**: - New template: `eskaera_shop_products` (reusable for initial page + AJAX) - Load More button with pagination controls - Spinner during AJAX load ("Loading..." state) - Event listener re-attachment for dynamically loaded products - **Documentation**: - Complete lazy loading guide: `docs/LAZY_LOADING.md` - Configuration examples - Troubleshooting section - Performance metrics ### Changed - Template `eskaera_shop`: - Products grid now has `id="products-grid"` - Calls reusable `eskaera_shop_products` template - Conditional "Load More" button display - JavaScript `website_sale.js`: - `_attachEventListeners()` now calls `_attachLoadMoreListener()` - Re-attaches listeners after AJAX loads new products - README.md: - Added lazy loading feature to features list - Added version 18.0.1.3.0 to changelog ### Performance Impact - **Initial page load**: 10-20s → 500-800ms (20x faster) - **Product DOM size**: 1000 elements → 20 elements (initial) - **Subsequent page loads**: 200-400ms via AJAX - **Price calculation**: Only for visible products (reduced from 1000+ to 20) ### Technical Details - Zero-impact if lazy loading disabled - Transparent pagination (no URL changes) - Maintains cart synchronization - Compatible with existing search/filter - No changes to pricing logic or validation --- ## [18.0.1.2.0] - 2026-02-02 ### Added - Improved UI elements in cart and checkout ### Fixed - Pickup date calculation (was adding extra week) - Delivery date display on order pages ### Changed - Cart styling: 2x text size, larger icons - Checkout button: Enhanced visibility --- ## [18.0.1.0.0] - 2024-12-20 ### Added - Initial release of Website Sale Aplicoop - Group order management system - Multi-language support (ES, PT, GL, CA, EU, FR, IT) - Member management and tracking - Order state machine (draft → confirmed → collected → invoiced → completed) - Separate shopping carts per group order - Cutoff and pickup date validation - Integration with OCA ecosystem (pricing, taxes, etc.)