Compare commits
No commits in common. "135967019e95e7f77b033a9c78f8ca0465e271f7" and "26bfa028d1a951e934df0c181283a8ea3cab3622" have entirely different histories.
135967019e
...
26bfa028d1
7 changed files with 9 additions and 244 deletions
|
|
@ -268,13 +268,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
||||||
"items": env_lang._("items"),
|
"items": env_lang._("items"),
|
||||||
"added_to_cart": env_lang._("added to cart"),
|
"added_to_cart": env_lang._("added to cart"),
|
||||||
"out_of_stock": env_lang._("Out of stock"),
|
"out_of_stock": env_lang._("Out of stock"),
|
||||||
# ============ CLEAR CART ============
|
|
||||||
"clear_cart": env_lang._("Clear Cart"),
|
|
||||||
"clear_cart_confirm": env_lang._(
|
|
||||||
"Are you sure you want to clear the cart? This will also cancel any saved draft order."
|
|
||||||
),
|
|
||||||
"cart_cleared": env_lang._("Cart cleared"),
|
|
||||||
"draft_cancelled": env_lang._("draft order cancelled"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return labels
|
return labels
|
||||||
|
|
@ -2422,107 +2415,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
||||||
status=500,
|
status=500,
|
||||||
)
|
)
|
||||||
|
|
||||||
@http.route(
|
|
||||||
["/eskaera/clear-cart"],
|
|
||||||
type="http",
|
|
||||||
auth="user",
|
|
||||||
website=True,
|
|
||||||
methods=["POST"],
|
|
||||||
csrf=False,
|
|
||||||
)
|
|
||||||
def clear_cart(self, **post):
|
|
||||||
"""Clear the user's cart and cancel any existing draft sale.order.
|
|
||||||
|
|
||||||
Receives: JSON body with 'order_id'
|
|
||||||
Returns: JSON with success status and cancelled_order_id if applicable.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
data = self._decode_json_body()
|
|
||||||
except ValueError as e:
|
|
||||||
return request.make_response(
|
|
||||||
json.dumps({"error": str(e)}),
|
|
||||||
[("Content-Type", "application/json")],
|
|
||||||
status=400,
|
|
||||||
)
|
|
||||||
|
|
||||||
order_id = data.get("order_id")
|
|
||||||
if not order_id:
|
|
||||||
return request.make_response(
|
|
||||||
json.dumps({"error": "order_id is required"}),
|
|
||||||
[("Content-Type", "application/json")],
|
|
||||||
status=400,
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
order_id = int(order_id)
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
return request.make_response(
|
|
||||||
json.dumps({"error": f"Invalid order_id format: {order_id}"}),
|
|
||||||
[("Content-Type", "application/json")],
|
|
||||||
status=400,
|
|
||||||
)
|
|
||||||
|
|
||||||
group_order = request.env["group.order"].sudo().browse(order_id)
|
|
||||||
if not group_order.exists():
|
|
||||||
return request.make_response(
|
|
||||||
json.dumps({"error": f"Order {order_id} not found"}),
|
|
||||||
[("Content-Type", "application/json")],
|
|
||||||
status=404,
|
|
||||||
)
|
|
||||||
|
|
||||||
current_user = request.env.user
|
|
||||||
if not current_user.partner_id:
|
|
||||||
return request.make_response(
|
|
||||||
json.dumps({"error": "User has no associated partner"}),
|
|
||||||
[("Content-Type", "application/json")],
|
|
||||||
status=400,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Find and cancel any existing draft sale.order for this period
|
|
||||||
cancelled_order_id = None
|
|
||||||
try:
|
|
||||||
draft_orders = self._find_recent_draft_order(
|
|
||||||
current_user.partner_id.id, group_order
|
|
||||||
)
|
|
||||||
if draft_orders:
|
|
||||||
draft_order = draft_orders[0]
|
|
||||||
cancelled_order_id = draft_order.id
|
|
||||||
# Use action_cancel if available, otherwise unlink
|
|
||||||
if draft_order.state == "draft":
|
|
||||||
draft_order.sudo().action_cancel()
|
|
||||||
_logger.info(
|
|
||||||
"clear_cart: Cancelled draft sale.order %d for partner %d",
|
|
||||||
draft_order.id,
|
|
||||||
current_user.partner_id.id,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
_logger.info(
|
|
||||||
"clear_cart: Draft order %d already in state '%s', skipping cancel",
|
|
||||||
draft_order.id,
|
|
||||||
draft_order.state,
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
_logger.warning(
|
|
||||||
"clear_cart: Error cancelling draft order for partner %d: %s",
|
|
||||||
current_user.partner_id.id,
|
|
||||||
str(e),
|
|
||||||
)
|
|
||||||
|
|
||||||
response_data = {
|
|
||||||
"success": True,
|
|
||||||
"message": request.env._("Cart cleared"),
|
|
||||||
"cancelled_order_id": cancelled_order_id,
|
|
||||||
}
|
|
||||||
_logger.info(
|
|
||||||
"clear_cart: Cart cleared for partner %d, order %d (cancelled_sale_order: %s)",
|
|
||||||
current_user.partner_id.id,
|
|
||||||
order_id,
|
|
||||||
cancelled_order_id,
|
|
||||||
)
|
|
||||||
return request.make_response(
|
|
||||||
json.dumps(response_data),
|
|
||||||
[("Content-Type", "application/json")],
|
|
||||||
)
|
|
||||||
|
|
||||||
@http.route(
|
@http.route(
|
||||||
["/eskaera/save-order"],
|
["/eskaera/save-order"],
|
||||||
type="http",
|
type="http",
|
||||||
|
|
|
||||||
|
|
@ -1243,12 +1243,12 @@ msgstr "Guardar como Borrador"
|
||||||
#. odoo-python
|
#. odoo-python
|
||||||
#: code:addons/website_sale_aplicoop/models/js_translations.py:0
|
#: code:addons/website_sale_aplicoop/models/js_translations.py:0
|
||||||
msgid "Save Draft"
|
msgid "Save Draft"
|
||||||
msgstr "Confirmar Pedido"
|
msgstr "Guardar borrador"
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
#. module: website_sale_aplicoop
|
||||||
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.eskaera_checkout
|
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.eskaera_checkout
|
||||||
msgid "Save order as draft"
|
msgid "Save order as draft"
|
||||||
msgstr "Confirmar Pedido"
|
msgstr "Guardar pedido como borrador"
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
#. module: website_sale_aplicoop
|
||||||
#. odoo-python
|
#. odoo-python
|
||||||
|
|
@ -2278,22 +2278,3 @@ msgstr "Semanal"
|
||||||
msgid "Whether this picking includes home delivery (from sale order)"
|
msgid "Whether this picking includes home delivery (from sale order)"
|
||||||
msgstr "Si este albarán incluye entrega a domicilio (del pedido de venta)"
|
msgstr "Si este albarán incluye entrega a domicilio (del pedido de venta)"
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
|
||||||
msgid "Clear Cart"
|
|
||||||
msgstr "Vaciar carrito"
|
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
|
||||||
msgid ""
|
|
||||||
"Are you sure you want to clear the cart? This will also cancel any saved "
|
|
||||||
"draft order."
|
|
||||||
msgstr ""
|
|
||||||
"¿Estás seguro de que quieres vaciar el carrito? Esto también cancelará "
|
|
||||||
"cualquier pedido borrador guardado."
|
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
|
||||||
msgid "Cart cleared"
|
|
||||||
msgstr "Carrito vaciado"
|
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
|
||||||
msgid "draft order cancelled"
|
|
||||||
msgstr "pedido borrador cancelado"
|
|
||||||
|
|
|
||||||
|
|
@ -1242,12 +1242,12 @@ msgstr "Zirriborro Gisa Gorde"
|
||||||
#. odoo-python
|
#. odoo-python
|
||||||
#: code:addons/website_sale_aplicoop/models/js_translations.py:0
|
#: code:addons/website_sale_aplicoop/models/js_translations.py:0
|
||||||
msgid "Save Draft"
|
msgid "Save Draft"
|
||||||
msgstr "Eskaera Konfirmatu"
|
msgstr "Zirriborroa gorde"
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
#. module: website_sale_aplicoop
|
||||||
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.eskaera_checkout
|
#: model_terms:ir.ui.view,arch_db:website_sale_aplicoop.eskaera_checkout
|
||||||
msgid "Save order as draft"
|
msgid "Save order as draft"
|
||||||
msgstr "Eskaera Zirriborro Gisa Gorde"
|
msgstr "Gorde enparatzea zirriborro gisa"
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
#. module: website_sale_aplicoop
|
||||||
#. odoo-python
|
#. odoo-python
|
||||||
|
|
@ -2272,21 +2272,3 @@ msgstr ""
|
||||||
"eskaeraren)"
|
"eskaeraren)"
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
#. module: website_sale_aplicoop
|
||||||
msgid "Clear Cart"
|
|
||||||
msgstr "Saskia garbitu"
|
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
|
||||||
msgid ""
|
|
||||||
"Are you sure you want to clear the cart? This will also cancel any saved "
|
|
||||||
"draft order."
|
|
||||||
msgstr ""
|
|
||||||
"Ziur zaude saskia garbitu nahi duzula? Honek gordetako zirriborro-eskaera "
|
|
||||||
"ere ezeztatuko du."
|
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
|
||||||
msgid "Cart cleared"
|
|
||||||
msgstr "Saskia garbituta"
|
|
||||||
|
|
||||||
#. module: website_sale_aplicoop
|
|
||||||
msgid "draft order cancelled"
|
|
||||||
msgstr "zirriborro-eskaera ezeztatu da"
|
|
||||||
|
|
|
||||||
|
|
@ -173,13 +173,3 @@ def _register_translations():
|
||||||
_("Friday")
|
_("Friday")
|
||||||
_("Saturday")
|
_("Saturday")
|
||||||
_("Sunday")
|
_("Sunday")
|
||||||
|
|
||||||
# ========================
|
|
||||||
# Clear Cart
|
|
||||||
# ========================
|
|
||||||
_("Clear Cart")
|
|
||||||
_(
|
|
||||||
"Are you sure you want to clear the cart? This will also cancel any saved draft order."
|
|
||||||
)
|
|
||||||
_("Cart cleared")
|
|
||||||
_("draft order cancelled")
|
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,14 @@ class ProductProduct(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
is_out_of_stock = fields.Boolean(
|
is_out_of_stock = fields.Boolean(
|
||||||
|
string="Is Out of Stock",
|
||||||
compute="_compute_stock_ribbons",
|
compute="_compute_stock_ribbons",
|
||||||
store=False,
|
store=False,
|
||||||
help="True if virtual_available <= 0",
|
help="True if virtual_available <= 0",
|
||||||
)
|
)
|
||||||
|
|
||||||
is_low_stock = fields.Boolean(
|
is_low_stock = fields.Boolean(
|
||||||
|
string="Is Low Stock",
|
||||||
compute="_compute_stock_ribbons",
|
compute="_compute_stock_ribbons",
|
||||||
store=False,
|
store=False,
|
||||||
help="True if 0 < virtual_available <= threshold",
|
help="True if 0 < virtual_available <= threshold",
|
||||||
|
|
|
||||||
|
|
@ -748,22 +748,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
this._cartCheckoutListenersAttached = true;
|
||||||
console.log("[_attachEventListeners] Checkout listeners attached (one-time)");
|
console.log("[_attachEventListeners] Checkout listeners attached (one-time)");
|
||||||
}
|
}
|
||||||
|
|
@ -1045,12 +1029,6 @@
|
||||||
draft_replace_warning: "The existing draft will be permanently deleted.",
|
draft_replace_warning: "The existing draft will be permanently deleted.",
|
||||||
draft_merge_btn: "Merge",
|
draft_merge_btn: "Merge",
|
||||||
draft_replace_btn: "Replace",
|
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",
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1658,60 +1636,6 @@
|
||||||
xhr.send(JSON.stringify(orderData));
|
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 () {
|
_saveOrderDraft: function () {
|
||||||
console.log("[_saveOrderDraft] Starting - this.orderId:", this.orderId);
|
console.log("[_saveOrderDraft] Starting - this.orderId:", this.orderId);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -283,21 +283,15 @@
|
||||||
<a t-attf-href="/eskaera/{{ group_order.id }}/checkout" class="btn btn-success cart-btn-compact" aria-label="Proceed to checkout" data-bs-title="Proceed to Checkout" data-bs-toggle="tooltip">
|
<a t-attf-href="/eskaera/{{ group_order.id }}/checkout" class="btn btn-success cart-btn-compact" aria-label="Proceed to checkout" data-bs-title="Proceed to Checkout" data-bs-toggle="tooltip">
|
||||||
<i class="fa fa-check cart-icon-size" aria-hidden="true" />
|
<i class="fa fa-check cart-icon-size" aria-hidden="true" />
|
||||||
</a>
|
</a>
|
||||||
<button type="button" class="btn btn-outline-danger cart-btn-compact" id="clear-cart-btn" t-attf-data-order-id="{{ group_order.id }}" data-bs-title="Clear Cart" data-bs-toggle="tooltip" aria-label="Clear Cart">
|
|
||||||
<i class="fa fa-trash cart-icon-size" aria-hidden="true" />
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body cart-body-lg" id="cart-items-container" t-attf-data-order-id="{{ group_order.id }}" aria-labelledby="cart-title" aria-live="polite" aria-relevant="additions removals">
|
<div class="card-body cart-body-lg" id="cart-items-container" t-attf-data-order-id="{{ group_order.id }}" aria-labelledby="cart-title" aria-live="polite" aria-relevant="additions removals">
|
||||||
<p class="text-muted">This order's cart is empty</p>
|
<p class="text-muted">This order's cart is empty</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer bg-white d-flex justify-content-between align-items-center gap-2">
|
<div class="card-footer bg-white text-center">
|
||||||
<button type="button" class="btn btn-outline-danger btn-sm" id="clear-cart-btn-footer" t-attf-data-order-id="{{ group_order.id }}" data-bs-title="Clear Cart" data-bs-toggle="tooltip" aria-label="Clear Cart">
|
|
||||||
<i class="fa fa-trash me-1" aria-hidden="true" />Clear Cart
|
|
||||||
</button>
|
|
||||||
<a t-attf-href="/eskaera/{{ group_order.id }}/checkout" class="btn btn-success checkout-btn-lg" data-bs-title="Proceed to Checkout" data-bs-toggle="tooltip">
|
<a t-attf-href="/eskaera/{{ group_order.id }}/checkout" class="btn btn-success checkout-btn-lg" data-bs-title="Proceed to Checkout" data-bs-toggle="tooltip">
|
||||||
Proceed to Checkout
|
Proceed to Checkout
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue