[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
This commit is contained in:
snt 2026-04-07 23:50:30 +02:00
parent 0eb7957a70
commit 135967019e
6 changed files with 244 additions and 7 deletions

View file

@ -748,6 +748,22 @@
});
}
// Buttons to clear cart (header + footer)
var clearCartBtns = [
document.getElementById("clear-cart-btn"),
document.getElementById("clear-cart-btn-footer"),
];
clearCartBtns.forEach(function (btn) {
if (btn) {
console.log("[_attachEventListeners] clear-cart-btn found:", btn.id);
btn.addEventListener("click", function (e) {
console.log("[CLICK] clear-cart-btn clicked");
e.preventDefault();
self._clearCart();
});
}
});
this._cartCheckoutListenersAttached = true;
console.log("[_attachEventListeners] Checkout listeners attached (one-time)");
}
@ -1029,6 +1045,12 @@
draft_replace_warning: "The existing draft will be permanently deleted.",
draft_merge_btn: "Merge",
draft_replace_btn: "Replace",
// Clear cart labels
clear_cart: "Clear Cart",
clear_cart_confirm:
"Are you sure you want to clear the cart? This will also cancel any saved draft order.",
cart_cleared: "Cart cleared",
draft_cancelled: "draft order cancelled",
};
},
@ -1636,6 +1658,60 @@
xhr.send(JSON.stringify(orderData));
},
_clearCart: function () {
var self = this;
var labels = this._getLabels();
var confirmMsg =
labels.clear_cart_confirm ||
"Are you sure you want to clear the cart? This will also cancel any saved draft order.";
if (!window.confirm(confirmMsg)) {
return;
}
// Clear localStorage immediately
this._clearCurrentOrderCartSilently();
this._updateCartDisplay();
// Cancel draft sale.order on the server
var xhr = new XMLHttpRequest();
xhr.open("POST", "/eskaera/clear-cart", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = function () {
var labels2 = self._getLabels();
if (xhr.status === 200) {
try {
var data = JSON.parse(xhr.responseText);
if (data.success) {
var msg = labels2.cart_cleared || "Cart cleared";
if (data.cancelled_order_id) {
msg +=
" (" +
(labels2.draft_cancelled || "draft order cancelled") +
")";
}
self._showNotification("✓ " + msg, "success", 4000);
}
} catch (e) {
console.error("[_clearCart] Error parsing response:", e);
}
} else {
console.warn("[_clearCart] Server error:", xhr.status, xhr.responseText);
// Cart is already cleared locally, server error is non-critical
self._showNotification(labels2.cart_cleared || "Cart cleared", "success", 3000);
}
};
xhr.onerror = function () {
console.warn("[_clearCart] Network error, but cart already cleared locally");
var labels2 = self._getLabels();
self._showNotification(labels2.cart_cleared || "Cart cleared", "success", 3000);
};
xhr.send(JSON.stringify({ order_id: this.orderId }));
},
_saveOrderDraft: function () {
console.log("[_saveOrderDraft] Starting - this.orderId:", this.orderId);