addons-cm/website_sale_aplicoop/CHANGELOG.md
GitHub Copilot f2194c5367 [ADD] website_sale_disable_cart: extract cart restriction from website_sale_aplicoop
The "shop as a read-only catalog" behaviour lived inside website_sale_aplicoop,
so every site that wanted the eskaera flow also lost the standard cart. It now
ships as its own installable addon, with the redirect target configurable
instead of hardcoded to /eskaera.

- website_sale_disable_cart: hides the cart UI (12 header styles + the product
  card quick-add) and overrides the standard cart endpoints. Redirect URL is
  configurable in Website settings (default /shop); only site-internal paths are
  accepted, so a misconfigured value cannot turn the shop into an open redirect
  nor loop back into a disabled route.
- Fixes carried over from the original code: /shop/cart/quantity is the Odoo 18
  path (it was /shop/cart_quantity, which never matched), the boxed, sidebar and
  sales two/three/four headers were not covered (the cart link stayed visible on
  them), and the routes now override the standard methods instead of registering
  duplicate ones.
- website_sale_aplicoop 18.0.1.12.0: drops the view file and the four redirect
  routes; installing it no longer touches the standard shop.

Upgrade order matters: update website_sale_aplicoop first, then install
website_sale_disable_cart in a second Odoo run — both use the same XPaths and
obsolete records are only cleaned up at the end of a run.

Tests: 8/8 in website_sale_disable_cart, aplicoop unaffected (its 2 failures
predate this change). Verified live on a DB clone: /shop/cart returns 303 to the
configured URL and no cart markup remains on /shop.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 11:34:59 +02:00

14 KiB

Changelog - Website Sale Aplicoop

[18.0.1.12.0] - 2026-08-06

Removed

  • Standard cart restriction extracted to website_sale_disable_cart: the cart UI removal (header cart link, add-to-cart buttons) and the /shop/cart* route redirects no longer live in this module, so installing Aplicoop leaves the standard website_sale shop untouched. Sites that want the previous behaviour must install website_sale_disable_cart and set its Cart Redirect URL to /eskaera. The new module also fixes the route paths (Odoo 18 uses /shop/cart/quantity, not /shop/cart_quantity), covers the 5 header styles that were missing (boxed, sidebar, sales two/three/four — the header cart link was still visible on those) and overrides the standard endpoints instead of registering duplicate ones. Upgrade order matters: update this module first (so its old templates are dropped) and install website_sale_disable_cart in a second Odoo run — both sets of templates use the same XPaths and obsolete records are only cleaned up at the end of a run, so a single combined run fails.

[18.0.1.11.0] - 2026-07-15

Added

  • Non-weekly cycle automation: one-time (special/promotional), biweekly and monthly group orders now follow the same cron confirmation flow as weekly orders (confirm linked sale orders + batch their pickings once the cycle cutoff passes).
  • Biweekly/monthly recurrence: these periods keep the weekday scheme (cutoff_day/pickup_day) but on a recurrence grid anchored at start_date (creation date as fallback): cutoffs advance every 14 days / 1 month (snapped to cutoff_day), with automatic catch-up if the cron was down. Previously they behaved as weekly.
  • One-time orders: their single cycle is driven by end_date (cutoff_date = end_date); once it passes, the cron confirms, batches and closes the group order automatically.

Changed

  • end_date keeps its "permanent if empty" meaning for all recurring periods; it only closes the cycle for one-time orders.
  • Draft-cart lookup window on the website is now period-aware (7/14 days, 1 month, or the full order lifetime for one-time orders) instead of always 6 days.

[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 aplicoopShopgroupOrderShop 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/<order_id>/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.)