diff --git a/website_sale_aplicoop/__manifest__.py b/website_sale_aplicoop/__manifest__.py index 9bc2aaf..f7ac586 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.1", + "version": "18.0.1.10.2", "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/static/src/js/website_sale.js b/website_sale_aplicoop/static/src/js/website_sale.js index a51ead4..1ed420b 100644 --- a/website_sale_aplicoop/static/src/js/website_sale.js +++ b/website_sale_aplicoop/static/src/js/website_sale.js @@ -442,7 +442,18 @@ }, _loadCart: function () { + // Storage layout: + // eskaera__cart → items as plain {productId: {...}} + // (keeps the contract used by + // checkout_labels.js, home_delivery.js + // and _saveOrderDraft). + // eskaera__cart_cycle → "YYYY-MM-DD" the cart was saved at. + // Eviction only fires when we KNOW the current cycle and it + // disagrees with the stored one. If either side is missing + // (e.g. checkout page that doesn't call check-status, or XHR + // failure), we preserve the user's cart. var cartKey = "eskaera_" + this.orderId + "_cart"; + var cycleKey = "eskaera_" + this.orderId + "_cart_cycle"; var raw = localStorage.getItem(cartKey); this.cart = {}; if (!raw) { @@ -455,27 +466,32 @@ } catch (e) { console.warn("Cart load: invalid JSON in localStorage, dropping", e); localStorage.removeItem(cartKey); + localStorage.removeItem(cycleKey); return; } - // Legacy / corrupt shape (raw items object without cycle stamp) → drop. - if ( - !parsed || - typeof parsed !== "object" || - !parsed.items || - !("cutoff_date" in parsed) - ) { - console.log( - "Cart load: legacy/unstamped value, dropping localStorage[" + cartKey + "]" - ); + if (!parsed || typeof parsed !== "object") { localStorage.removeItem(cartKey); + localStorage.removeItem(cycleKey); return; } - // Cycle mismatch (or no current cycle known) → drop. This is the - // primary defence against stale carts surviving cycle rollover. - if (!this._currentCutoffDate || parsed.cutoff_date !== this._currentCutoffDate) { + // Migration: v18.0.1.10.0 wrapped the cart as {cutoff_date, items} + // in the same key, which broke checkout_labels.js / home_delivery.js + // / _saveOrderDraft (they iterated Object.keys treating them as + // productIds). Unwrap once; subsequent saves use the canonical + // split-key layout below. + var items; + var storedCycle; + if (parsed.items && "cutoff_date" in parsed) { + items = parsed.items; + storedCycle = parsed.cutoff_date; + } else { + items = parsed; + storedCycle = localStorage.getItem(cycleKey); + } + if (this._currentCutoffDate && storedCycle && storedCycle !== this._currentCutoffDate) { console.log( "Cart load: cycle mismatch (stored=" + - parsed.cutoff_date + + storedCycle + ", current=" + this._currentCutoffDate + "), dropping localStorage[" + @@ -483,14 +499,20 @@ "]" ); localStorage.removeItem(cartKey); + localStorage.removeItem(cycleKey); return; } - this.cart = parsed.items; + this.cart = items; + // Re-canonicalize storage so other readers see the plain shape. + localStorage.setItem(cartKey, JSON.stringify(items)); + if (storedCycle) { + localStorage.setItem(cycleKey, storedCycle); + } console.log( "Cart loaded from localStorage[" + cartKey + "] (cycle " + - parsed.cutoff_date + + (storedCycle || "unknown") + "):", this.cart ); @@ -498,11 +520,11 @@ _saveCart: function () { var cartKey = "eskaera_" + this.orderId + "_cart"; - var payload = JSON.stringify({ - cutoff_date: this._currentCutoffDate || null, - items: this.cart, - }); - localStorage.setItem(cartKey, payload); + var cycleKey = "eskaera_" + this.orderId + "_cart_cycle"; + localStorage.setItem(cartKey, JSON.stringify(this.cart)); + if (this._currentCutoffDate) { + localStorage.setItem(cycleKey, this._currentCutoffDate); + } console.log( "Cart saved to localStorage[" + cartKey + @@ -515,7 +537,9 @@ _clearCurrentOrderCartSilently: function () { var cartKey = "eskaera_" + this.orderId + "_cart"; + var cycleKey = "eskaera_" + this.orderId + "_cart_cycle"; localStorage.removeItem(cartKey); + localStorage.removeItem(cycleKey); this.cart = {}; console.log("[groupOrderShop] Cart cleared silently for order:", this.orderId); },