diff --git a/website_sale_aplicoop/__manifest__.py b/website_sale_aplicoop/__manifest__.py index 1b29beb..9bc2aaf 100644 --- a/website_sale_aplicoop/__manifest__.py +++ b/website_sale_aplicoop/__manifest__.py @@ -3,7 +3,7 @@ { # noqa: B018 "name": "Website Sale - Aplicoop", - "version": "18.0.1.10.0", + "version": "18.0.1.10.1", "category": "Website/Sale", "summary": "Modern replacement of legacy Aplicoop - Collaborative consumption group orders", "author": "Odoo Community Association (OCA), Criptomart", diff --git a/website_sale_aplicoop/controllers/website_sale.py b/website_sale_aplicoop/controllers/website_sale.py index a9d6894..315143a 100644 --- a/website_sale_aplicoop/controllers/website_sale.py +++ b/website_sale_aplicoop/controllers/website_sale.py @@ -641,6 +641,16 @@ class AplicoopWebsiteSale(WebsiteSale): def _decode_json_body(self): return _utils._decode_json_body(self, request) + def _get_installed_module_version(self): + """Return the installed version of this addon, used as a build-id + signal so the frontend can detect a deploy and force a reload.""" + module = ( + request.env["ir.module.module"] + .sudo() + .search([("name", "=", "website_sale_aplicoop")], limit=1) + ) + return module.installed_version or "" + def _build_group_order_unavailable_response(self, group_order, status=403): """Delegate building of unavailable response to utils helper.""" self._request = request @@ -827,6 +837,7 @@ class AplicoopWebsiteSale(WebsiteSale): "current_page": page, "has_next": has_next, "total_products": total_products, + "module_version": self._get_installed_module_version(), }, ) @@ -1370,6 +1381,7 @@ class AplicoopWebsiteSale(WebsiteSale): ), "cutoff_passed": cutoff_passed, "cutoff_date": cutoff_date_str, + "client_version": self._get_installed_module_version(), } return request.make_response( json.dumps(response_data), diff --git a/website_sale_aplicoop/static/src/js/website_sale.js b/website_sale_aplicoop/static/src/js/website_sale.js index 15076c0..a51ead4 100644 --- a/website_sale_aplicoop/static/src/js/website_sale.js +++ b/website_sale_aplicoop/static/src/js/website_sale.js @@ -45,6 +45,13 @@ console.log("Initializing cart for order:", this.orderId); + // Capture the build version embedded in the rendered HTML. The + // server returns its installed version in /eskaera/check-status, + // and if the two disagree we know a deploy happened and the + // current page is running stale JS — force a one-shot reload. + this._buildVersion = orderIdElement.getAttribute("data-build-version") || null; + console.log("[groupOrderShop] Build version:", this._buildVersion); + // Attach event listeners FIRST (doesn't depend on translations) this._attachEventListeners(); console.log("[groupOrderShop] Event listeners attached"); @@ -513,6 +520,35 @@ console.log("[groupOrderShop] Cart cleared silently for order:", this.orderId); }, + // Avoid a reload loop if for any reason (HTML cached upstream, etc.) + // the build versions keep disagreeing after a reload. + _shouldReloadForNewBuild: function () { + try { + var raw = sessionStorage.getItem("eskaera_build_reload_at"); + if (!raw) { + return true; + } + var last = parseInt(raw, 10); + if (isNaN(last)) { + return true; + } + // If we already reloaded in the last 30s, don't try again. + return Date.now() - last > 30000; + } catch (e) { + return true; + } + }, + + _markReloadAttempt: function () { + try { + sessionStorage.setItem("eskaera_build_reload_at", String(Date.now())); + } catch (e) { + // sessionStorage unavailable — fail open; worst case we get a + // single extra reload, never a loop because the next render + // will carry the new version. + } + }, + _isClosedOrderResponse: function (xhr) { if (!xhr) { return false; @@ -555,6 +591,27 @@ } try { var data = JSON.parse(xhr.responseText || "{}"); + // Deploy-detection: server tells us the installed module + // version; if it differs from the version embedded in + // the HTML, we are running stale JS — reload once. + if ( + data && + data.client_version && + self._buildVersion && + data.client_version !== self._buildVersion && + self._shouldReloadForNewBuild() + ) { + console.warn( + "[groupOrderShop] Build mismatch (page=" + + self._buildVersion + + ", server=" + + data.client_version + + "), reloading" + ); + self._markReloadAttempt(); + window.location.reload(); + return; + } // Capture current cycle marker so _loadCart can evict a // localStorage cart that belongs to a previous cycle. self._currentCutoffDate = data && data.cutoff_date ? data.cutoff_date : null; diff --git a/website_sale_aplicoop/views/website_templates.xml b/website_sale_aplicoop/views/website_templates.xml index 66f266d..3d4d6ac 100644 --- a/website_sale_aplicoop/views/website_templates.xml +++ b/website_sale_aplicoop/views/website_templates.xml @@ -337,7 +337,7 @@ -
This order's cart is empty