[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
This commit is contained in:
parent
4a928e92dd
commit
3ca90578ae
7 changed files with 271 additions and 8 deletions
|
|
@ -37,6 +37,7 @@
|
||||||
"views/res_partner_views.xml",
|
"views/res_partner_views.xml",
|
||||||
"views/res_config_settings_views.xml",
|
"views/res_config_settings_views.xml",
|
||||||
"views/website_templates.xml",
|
"views/website_templates.xml",
|
||||||
|
"views/website_sale_disable_cart.xml",
|
||||||
"views/product_template_views.xml",
|
"views/product_template_views.xml",
|
||||||
"views/sale_order_views.xml",
|
"views/sale_order_views.xml",
|
||||||
"views/stock_picking_views.xml",
|
"views/stock_picking_views.xml",
|
||||||
|
|
|
||||||
|
|
@ -1511,6 +1511,87 @@ class AplicoopWebsiteSale(WebsiteSale):
|
||||||
status=status,
|
status=status,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _validate_items_for_group_order(self, items, group_order):
|
||||||
|
"""Validate items from historical order against current group order availability.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
items: list of dicts with keys: product_id, product_name, quantity, price
|
||||||
|
group_order: group.order record
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict with keys:
|
||||||
|
- available_items: list of items that are available in current group order
|
||||||
|
- unavailable_items: list of items that are NOT available
|
||||||
|
- unavailable_products: set of product IDs that are unavailable
|
||||||
|
- warning_message: str, message about unavailable items (or empty)
|
||||||
|
"""
|
||||||
|
if not items:
|
||||||
|
return {
|
||||||
|
"available_items": [],
|
||||||
|
"unavailable_items": [],
|
||||||
|
"unavailable_products": set(),
|
||||||
|
"warning_message": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get available products for the current group order
|
||||||
|
try:
|
||||||
|
available_products = request.env[
|
||||||
|
"group.order"
|
||||||
|
]._get_products_for_group_order(group_order.id)
|
||||||
|
available_product_ids = set(available_products.ids)
|
||||||
|
except Exception as e:
|
||||||
|
_logger.error(
|
||||||
|
"Error getting available products for group_order %d: %s",
|
||||||
|
group_order.id,
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
# If something fails, return all items as available (failsafe)
|
||||||
|
return {
|
||||||
|
"available_items": items,
|
||||||
|
"unavailable_items": [],
|
||||||
|
"unavailable_products": set(),
|
||||||
|
"warning_message": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Separate items into available and unavailable
|
||||||
|
available_items = []
|
||||||
|
unavailable_items = []
|
||||||
|
unavailable_product_ids = set()
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
product_id = item.get("product_id")
|
||||||
|
if product_id in available_product_ids:
|
||||||
|
available_items.append(item)
|
||||||
|
else:
|
||||||
|
unavailable_items.append(item)
|
||||||
|
unavailable_product_ids.add(product_id)
|
||||||
|
|
||||||
|
# Build warning message if there are unavailable items
|
||||||
|
warning_message = ""
|
||||||
|
if unavailable_items:
|
||||||
|
unavailable_names = [
|
||||||
|
item.get("product_name", "Unknown") for item in unavailable_items
|
||||||
|
]
|
||||||
|
warning_message = request.env._(
|
||||||
|
"%(count)d product(s) from your saved order are no longer available in this group order: %(names)s. "
|
||||||
|
"Only available products will be loaded.",
|
||||||
|
count=len(unavailable_items),
|
||||||
|
names=", ".join(unavailable_names),
|
||||||
|
)
|
||||||
|
_logger.warning(
|
||||||
|
"load_order_from_history: %d unavailable items in group_order %d (products: %s)",
|
||||||
|
len(unavailable_items),
|
||||||
|
group_order.id,
|
||||||
|
unavailable_product_ids,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"available_items": available_items,
|
||||||
|
"unavailable_items": unavailable_items,
|
||||||
|
"unavailable_products": unavailable_product_ids,
|
||||||
|
"warning_message": warning_message,
|
||||||
|
}
|
||||||
|
|
||||||
def _find_recent_draft_order(self, partner_id, group_order):
|
def _find_recent_draft_order(self, partner_id, group_order):
|
||||||
"""Find most recent draft sale.order for partner in the active order period.
|
"""Find most recent draft sale.order for partner in the active order period.
|
||||||
|
|
||||||
|
|
@ -2218,12 +2299,31 @@ class AplicoopWebsiteSale(WebsiteSale):
|
||||||
status=404,
|
status=404,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Determine if cutoff date for the current cycle has already passed
|
||||||
|
try:
|
||||||
|
today = fields.Date.today()
|
||||||
|
cutoff_passed = False
|
||||||
|
cutoff_date_str = None
|
||||||
|
if group_order.cutoff_date:
|
||||||
|
cutoff_passed = group_order.cutoff_date < today
|
||||||
|
# Convert to ISO-like string for frontend (YYYY-MM-DD)
|
||||||
|
cutoff_date_str = str(group_order.cutoff_date)
|
||||||
|
except Exception:
|
||||||
|
cutoff_passed = False
|
||||||
|
cutoff_date_str = None
|
||||||
|
|
||||||
response_data = {
|
response_data = {
|
||||||
"success": True,
|
"success": True,
|
||||||
"order_id": group_order.id,
|
"order_id": group_order.id,
|
||||||
"state": group_order.state,
|
"state": group_order.state,
|
||||||
"is_open": group_order.state == "open",
|
"is_open": group_order.state == "open",
|
||||||
"action": "clear_cart" if group_order.state != "open" else "none",
|
"action": (
|
||||||
|
"clear_cart"
|
||||||
|
if (group_order.state != "open" or cutoff_passed)
|
||||||
|
else "none"
|
||||||
|
),
|
||||||
|
"cutoff_passed": cutoff_passed,
|
||||||
|
"cutoff_date": cutoff_date_str,
|
||||||
}
|
}
|
||||||
return request.make_response(
|
return request.make_response(
|
||||||
json.dumps(response_data),
|
json.dumps(response_data),
|
||||||
|
|
@ -2975,9 +3075,14 @@ class AplicoopWebsiteSale(WebsiteSale):
|
||||||
if sale_order.group_order_id.id != group_order_id:
|
if sale_order.group_order_id.id != group_order_id:
|
||||||
return request.redirect("/eskaera/%d" % sale_order.group_order_id.id)
|
return request.redirect("/eskaera/%d" % sale_order.group_order_id.id)
|
||||||
|
|
||||||
|
# Get the current group_order (the one being viewed, not necessarily the one from the history)
|
||||||
|
group_order = request.env["group.order"].sudo().browse(group_order_id)
|
||||||
|
if not group_order.exists():
|
||||||
|
return request.redirect("/shop")
|
||||||
|
|
||||||
# Extract items from the order (skip delivery product)
|
# Extract items from the order (skip delivery product)
|
||||||
# Use the delivery_product_id from the group_order
|
# Use the delivery_product_id from the group_order
|
||||||
delivery_product = sale_order.group_order_id.delivery_product_id
|
delivery_product = group_order.delivery_product_id
|
||||||
delivery_product_id = delivery_product.id if delivery_product else None
|
delivery_product_id = delivery_product.id if delivery_product else None
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
|
|
@ -2995,6 +3100,21 @@ class AplicoopWebsiteSale(WebsiteSale):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Validate items against current group order availability
|
||||||
|
validation_result = self._validate_items_for_group_order(items, group_order)
|
||||||
|
available_items = validation_result["available_items"]
|
||||||
|
unavailable_items = validation_result["unavailable_items"]
|
||||||
|
warning_message = validation_result["warning_message"]
|
||||||
|
|
||||||
|
_logger.info(
|
||||||
|
"load_order_from_history: Loaded %d items, %d available, %d unavailable from sale_order %d into group_order %d",
|
||||||
|
len(items),
|
||||||
|
len(available_items),
|
||||||
|
len(unavailable_items),
|
||||||
|
sale_order_id,
|
||||||
|
group_order_id,
|
||||||
|
)
|
||||||
|
|
||||||
# Store items in localStorage by passing via URL parameter or session
|
# Store items in localStorage by passing via URL parameter or session
|
||||||
# We'll use sessionStorage in JavaScript to avoid URL length limits
|
# We'll use sessionStorage in JavaScript to avoid URL length limits
|
||||||
|
|
||||||
|
|
@ -3019,13 +3139,19 @@ class AplicoopWebsiteSale(WebsiteSale):
|
||||||
"website_sale_aplicoop.eskaera_load_from_history",
|
"website_sale_aplicoop.eskaera_load_from_history",
|
||||||
{
|
{
|
||||||
"group_order_id": group_order_id,
|
"group_order_id": group_order_id,
|
||||||
"items_json": json.dumps(items), # Pass serialized JSON
|
"items_json": json.dumps(
|
||||||
|
available_items
|
||||||
|
), # Pass ONLY available items
|
||||||
"sale_order": sale_order,
|
"sale_order": sale_order,
|
||||||
"sale_order_name": sale_order.name, # Pass order reference
|
"sale_order_name": sale_order.name, # Pass order reference
|
||||||
"pickup_day": pickup_day_to_restore, # Pass pickup day (or None if different group)
|
"pickup_day": pickup_day_to_restore, # Pass pickup day (or None if different group)
|
||||||
"pickup_date": pickup_date_to_restore, # Pass pickup date (or None if different group)
|
"pickup_date": pickup_date_to_restore, # Pass pickup date (or None if different group)
|
||||||
"home_delivery": home_delivery_to_restore, # Pass home delivery flag (or None if different group)
|
"home_delivery": home_delivery_to_restore, # Pass home delivery flag (or None if different group)
|
||||||
"same_group_order": same_group_order, # Indicate if from same group order
|
"same_group_order": same_group_order, # Indicate if from same group order
|
||||||
|
"unavailable_items": unavailable_items, # List of unavailable items
|
||||||
|
"warning_message": warning_message, # Warning about unavailable products
|
||||||
|
"has_unavailable_items": len(unavailable_items)
|
||||||
|
> 0, # Boolean flag for template
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -3269,3 +3395,50 @@ class AplicoopWebsiteSale(WebsiteSale):
|
||||||
"empty_cart": "Your cart is empty",
|
"empty_cart": "Your cart is empty",
|
||||||
"added_to_cart": "added to cart",
|
"added_to_cart": "added to cart",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ================================================================
|
||||||
|
# CART REDIRECT METHODS - Redirect /shop/cart routes to /eskaera
|
||||||
|
# ================================================================
|
||||||
|
|
||||||
|
@http.route(["/shop/cart"], type="http", auth="public", website=True)
|
||||||
|
def cart_redirect(self, access_token=None, revive="", **post):
|
||||||
|
"""Redirect /shop/cart to /eskaera (no standard cart)."""
|
||||||
|
_logger.info("🛒 Redirecting /shop/cart → /eskaera")
|
||||||
|
return http.redirect_with_hash("/eskaera")
|
||||||
|
|
||||||
|
@http.route(
|
||||||
|
["/shop/cart/update"],
|
||||||
|
type="http",
|
||||||
|
auth="public",
|
||||||
|
website=True,
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
def cart_update_redirect(self, **post):
|
||||||
|
"""Redirect /shop/cart/update to /eskaera (no standard cart)."""
|
||||||
|
_logger.info("🛒 Redirecting /shop/cart/update → /eskaera")
|
||||||
|
return http.redirect_with_hash("/eskaera")
|
||||||
|
|
||||||
|
@http.route(
|
||||||
|
["/shop/cart/update_json"],
|
||||||
|
type="http",
|
||||||
|
auth="public",
|
||||||
|
website=True,
|
||||||
|
methods=["POST"],
|
||||||
|
csrf=False,
|
||||||
|
)
|
||||||
|
def cart_update_json_redirect(self, **post):
|
||||||
|
"""Redirect /shop/cart/update_json to /eskaera (no standard cart)."""
|
||||||
|
_logger.info("🛒 Redirecting /shop/cart/update_json → /eskaera")
|
||||||
|
return http.redirect_with_hash("/eskaera")
|
||||||
|
|
||||||
|
@http.route(
|
||||||
|
["/shop/cart_quantity"],
|
||||||
|
type="http",
|
||||||
|
auth="public",
|
||||||
|
website=True,
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
def cart_quantity_redirect(self):
|
||||||
|
"""Redirect /shop/cart_quantity to /eskaera (no standard cart)."""
|
||||||
|
_logger.info("🛒 Redirecting /shop/cart_quantity → /eskaera")
|
||||||
|
return http.redirect_with_hash("/eskaera")
|
||||||
|
|
|
||||||
|
|
@ -882,7 +882,7 @@ class GroupOrder(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
def _create_picking_batches_for_sale_orders(self, sale_orders):
|
def _create_picking_batches_for_sale_orders(self, sale_orders):
|
||||||
"""Create stock.picking.batch grouped by consumer_group_id.
|
"""Create stock.picking.batch grouped by picking type for this group order.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
sale_orders: Recordset of confirmed sale.order
|
sale_orders: Recordset of confirmed sale.order
|
||||||
|
|
@ -902,9 +902,13 @@ class GroupOrder(models.Model):
|
||||||
)
|
)
|
||||||
grouped_pickings[picking.picking_type_id.id] |= picking
|
grouped_pickings[picking.picking_type_id.id] |= picking
|
||||||
|
|
||||||
scheduled_date = self.pickup_date
|
scheduled_date = None
|
||||||
if not scheduled_date and self.delivery_date:
|
if self.pickup_date:
|
||||||
scheduled_date = self.delivery_date - timedelta(days=1)
|
scheduled_date = fields.Datetime.to_datetime(self.pickup_date)
|
||||||
|
elif self.delivery_date:
|
||||||
|
scheduled_date = fields.Datetime.to_datetime(
|
||||||
|
self.delivery_date - timedelta(days=1)
|
||||||
|
)
|
||||||
|
|
||||||
for picking_type_id, pickings in grouped_pickings.items():
|
for picking_type_id, pickings in grouped_pickings.items():
|
||||||
if not pickings:
|
if not pickings:
|
||||||
|
|
|
||||||
|
|
@ -222,12 +222,14 @@
|
||||||
var pickupDayKey = "load_from_history_pickup_day_" + this.orderId;
|
var pickupDayKey = "load_from_history_pickup_day_" + this.orderId;
|
||||||
var pickupDateKey = "load_from_history_pickup_date_" + this.orderId;
|
var pickupDateKey = "load_from_history_pickup_date_" + this.orderId;
|
||||||
var homeDeliveryKey = "load_from_history_home_delivery_" + this.orderId;
|
var homeDeliveryKey = "load_from_history_home_delivery_" + this.orderId;
|
||||||
|
var warningKey = "load_from_history_warning_" + this.orderId;
|
||||||
|
|
||||||
var itemsJson = sessionStorage.getItem(storageKey);
|
var itemsJson = sessionStorage.getItem(storageKey);
|
||||||
var orderName = sessionStorage.getItem(orderNameKey);
|
var orderName = sessionStorage.getItem(orderNameKey);
|
||||||
var pickupDay = sessionStorage.getItem(pickupDayKey);
|
var pickupDay = sessionStorage.getItem(pickupDayKey);
|
||||||
var pickupDate = sessionStorage.getItem(pickupDateKey);
|
var pickupDate = sessionStorage.getItem(pickupDateKey);
|
||||||
var homeDelivery = sessionStorage.getItem(homeDeliveryKey) === "true";
|
var homeDelivery = sessionStorage.getItem(homeDeliveryKey) === "true";
|
||||||
|
var warningMessage = sessionStorage.getItem(warningKey);
|
||||||
|
|
||||||
console.log("DEBUG: _loadFromHistory called for orderId:", this.orderId);
|
console.log("DEBUG: _loadFromHistory called for orderId:", this.orderId);
|
||||||
console.log("DEBUG: sessionStorageKey:", storageKey);
|
console.log("DEBUG: sessionStorageKey:", storageKey);
|
||||||
|
|
@ -240,6 +242,7 @@
|
||||||
homeDelivery,
|
homeDelivery,
|
||||||
"(empty means different group order)"
|
"(empty means different group order)"
|
||||||
);
|
);
|
||||||
|
console.log("DEBUG: warningMessage:", warningMessage);
|
||||||
|
|
||||||
if (!itemsJson || itemsJson === "[object Object]") {
|
if (!itemsJson || itemsJson === "[object Object]") {
|
||||||
console.log("No valid items from history found in sessionStorage");
|
console.log("No valid items from history found in sessionStorage");
|
||||||
|
|
@ -248,6 +251,7 @@
|
||||||
sessionStorage.removeItem(pickupDayKey);
|
sessionStorage.removeItem(pickupDayKey);
|
||||||
sessionStorage.removeItem(pickupDateKey);
|
sessionStorage.removeItem(pickupDateKey);
|
||||||
sessionStorage.removeItem(homeDeliveryKey);
|
sessionStorage.removeItem(homeDeliveryKey);
|
||||||
|
sessionStorage.removeItem(warningKey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,6 +273,7 @@
|
||||||
sessionStorage.removeItem(pickupDayKey);
|
sessionStorage.removeItem(pickupDayKey);
|
||||||
sessionStorage.removeItem(pickupDateKey);
|
sessionStorage.removeItem(pickupDateKey);
|
||||||
sessionStorage.removeItem(homeDeliveryKey);
|
sessionStorage.removeItem(homeDeliveryKey);
|
||||||
|
sessionStorage.removeItem(warningKey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -349,12 +354,19 @@
|
||||||
}
|
}
|
||||||
this._showNotification(message, "success", 3000);
|
this._showNotification(message, "success", 3000);
|
||||||
|
|
||||||
|
// Show warning if some products were unavailable
|
||||||
|
if (warningMessage) {
|
||||||
|
console.log("Showing warning about unavailable products:", warningMessage);
|
||||||
|
this._showNotification(warningMessage, "warning", 5000);
|
||||||
|
}
|
||||||
|
|
||||||
// Clear sessionStorage
|
// Clear sessionStorage
|
||||||
sessionStorage.removeItem(storageKey);
|
sessionStorage.removeItem(storageKey);
|
||||||
sessionStorage.removeItem(orderNameKey);
|
sessionStorage.removeItem(orderNameKey);
|
||||||
sessionStorage.removeItem(pickupDayKey);
|
sessionStorage.removeItem(pickupDayKey);
|
||||||
sessionStorage.removeItem(pickupDateKey);
|
sessionStorage.removeItem(pickupDateKey);
|
||||||
sessionStorage.removeItem(homeDeliveryKey);
|
sessionStorage.removeItem(homeDeliveryKey);
|
||||||
|
sessionStorage.removeItem(warningKey);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error loading from history:", e);
|
console.error("Error loading from history:", e);
|
||||||
console.error("itemsJson was:", itemsJson);
|
console.error("itemsJson was:", itemsJson);
|
||||||
|
|
@ -435,8 +447,32 @@
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
var data = JSON.parse(xhr.responseText || "{}");
|
var data = JSON.parse(xhr.responseText || "{}");
|
||||||
if (data && data.is_open === false) {
|
// Clear cart if order is closed, action requests clearance, or cutoff already passed
|
||||||
|
var shouldClear = false;
|
||||||
|
if (data) {
|
||||||
|
if (data.is_open === false) {
|
||||||
|
shouldClear = true;
|
||||||
|
}
|
||||||
|
if (data.action && data.action === "clear_cart") {
|
||||||
|
shouldClear = true;
|
||||||
|
}
|
||||||
|
if (data.cutoff_passed === true) {
|
||||||
|
shouldClear = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shouldClear) {
|
||||||
|
console.log(
|
||||||
|
"[groupOrderShop] check-status: clearing cart (reason:",
|
||||||
|
data,
|
||||||
|
")"
|
||||||
|
);
|
||||||
self._clearCurrentOrderCartSilently();
|
self._clearCurrentOrderCartSilently();
|
||||||
|
// Update on-screen cart if visible
|
||||||
|
try {
|
||||||
|
self._updateCartDisplay();
|
||||||
|
} catch (err) {
|
||||||
|
console.warn("_updateCartDisplay failed after clearing cart:", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("[groupOrderShop] check-status parse error", e);
|
console.warn("[groupOrderShop] check-status parse error", e);
|
||||||
|
|
|
||||||
|
|
@ -361,6 +361,7 @@ class TestCronPickingBatch(TransactionCase):
|
||||||
|
|
||||||
# Call second time
|
# Call second time
|
||||||
group_order._confirm_linked_sale_orders()
|
group_order._confirm_linked_sale_orders()
|
||||||
|
so.invalidate_recordset()
|
||||||
|
|
||||||
batch_second = so.picking_ids[0].batch_id
|
batch_second = so.picking_ids[0].batch_id
|
||||||
batch_count_second = self.env["stock.picking.batch"].search_count(
|
batch_count_second = self.env["stock.picking.batch"].search_count(
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,17 @@
|
||||||
var homeDelivery = <t t-esc="home_delivery and 'true' or 'false'"/>;
|
var homeDelivery = <t t-esc="home_delivery and 'true' or 'false'"/>;
|
||||||
var sameGroupOrder = <t t-esc="same_group_order and 'true' or 'false'"/>;
|
var sameGroupOrder = <t t-esc="same_group_order and 'true' or 'false'"/>;
|
||||||
|
|
||||||
|
// Product availability warning
|
||||||
|
var hasUnavailableItems = <t t-esc="has_unavailable_items and 'true' or 'false'"/>;
|
||||||
|
var warningMessage = '<t t-esc="warning_message or ''"/>';
|
||||||
|
|
||||||
console.log('load_from_history template: groupOrderId=', groupOrderId);
|
console.log('load_from_history template: groupOrderId=', groupOrderId);
|
||||||
console.log('load_from_history template: saleOrderName=', saleOrderName);
|
console.log('load_from_history template: saleOrderName=', saleOrderName);
|
||||||
console.log('load_from_history template: pickupDay=', pickupDay);
|
console.log('load_from_history template: pickupDay=', pickupDay);
|
||||||
console.log('load_from_history template: pickupDate=', pickupDate);
|
console.log('load_from_history template: pickupDate=', pickupDate);
|
||||||
console.log('load_from_history template: homeDelivery=', homeDelivery);
|
console.log('load_from_history template: homeDelivery=', homeDelivery);
|
||||||
console.log('load_from_history template: sameGroupOrder=', sameGroupOrder);
|
console.log('load_from_history template: sameGroupOrder=', sameGroupOrder);
|
||||||
|
console.log('load_from_history template: hasUnavailableItems=', hasUnavailableItems);
|
||||||
console.log('load_from_history template: itemsJson type=', typeof itemsJson);
|
console.log('load_from_history template: itemsJson type=', typeof itemsJson);
|
||||||
console.log('load_from_history template: itemsJson value=', itemsJson);
|
console.log('load_from_history template: itemsJson value=', itemsJson);
|
||||||
|
|
||||||
|
|
@ -47,6 +52,12 @@
|
||||||
console.log('Skipped saving pickup fields (different group order - will use current group order days)');
|
console.log('Skipped saving pickup fields (different group order - will use current group order days)');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store warning about unavailable products if they exist
|
||||||
|
if (hasUnavailableItems === 'true') {
|
||||||
|
sessionStorage['load_from_history_warning_' + groupOrderId] = warningMessage;
|
||||||
|
console.log('Unavailable products detected:', warningMessage);
|
||||||
|
}
|
||||||
|
|
||||||
console.log('Saved to sessionStorage[load_from_history_' + groupOrderId + ']:', itemsJsonString);
|
console.log('Saved to sessionStorage[load_from_history_' + groupOrderId + ']:', itemsJsonString);
|
||||||
console.log('Saved order name to sessionStorage[load_from_history_order_name_' + groupOrderId + ']:', saleOrderName);
|
console.log('Saved order name to sessionStorage[load_from_history_order_name_' + groupOrderId + ']:', saleOrderName);
|
||||||
|
|
||||||
|
|
|
||||||
37
website_sale_aplicoop/views/website_sale_disable_cart.xml
Normal file
37
website_sale_aplicoop/views/website_sale_disable_cart.xml
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!-- ==========================================
|
||||||
|
DISABLE STANDARD WEBSITE_SALE CART
|
||||||
|
Convert /shop to a simple product catalog
|
||||||
|
========================================== -->
|
||||||
|
|
||||||
|
<!-- Hide the cart link from the header -->
|
||||||
|
<template id="header_cart_link_hidden" inherit_id="website_sale.header_cart_link" name="Hide Cart Link">
|
||||||
|
<xpath expr="//li[hasclass('o_wsale_my_cart')]" position="attributes">
|
||||||
|
<attribute name="class" add="d-none" separator=" "/>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Remove "Add to Cart" button from product items in the shop -->
|
||||||
|
<template id="products_item_no_add_to_cart" inherit_id="website_sale.products_item" name="Product Item Without Add to Cart">
|
||||||
|
<!-- Remove the form action that points to /shop/cart/update -->
|
||||||
|
<xpath expr="//form[hasclass('oe_product_cart')]" position="attributes">
|
||||||
|
<attribute name="action">/</attribute>
|
||||||
|
<attribute name="method">get</attribute>
|
||||||
|
</xpath>
|
||||||
|
<!-- Hide the quick add button area completely -->
|
||||||
|
<xpath expr="//div[hasclass('o_wsale_product_btn')]" position="attributes">
|
||||||
|
<attribute name="class" add="d-none" separator=" "/>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Hide cart suggestion snippets and related cart features -->
|
||||||
|
<template id="suggested_products_list_hidden" inherit_id="website_sale.suggested_products_list" name="Hide Suggested Products" active="False">
|
||||||
|
<xpath expr="//*[hasclass('js_cart_lines')]" position="attributes">
|
||||||
|
<attribute name="class" add="d-none" separator=" "/>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue