Commit graph

46 commits

Author SHA1 Message Date
GitHub Copilot
5de7573fba [IMP] website_sale_aplicoop: accessibility and responsive polish — phase 8
Quantity control layout: changed from wrapping flex to deliberate two-row
grid so the add-to-cart button sits full-width underneath the stepper,
avoiding accidental line breaks and giving the primary action more pulsing
area. Also removed the /Kg suffix's redundant font rules.

Order card delivery row: reordered to badge-then-date (visually centred),
removed the "Delivery" label, and swapped bg-primary to text-bg-primary for
proper contrast on the home-delivery badge (3.13:1 minimum).

Tooltip translations: moved hardcoded static tooltips from data-bs-title
(untranslatable) to title (QWeb-translatable). Handled the edge case of
"Save Cart" and "Back to Cart" which had translations but no model_terms
reference in the POT, causing the merge to discard them — added the view
reference so translations now apply.

Load-from-history page: added accessibility: a visible status message
("Loading your order…"), a <noscript> fallback with link to the group
order, lang and viewport meta tags, and localised strings for all three
languages. Gave the page a minimal inline style block since it does not
inherit the token system (no website.layout).

Translations: 11 new entries (es/eu/ca) for new/reworded UI strings, plus
two code catalogue entries (products found, Close) that needed the
#. odoo-python comment for _() resolution. Documented the silent-failure
pattern in docs/TRANSLATIONS.md: the POT merge, untranslatable attributes,
and missing code comments.

Tests: 246 passing. Pre-commit: clean.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 11:34:38 +02:00
GitHub Copilot
23edee6154 [IMP] website_sale_aplicoop: readable slug in the group order URL
Group order pages were published under their database id (`/eskaera/1`), which
says nothing to the member opening the link. `group.order` gains a `slug` field
and the public pages move to `/eskaera/<slug>` (e.g. `/eskaera/escola-fructuos`).

The slug is generated from the order name on creation, is unique, and can be
edited under the name on the form; emptying it regenerates it from the current
name. Values that would make the order unreachable are rejected: a plain number
(the legacy numeric URLs win that match) and the static routes served under
`/eskaera/` (`labels`, `save-order`, `i18n`, ...).

`/eskaera/<id>` and `/eskaera/<id>/checkout` are kept as redirects to their slug
URL, so the links already shared with members keep working. The AJAX endpoints
(`load-page`, `save-order`, `confirm`, ...) stay numeric: they never show up in
the address bar. Consequently the frontend now reads the order id from the
`data-order-id` attribute only, as the URL no longer carries it.

The post-migration script fills the slug of the orders that already existed.

Renaming the `/eskaera` prefix itself (`/escolas` for a schools deployment)
needs no code: a *308 Redirect / Rewrite* rule per public route in Website >
Configuration > Redirects serves the pages on the new prefix, rewrites the
links in the templates and redirects the old URLs, per website. Documented in
`readme/CONFIGURE.rst`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 16:49:54 +02:00
GitHub Copilot
1d6747e703 [IMP] website_sale_aplicoop: filter and cap stock using forecasted net qty
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>
2026-06-12 18:18:40 +02:00
GitHub Copilot
9484f8c349 [FIX] website_sale_aplicoop: split cart and cycle stamp in localStorage
965c5c2 stored the cart as {cutoff_date, items: {...}} in
eskaera_<id>_cart. That broke every other reader of the same key:

- checkout_labels.js iterates Object.keys() expecting product IDs and
  rendered "cutoff_date" / "items" as ghost rows → users on the
  checkout page saw their cart as empty.
- home_delivery.js read/wrote the cart in place; the in-place mutation
  destroyed the wrapper.
- _saveOrderDraft serialised the same object straight to the server,
  POSTing "cutoff_date" and "items" as productIds.

Split the schema: eskaera_<id>_cart keeps the plain {productId: {...}}
shape every other JS file already relies on; the cycle marker moves to
eskaera_<id>_cart_cycle. _loadCart migrates browsers still holding the
v18.0.1.10.0 wrapped value on the next read.

Also make eviction strictly opt-in: drop the cart only when we know
the current cycle AND the stored cycle disagrees. Missing data on
either side (check-status didn't run, XHR failed) → preserve. This
restores the checkout page where check-status isn't called.

Version bump triggers the in-tab auto-reload added in 6e6d1e5 for
clients already on that build.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 15:37:55 +02:00
GitHub Copilot
6e6d1e5256 [IMP] website_sale_aplicoop: signal frontend to reload on deploy
When we ship a JS-only fix, users with a long-lived tab keep running
the old code until they hard-refresh — there is no clean way to push
new code to an already-loaded page. Now /eskaera/check-status returns
the module's installed_version as client_version, and the eskaera
page embeds the same version in data-build-version on the cart
container. The JS captures the page's build version at init; on every
check-status response it compares them and triggers window.location.
reload() on mismatch. A sessionStorage timestamp guards against
reload loops if the versions stay disagreeing (cached HTML upstream).

The version bump in __manifest__.py also invalidates the asset bundle
URL hash, so even users without this signalling path get fresh JS on
their next navigation.

This is forward-looking: clients on the old JS (no check) still need
one manual refresh today, but every future deploy will auto-recover.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 15:31:37 +02:00
GitHub Copilot
965c5c2495 [FIX] website_sale_aplicoop: stamp localStorage cart with cycle and evict on rollover
The cart was reappearing on stage with ghost items that had never been
saved as drafts on the server. Root cause: the localStorage cart had no
cycle awareness. Users who added items but never clicked Save left the
items in localStorage forever, and the only existing eviction path
(_clearCurrentOrderCartSilently via _checkGroupOrderStatus) only fires
when cutoff_passed flips true — which it rarely does, because the
stored cutoff_date is normally in the future for an active cycle. On
the next visit, _loadCart happily rehydrated the stale items and
_autoLoadDraftOnInit short-circuited because the cart was no longer
empty.

Stamp every cart written to localStorage with the cutoff_date it
belongs to and reject on cycle mismatch in _loadCart. The cutoff_date
is captured from /eskaera/check-status (which already returned it).
Legacy unstamped values and corrupt JSON are also dropped, so existing
browsers self-heal on first reload after the deploy.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 15:14:04 +02:00
GitHub Copilot
b01794c319 [FIX] website_sale_aplicoop: clear cart when group order cutoff has passed
Previously, when a user reopened a group order whose cutoff day had
already passed, the /eskaera/check-status response correctly triggered
the localStorage cart clear, but _autoLoadDraftOnInit immediately
re-fetched the previous cycle's draft sale.order from /eskaera/load-draft
(which only guarded on group_order.state, not cutoff_date) and the stale
items reappeared in the cart, confusing users.

Add a cutoff_date < today guard to load_draft_cart so the endpoint
returns the existing clear_cart unavailable response, and short-circuit
_autoLoadDraftOnInit on the frontend via a _skipDraftAutoLoad flag set
in _checkGroupOrderStatus to avoid the now-pointless XHR round trip.

Covered by a new regression test in tests/test_group_order_status_endpoint.py.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 13:51:37 +02:00
GitHub Copilot
5eea3e2a23 [IMP] website_sale_aplicoop: improve i18n label fallbacks and response parsing
Add hardcoded fallback translations for es/eu when PO-based translation
returns the source string unchanged. Expand labels dict with all keys
needed by the frontend. Fix JSON response parsing in template
(data.result || data). Add js_translations keys. Add pot file for
stock_picking_batch_custom.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 12:28:33 +02:00
GitHub Copilot
98fe8676ea group order form notebook 2026-05-21 17:37:22 +02:00
GitHub Copilot
f983d71ea3 [FIX] website_sale_aplicoop: fix account.tax access error and duplicate home-delivery handler
Add sudo() to pricelist_item and fiscal position fallback in _get_pricing_info
so portal users can price the delivery product without triggering an AccessError
on account.tax. Remove the redundant #home-delivery-btn click handler from
website_sale.js — home_delivery.js already owns that button via
bindShopHomeDeliveryButton(), which manages the active class and localStorage cart.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 18:20:02 +02:00
GitHub Copilot
27097004fb [FIX] website_sale_aplicoop: wire home delivery preference through all save flows
Three bugs prevented home_delivery from reaching sale.order:

1. #home-delivery-btn (shop sidebar) had no JS handler — clicking it did
   nothing. Now it toggles active state and persists choice to sessionStorage.

2. _executeSaveCartAsDraft (Save Cart button) never included is_delivery in
   the request body. Now reads the toggle button state (or the page-level
   data-home-delivery-enabled fallback) and sends is_delivery correctly.

3. #home-delivery-checkbox on checkout page was unchecked by default and
   always shown. Now it is pre-checked when group_order.home_delivery is
   True, wrapped in t-if to hide it when delivery is not configured, and
   synced bidirectionally with sessionStorage so the shop-page toggle state
   carries over to checkout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 17:57:07 +02:00
GitHub Copilot
eb81e7db6a [IMP] website_sale_aplicoop: ajustar CSS tarjeta producto — placeholder y compresión móvil
- product-img-cover: max-height → height fija para que placeholder y imagen
  real ocupen exactamente el mismo bloque (120px/90px/60px según breakpoint)
- product-img-placeholder: reemplaza SVG inline por flex centrado, más limpio
- Reducir padding/márgenes generales en card-body, title, supplier, tags y precio
- Dos breakpoints responsivos: ≤768px (tablet, imagen 90px) y ≤480px (móvil,
  imagen 60px, fuentes y márgenes mínimos)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 17:02:33 +02:00
snt
a997331c2d lint: fix linter warnings (log exceptions, disable attribute-string-redundant, suppress C901 where necessary) 2026-05-20 16:05:14 +02:00
snt
3ca90578ae [IMP] website_sale_aplicoop: Validar disponibilidad de productos al cargar órdenes históricas
- Backend: Agregar método _validate_items_for_group_order() para validar que los productos históricos sigan siendo disponibles en la orden de grupo actual
- Backend: Modificar load_order_from_history() para filtrar solo items disponibles antes de pasar al template
- Backend: Generar mensaje de aviso traducido cuando hay productos no disponibles
- Template: Pasar información de productos no disponibles y warnings al JavaScript
- Frontend: Mostrar notificación de advertencia si hubo productos excluidos durante la carga histórica
- Notas: Esto evita cargar productos que ya no existen en la orden actual debido a cambios en categorías, proveedores o listas negras
2026-05-20 16:05:14 +02:00
snt
1d4971c803 [IMP] website_sale_aplicoop: mejora card producto (placeholder, responsive móvil, accesibilidad y estilo profesional) 2026-05-20 16:05:14 +02:00
snt
e9809b90e9 [FIX] website_sale_aplicoop: fix home delivery draft flow 2026-04-08 00:07:43 +02:00
snt
135967019e [ADD] website_sale_aplicoop: botón limpiar carrito en sidebar
Añade botón 'Clear Cart' (fa-trash) en el header y footer del sidebar
del carrito en la página de lista de productos.

Cambios:
- views/website_templates.xml: botón clear-cart-btn en card-header y
  clear-cart-btn-footer en card-footer del sidebar
- controllers/website_sale.py: nuevo endpoint POST /eskaera/clear-cart
  que cancela el sale.order borrador del usuario si existe
- static/src/js/website_sale.js: método _clearCart(), listeners para
  ambos botones (header + footer)
- models/js_translations.py: nuevas cadenas clear_cart, clear_cart_confirm,
  cart_cleared, draft_cancelled
- i18n/es.po, i18n/eu.po: traducciones ES y EU de los nuevos labels
2026-04-07 23:50:30 +02:00
snt
813c8071d9 [I18N] website_sale_aplicoop: remove legacy week draft strings 2026-03-31 19:07:43 +02:00
snt
7e13ffef07 [FIX] website_sale_aplicoop: evitar x2 en carrito y mostrar /Kg en granel 2026-03-30 19:07:57 +02:00
snt
c345699bf4 [FIX] website_sale_aplicoop: invalidate stale carts on closed group orders 2026-03-30 17:39:15 +02:00
snt
c3173a32c9 [IMP] website_sale_aplicoop: extract order card meta to separate template
- Create eskaera_order_card_meta template for cleaner code
- Simplify layout: horizontal meta-grid instead of table
- Fix t-if conditions on container elements
- Show only relevant fields: cutoff, pickup, delivery
- Add meta-grid CSS styles for compact horizontal display
- Home delivery badge only shown when enabled
2026-03-06 14:10:58 +01:00
snt
d3f26120b0 [FIX] website_sale_aplicoop: fix aplicoopShop -> groupOrderShop reference
After infinite scroll loads new products, the event listeners were
never re-attached because the code was looking for window.aplicoopShop
but the actual object is window.groupOrderShop.
2026-03-05 22:03:34 +01:00
snt
9c14e1dc1a [FIX] website_sale_aplicoop: ensure add-to-cart on infinite scroll 2026-03-05 18:57:10 +01:00
snt
eaedf0b421 [FIX] website_sale_aplicoop: hard block out-of-stock button 2026-03-03 15:49:19 +01:00
snt
33c148e6a1 [FIX] website_sale_aplicoop: block out-of-stock add 2026-03-03 15:30:43 +01:00
snt
62a1c4e1e9 [FIX] website_sale_aplicoop: force enable cart buttons 2026-03-03 15:09:16 +01:00
snt
a9c1f1f609 [FIX] website_sale_aplicoop: align pricing and drafts 2026-02-27 19:39:25 +01:00
snt
97dc41d212 [FIX] website_sale_aplicoop: toggle reparto desde carrito 2026-02-27 15:43:59 +01:00
snt
6935d8fc83 [FIX] website_sale_aplicoop: save draft on checkout button 2026-02-27 14:58:20 +01:00
snt
a483925005 demo files 2026-02-27 13:43:56 +01:00
snt
130a5ff6c4 [FIX] website_sale_aplicoop: Arreglar botón Home Delivery en shop (añadir/remover producto de entrega al carrito) 2026-02-26 15:12:06 +01:00
snt
9937e987f4 [I18N] website_sale_aplicoop: Limpieza de traducciones y etiquetas UI en inglés por defecto 2026-02-26 14:33:44 +01:00
snt
1a8f92a01e iconos 2026-02-25 18:41:16 +01:00
snt
92b35ccd6d [FIX] website_sale_aplicoop: step de cantidad correcto tras filtrar categoría. El JS ahora usa data-quantity-step generado por backend, evitando sobrescribir el step correcto en inputs de productos a peso/unidad. 2026-02-25 17:17:06 +01:00
snt
4a4639f13a [DOC] Actualizar documentación a estándares OCA y preparar logo CriptoMart
- Renombrar README.md a README_DEV.md en todos los addons custom
- Crear README.rst siguiendo estructura OCA oficial
- Crear directorios readme/ con fragmentos .rst (DESCRIPTION, INSTALL, CONFIGURE, USAGE, CONTRIBUTORS, CREDITS)
- Actualizar créditos: Criptomart (autor) + Elika Bilbo (financiador)
- Actualizar __manifest__.py con maintainers correctos
- Crear estructura static/description/ para logo en 5 addons
- Agregar documentación de logo (LOGO_INSTRUCTIONS.md, install_logo.sh)
- Actualizar copilot-instructions.md con referencias a OCA_DOCUMENTATION.md
- Crear docs/OCA_DOCUMENTATION.md con guía completa de estructura
- Crear docs/RESUMEN_CAMBIOS_DOCUMENTACION.md con resumen detallado

Addons actualizados:
- website_sale_aplicoop
- product_sale_price_from_pricelist
- product_pricelist_total_margin
- product_price_category_supplier
- account_invoice_triple_discount_readonly
2026-02-21 19:55:57 +01:00
snt
cf9ea887c1 [REF] Code quality improvements and structure fixes
- Add mypy.ini configuration to exclude migration scripts
- Rename migration files to proper snake_case (post-migration.py → post_migration.py)
- Add __init__.py to migration directories for proper Python package structure
- Add new portal access tests for website_sale_aplicoop
- Code formatting improvements (black, isort)
- Update copilot instructions and project configuration

Related to previous code quality refactoring work.
2026-02-21 13:51:25 +01:00
snt
5d4552581c [IMP] website_sale_aplicoop: Auto-carga de productos al filtrar por tags
Mejora en la UX del filtrado por tags:
- Cuando se aplica un filtro que deja pocos productos visibles (<10),
  automáticamente carga más páginas sin esperar scroll del usuario
- Evita pantallas vacías o con muy pocos productos después de filtrar
- El auto-carga se ejecuta con delay de 100ms para evitar race conditions
- Solo se activa si hay más páginas disponibles (hasMore) y no está ya cargando

Nuevo método: _autoLoadMoreIfNeeded(visibleCount)
- Umbral configurable: 10 productos mínimos
- Se llama automáticamente desde _filterProducts()
- Integración con infiniteScroll.loadNextPage()
2026-02-18 19:01:33 +01:00
snt
19eb1b91b5 [FIX] website_sale_aplicoop: Arreglar búsqueda y filtrado por tags
Problemas resueltos:
- Contador de badges mostraba solo productos de página actual (20) en lugar del total
- Productos cargados con lazy loading no se filtraban por tags seleccionados

Cambios en realtime_search.js:
- Eliminado recálculo dinámico de contadores en _filterProducts()
- Los contadores permanecen estáticos (calculados por backend sobre dataset completo)
- Mejorado logging para debug de tags seleccionados

Cambios en infinite_scroll.js:
- Después de cargar nueva página, actualiza lista de productos para realtime search
- Aplica filtros activos automáticamente a productos recién cargados
- Garantiza consistencia de estado de filtrado en toda la aplicación

Documentación:
- Añadido docs/TAG_FILTER_FIX.md con explicación completa del sistema
- Incluye arquitectura, flujo de datos y casos de prueba
2026-02-18 18:51:26 +01:00
snt
6fbc7b9456 [FIX] website_sale_aplicoop: Remove redundant string= attributes and fix OCA linting warnings
- 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
2026-02-18 17:54:43 +01:00
snt
c70de71cff [ADD] website_sale_aplicoop: re-implement clear search button
Added × button to clear the search input field. When clicked:
- Clears the search text
- Updates lastSearchValue to prevent polling false-positive
- Calls infiniteScroll.resetWithFilters() to reload all products from server
- Maintains current category filter
- Returns focus to search input

The button appears when text is entered and hides when search is empty.
2026-02-18 17:11:47 +01:00
snt
267059fa1b [FIX] website_sale_aplicoop: save-cart-btn listener was never attached
The save-cart-btn event listener was placed after a return statement in
_attachEventListeners(), so it was never executed. Moved it to the correct
location inside the _cartCheckoutListenersAttached block alongside the
other cart/checkout buttons (reload-cart-btn, confirm-order-btn, etc.).
2026-02-18 17:00:57 +01:00
snt
b07b7dc671 [FIX] website_sale_aplicoop: prevent grid destruction on event listener attachment
The _attachEventListeners() function was cloning the products-grid element
without its children (cloneNode(false)) to remove duplicate event listeners.
This destroyed all loaded products every time the function was called.

Solution: Use a flag (_delegationListenersAttached) to prevent adding
duplicate event listeners instead of cloning and replacing the grid node.

This fixes the issue where products would disappear ~1-2 seconds after
page load.
2026-02-18 16:53:27 +01:00
snt
40ce973bd6 [FIX] website_sale_aplicoop: Complete infinite scroll and search filter integration
Major fixes:
- Fix JSON body parsing in load_products_ajax with type='http' route
  * Parse JSON from request.httprequest.get_data() instead of post params
  * Correctly read page, search, category from JSON request body

- Fix search and category filter combination
  * Use intersection (&) instead of replacement to preserve both filters
  * Now respects search AND category simultaneously

- Integrate realtime_search.js with infinite_scroll.js
  * Add resetWithFilters() method to reset scroll to page 1 with new filters
  * When search/category changes, reload products from server
  * Clear grid and load fresh results

- Fix pagination reset logic
  * Set currentPage = 0 in resetWithFilters() so loadNextPage() increments to 1
  * Prevents loading empty page 2 when resetting filters

Results:
✅ Infinite scroll loads all pages correctly (1, 2, 3...)
✅ Search filters work across all products (not just loaded)
✅ Category filters work correctly
✅ Search AND category filters work together
✅ Page resets to 1 when filters change
2026-02-17 01:26:20 +01:00
snt
5eb039ffe0 [FIX] website_sale_aplicoop: Complete infinite scroll and search filter integration
Major fixes:
- Fix JSON body parsing in load_products_ajax with type='http' route
  * Parse JSON from request.httprequest.get_data() instead of post params
  * Correctly read page, search, category from JSON request body

- Fix search and category filter combination
  * Use intersection (&) instead of replacement to preserve both filters
  * Now respects search AND category simultaneously

- Integrate realtime_search.js with infinite_scroll.js
  * Add resetWithFilters() method to reset scroll to page 1 with new filters
  * When search/category changes, reload products from server
  * Clear grid and load fresh results

- Fix pagination reset logic
  * Set currentPage = 0 in resetWithFilters() so loadNextPage() increments to 1
  * Prevents loading empty page 2 when resetting filters

Results:
✅ Infinite scroll loads all pages correctly (1, 2, 3...)
✅ Search filters work across all products (not just loaded)
✅ Category filters work correctly
✅ Search AND category filters work together
✅ Page resets to 1 when filters change
2026-02-17 01:10:47 +01:00
snt
9000e92324 [DOC] website_sale_aplicoop: Add lazy loading documentation and implement v18.0.1.3.0 feature
- Add LAZY_LOADING.md with complete technical documentation (600+ lines)
- Add LAZY_LOADING_QUICK_START.md for quick reference (5 min)
- Add LAZY_LOADING_DOCS_INDEX.md as navigation guide
- Add UPGRADE_INSTRUCTIONS_v18.0.1.3.0.md with step-by-step installation
- Create DOCUMENTATION.md as main documentation index
- Update README.md with lazy loading reference
- Update docs/README.md with new docs section
- Update website_sale_aplicoop/README.md with features and changelog
- Create website_sale_aplicoop/CHANGELOG.md with version history

Lazy Loading Implementation (v18.0.1.3.0):
- Reduces initial store load from 10-20s to 500-800ms (20x faster)
- Add pagination configuration to res_config_settings
- Add _get_products_paginated() method to group_order model
- Implement AJAX endpoint for product loading
- Create 'Load More' button in website templates
- Add JavaScript listener for lazy loading behavior
- Backward compatible: can be disabled in settings

Performance Improvements:
- Initial load: 500-800ms (vs 10-20s before)
- Subsequent pages: 200-400ms via AJAX
- DOM optimization: 20 products initial vs 1000+ before
- Configurable: enable/disable and items per page

Documentation Coverage:
- Technical architecture and design
- Installation and upgrade instructions
- Configuration options and best practices
- Troubleshooting and common issues
- Performance metrics and validation
- Rollback procedures
- Future improvements roadmap
2026-02-16 18:39:39 +01:00
snt
7cff89e418 Aplicoop desde el repo de kidekoop 2026-02-11 15:32:11 +01:00