[FIX] website_sale_aplicoop: align pricing and drafts
This commit is contained in:
parent
aef57a3de4
commit
a9c1f1f609
4 changed files with 258 additions and 533 deletions
|
|
@ -6,6 +6,7 @@ import logging
|
|||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import fields
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
|
|
@ -302,7 +303,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
# Agregar a los hijos de su padre
|
||||
category_map[parent_id]["children"].append(cat_info)
|
||||
|
||||
# Ordenar raíces y sus hijos por nombre
|
||||
def sort_hierarchy(items):
|
||||
items.sort(key=lambda x: x["name"])
|
||||
for item in items:
|
||||
|
|
@ -325,87 +325,49 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
Returns:
|
||||
product.pricelist record or False if none found
|
||||
"""
|
||||
env = request.env
|
||||
website = request.website
|
||||
pricelist = None
|
||||
|
||||
# Try to get configured Aplicoop pricelist first
|
||||
# 1) Configured pricelist from settings
|
||||
try:
|
||||
aplicoop_pricelist_id = (
|
||||
request.env["ir.config_parameter"]
|
||||
param_value = (
|
||||
env["ir.config_parameter"]
|
||||
.sudo()
|
||||
.get_param("website_sale_aplicoop.pricelist_id")
|
||||
)
|
||||
if aplicoop_pricelist_id:
|
||||
if param_value:
|
||||
pricelist = (
|
||||
request.env["product.pricelist"]
|
||||
.sudo()
|
||||
.browse(int(aplicoop_pricelist_id))
|
||||
env["product.pricelist"].browse(int(param_value)).exists() or None
|
||||
)
|
||||
if pricelist.exists():
|
||||
_logger.info(
|
||||
"_resolve_pricelist: Using configured Aplicoop pricelist: %s (id=%s)",
|
||||
pricelist.name,
|
||||
pricelist.id,
|
||||
)
|
||||
return pricelist
|
||||
else:
|
||||
_logger.warning(
|
||||
"_resolve_pricelist: Configured Aplicoop pricelist (id=%s) not found",
|
||||
aplicoop_pricelist_id,
|
||||
)
|
||||
except Exception as err:
|
||||
_logger.warning(
|
||||
"_resolve_pricelist: Error getting Aplicoop pricelist: %s", str(err)
|
||||
)
|
||||
except Exception as e:
|
||||
_logger.warning("_resolve_pricelist: error reading config param: %s", e)
|
||||
|
||||
# Fallback to website pricelist
|
||||
try:
|
||||
pricelist = request.website._get_current_pricelist()
|
||||
if pricelist:
|
||||
_logger.info(
|
||||
"_resolve_pricelist: Using website pricelist: %s (id=%s)",
|
||||
pricelist.name,
|
||||
pricelist.id,
|
||||
# 2) Website current pricelist
|
||||
if not pricelist:
|
||||
try:
|
||||
pricelist = website._get_current_pricelist()
|
||||
except Exception as e:
|
||||
_logger.warning(
|
||||
"_resolve_pricelist: fallback to website pricelist failed: %s", e
|
||||
)
|
||||
return pricelist
|
||||
except Exception as err:
|
||||
_logger.warning(
|
||||
"_resolve_pricelist: Error getting website pricelist: %s", str(err)
|
||||
)
|
||||
|
||||
# Final fallback to first active pricelist
|
||||
pricelist = (
|
||||
request.env["product.pricelist"]
|
||||
.sudo()
|
||||
.search([("active", "=", True)], limit=1)
|
||||
)
|
||||
if pricelist:
|
||||
_logger.info(
|
||||
"_resolve_pricelist: Using first active pricelist: %s (id=%s)",
|
||||
pricelist.name,
|
||||
pricelist.id,
|
||||
)
|
||||
return pricelist
|
||||
# 3) First active pricelist as fallback
|
||||
if not pricelist:
|
||||
pricelist = env["product.pricelist"].sudo().search([], limit=1)
|
||||
|
||||
_logger.error(
|
||||
"_resolve_pricelist: ERROR - No pricelist found! Pricing may fail."
|
||||
)
|
||||
return False
|
||||
return pricelist
|
||||
|
||||
def _prepare_product_display_info(self, product, product_price_info):
|
||||
"""Prepare all display information for a product in a QWeb-safe way.
|
||||
|
||||
This function pre-processes all values that might be None or require
|
||||
conditional logic, so the template can use simple variable references
|
||||
without complex expressions that confuse QWeb's parser.
|
||||
"""Build display info for a product using precomputed prices.
|
||||
|
||||
Args:
|
||||
product: product.template record
|
||||
product_price_info: dict with 'price', 'list_price', etc.
|
||||
product (product.product): Product variant.
|
||||
product_price_info: dict with price data keyed by product.id.
|
||||
|
||||
Returns:
|
||||
dict with all pre-processed display values ready for template
|
||||
dict with display_price, safe_uom_category, quantity_step
|
||||
"""
|
||||
# Safety: Get price, ensure it's a float
|
||||
price_data = product_price_info.get(product.id, {})
|
||||
price = (
|
||||
price_data.get("price", product.list_price)
|
||||
|
|
@ -414,19 +376,14 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
)
|
||||
price_safe = float(price) if price else 0.0
|
||||
|
||||
# Safety: Get UoM category name (use sudo for read-only display to avoid ACL issues)
|
||||
uom_category_name = ""
|
||||
quantity_step = 1 # Default step for integer quantities (Units)
|
||||
quantity_step = 1
|
||||
|
||||
if product.uom_id:
|
||||
uom = product.uom_id.sudo()
|
||||
if uom.category_id:
|
||||
uom_category_name = uom.category_id.sudo().name or ""
|
||||
|
||||
# Use XML IDs to detect fractional UoM categories (multilingual robust)
|
||||
# This works regardless of translation/language
|
||||
try:
|
||||
# Get external ID for the UoM category
|
||||
ir_model_data = request.env["ir.model.data"].sudo()
|
||||
external_id = ir_model_data.search(
|
||||
[
|
||||
|
|
@ -437,18 +394,16 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
)
|
||||
|
||||
if external_id:
|
||||
# Standard Odoo UoM categories requiring fractional step
|
||||
fractional_categories = [
|
||||
"uom.product_uom_categ_kgm", # Weight (kg, g, ton, etc.)
|
||||
"uom.product_uom_categ_vol", # Volume (L, m³, etc.)
|
||||
"uom.uom_categ_length", # Length/Distance (m, km, etc.)
|
||||
"uom.uom_categ_surface", # Surface (m², ha, etc.)
|
||||
"uom.product_uom_categ_kgm",
|
||||
"uom.product_uom_categ_vol",
|
||||
"uom.uom_categ_length",
|
||||
"uom.uom_categ_surface",
|
||||
]
|
||||
full_xmlid = f"{external_id.module}.{external_id.name}"
|
||||
if full_xmlid in fractional_categories:
|
||||
quantity_step = 0.1
|
||||
except Exception as e:
|
||||
# Fallback to integer step on error
|
||||
_logger.warning(
|
||||
"_prepare_product_display_info: Error detecting UoM category XML ID for product %s: %s",
|
||||
product.id,
|
||||
|
|
@ -461,6 +416,70 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
"quantity_step": quantity_step,
|
||||
}
|
||||
|
||||
def _get_pricing_info(self, product, pricelist, quantity=1.0, partner=None):
|
||||
"""Compute pricing with taxes like website_sale but using a given pricelist.
|
||||
|
||||
Returns a dict with:
|
||||
- price_unit: raw pricelist price (before taxes), suitable for sale.order.line
|
||||
- price: display price (tax included/excluded per website setting)
|
||||
- list_price: display list price (pre-discount) with same tax display
|
||||
- has_discounted_price: bool
|
||||
"""
|
||||
|
||||
try:
|
||||
env = request.env
|
||||
website = request.website
|
||||
except RuntimeError:
|
||||
env = product.env
|
||||
website = env["website"].get_current_website()
|
||||
|
||||
partner = partner or env.user.partner_id
|
||||
currency = pricelist.currency_id
|
||||
company = website.company_id or product.company_id or env.company
|
||||
|
||||
price, rule_id = pricelist._get_product_price_rule(
|
||||
product=product,
|
||||
quantity=quantity,
|
||||
target_currency=currency,
|
||||
)
|
||||
|
||||
price_before_discount = price
|
||||
pricelist_item = env["product.pricelist.item"].browse(rule_id)
|
||||
if pricelist_item and pricelist_item._show_discount_on_shop():
|
||||
price_before_discount = pricelist_item._compute_price_before_discount(
|
||||
product=product,
|
||||
quantity=quantity or 1.0,
|
||||
date=fields.Date.context_today(pricelist),
|
||||
uom=product.uom_id,
|
||||
currency=currency,
|
||||
)
|
||||
|
||||
has_discounted_price = price_before_discount > price
|
||||
|
||||
fiscal_position = website.fiscal_position_id.sudo()
|
||||
product_taxes = product.sudo().taxes_id._filter_taxes_by_company(company)
|
||||
taxes = (
|
||||
fiscal_position.map_tax(product_taxes) if product_taxes else product_taxes
|
||||
)
|
||||
tax_display = "total_included"
|
||||
|
||||
def compute_display(amount):
|
||||
if not taxes:
|
||||
return amount
|
||||
return taxes.compute_all(amount, currency, 1, product, partner)[tax_display]
|
||||
|
||||
display_price = compute_display(price)
|
||||
display_list_price = compute_display(price_before_discount)
|
||||
|
||||
return {
|
||||
"price_unit": price,
|
||||
"price": display_price,
|
||||
"list_price": display_list_price,
|
||||
"has_discounted_price": has_discounted_price,
|
||||
"discount": display_list_price - display_price,
|
||||
"tax_included": tax_display == "total_included",
|
||||
}
|
||||
|
||||
def _compute_price_info(self, products, pricelist):
|
||||
"""Compute price info dict for a list of products using the given pricelist.
|
||||
|
||||
|
|
@ -473,23 +492,13 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
)
|
||||
if product_variant and pricelist:
|
||||
try:
|
||||
price_info = product_variant._get_price(
|
||||
qty=1.0,
|
||||
pricelist=pricelist,
|
||||
fposition=request.website.fiscal_position_id,
|
||||
pricing = self._get_pricing_info(
|
||||
product_variant,
|
||||
pricelist,
|
||||
quantity=1.0,
|
||||
partner=request.env.user.partner_id,
|
||||
)
|
||||
price = price_info.get("value", 0.0)
|
||||
original_price = price_info.get("original_value", 0.0)
|
||||
discount = price_info.get("discount", 0.0)
|
||||
has_discount = discount > 0
|
||||
|
||||
product_price_info[product.id] = {
|
||||
"price": price,
|
||||
"list_price": original_price,
|
||||
"has_discounted_price": has_discount,
|
||||
"discount": discount,
|
||||
"tax_included": price_info.get("tax_included", True),
|
||||
}
|
||||
product_price_info[product.id] = pricing
|
||||
except Exception as e:
|
||||
_logger.warning(
|
||||
"_compute_price_info: Error getting price for product %s (id=%s): %s. Using list_price fallback.",
|
||||
|
|
@ -498,19 +507,23 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
str(e),
|
||||
)
|
||||
product_price_info[product.id] = {
|
||||
"price_unit": product.list_price,
|
||||
"price": product.list_price,
|
||||
"list_price": product.list_price,
|
||||
"has_discounted_price": False,
|
||||
"discount": 0.0,
|
||||
"tax_included": False,
|
||||
"tax_included": request.website.show_line_subtotals_tax_selection
|
||||
!= "tax_excluded",
|
||||
}
|
||||
else:
|
||||
product_price_info[product.id] = {
|
||||
"price_unit": product.list_price,
|
||||
"price": product.list_price,
|
||||
"list_price": product.list_price,
|
||||
"has_discounted_price": False,
|
||||
"discount": 0.0,
|
||||
"tax_included": False,
|
||||
"tax_included": request.website.show_line_subtotals_tax_selection
|
||||
!= "tax_excluded",
|
||||
}
|
||||
return product_price_info
|
||||
|
||||
|
|
@ -814,7 +827,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
|
||||
return order_id, group_order, current_user, items, is_delivery
|
||||
|
||||
def _process_cart_items(self, items, group_order):
|
||||
def _process_cart_items(self, items, group_order, pricelist=None):
|
||||
"""Process cart items and build sale.order line data.
|
||||
|
||||
Args:
|
||||
|
|
@ -828,12 +841,13 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
ValueError: if no valid items after processing
|
||||
"""
|
||||
sale_order_lines = []
|
||||
pricelist = pricelist or self._resolve_pricelist()
|
||||
partner = request.env.user.partner_id
|
||||
|
||||
for item in items:
|
||||
try:
|
||||
product_id = int(item.get("product_id"))
|
||||
quantity = float(item.get("quantity", 1))
|
||||
price = float(item.get("product_price", 0))
|
||||
|
||||
product = request.env["product.product"].sudo().browse(product_id)
|
||||
if not product.exists():
|
||||
|
|
@ -846,10 +860,17 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
product_in_lang = product.with_context(lang=request.env.lang)
|
||||
product_name = product_in_lang.name
|
||||
|
||||
pricing = self._get_pricing_info(
|
||||
product,
|
||||
pricelist,
|
||||
quantity=quantity,
|
||||
partner=partner,
|
||||
)
|
||||
|
||||
line_data = {
|
||||
"product_id": product_id,
|
||||
"product_uom_qty": quantity,
|
||||
"price_unit": price or product.list_price,
|
||||
"price_unit": pricing.get("price_unit", product.list_price),
|
||||
"name": product_name, # Force the translated product name
|
||||
}
|
||||
_logger.info("_process_cart_items: Adding line: %s", line_data)
|
||||
|
|
@ -1018,19 +1039,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
return sale_order
|
||||
|
||||
def _build_confirmation_message(self, sale_order, group_order, is_delivery):
|
||||
"""Build localized confirmation message for confirm_eskaera.
|
||||
|
||||
Translates message and pickup/delivery info according to user's language.
|
||||
Handles day names and date formatting.
|
||||
|
||||
Args:
|
||||
sale_order: sale.order record just created
|
||||
group_order: group.order record
|
||||
is_delivery: boolean indicating if home delivery
|
||||
|
||||
Returns:
|
||||
dict with message, pickup_day, pickup_date, pickup_day_index
|
||||
"""
|
||||
"""Build localized confirmation message for confirm_eskaera."""
|
||||
# Get pickup day index, localized name and date string using helper
|
||||
pickup_day_name, pickup_date_str, pickup_day_index = self._format_pickup_info(
|
||||
group_order, is_delivery
|
||||
|
|
@ -1220,86 +1229,29 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
group_order,
|
||||
current_user,
|
||||
sale_order_lines,
|
||||
merge_action,
|
||||
existing_draft_id,
|
||||
existing_drafts,
|
||||
order_id,
|
||||
):
|
||||
"""Handle merge/replace logic for drafts and return (sale_order, merge_success).
|
||||
"""Replace existing draft (if any) with new lines, else create it."""
|
||||
|
||||
existing_drafts: recordset of existing draft orders (may be empty)
|
||||
"""
|
||||
# Merge
|
||||
if merge_action == "merge" and existing_draft_id:
|
||||
existing_draft = (
|
||||
request.env["sale.order"].sudo().browse(int(existing_draft_id))
|
||||
)
|
||||
if existing_draft.exists():
|
||||
for new_line_data in sale_order_lines:
|
||||
product_id = new_line_data[2]["product_id"]
|
||||
new_quantity = new_line_data[2]["product_uom_qty"]
|
||||
new_price = new_line_data[2]["price_unit"]
|
||||
|
||||
# Capture product_id as default arg to avoid late-binding in lambda (fix B023)
|
||||
existing_line = existing_draft.order_line.filtered(
|
||||
lambda line, pid=product_id: line.product_id.id == pid
|
||||
)
|
||||
if existing_line:
|
||||
# Use sudo() to avoid permission issues with portal users
|
||||
existing_line.sudo().write(
|
||||
{
|
||||
"product_uom_qty": existing_line.product_uom_qty
|
||||
+ new_quantity
|
||||
}
|
||||
)
|
||||
_logger.info(
|
||||
"Merged item: product_id=%d, new total quantity=%.2f",
|
||||
product_id,
|
||||
existing_line.product_uom_qty,
|
||||
)
|
||||
else:
|
||||
# Use sudo() to avoid permission issues with portal users
|
||||
existing_draft.order_line.sudo().create(
|
||||
{
|
||||
"order_id": existing_draft.id,
|
||||
"product_id": product_id,
|
||||
"product_uom_qty": new_quantity,
|
||||
"price_unit": new_price,
|
||||
}
|
||||
)
|
||||
_logger.info(
|
||||
"Added new item to draft: product_id=%d, quantity=%.2f",
|
||||
product_id,
|
||||
new_quantity,
|
||||
)
|
||||
|
||||
return existing_draft, True
|
||||
|
||||
# Replace
|
||||
if merge_action == "replace" and existing_draft_id and existing_drafts:
|
||||
existing_drafts.unlink()
|
||||
if existing_drafts:
|
||||
draft = existing_drafts[0].sudo()
|
||||
_logger.info(
|
||||
"Deleted existing draft(s) for replace: %s",
|
||||
existing_drafts.mapped("id"),
|
||||
"Replacing existing draft order %s for partner %s",
|
||||
draft.id,
|
||||
current_user.partner_id.id,
|
||||
)
|
||||
order_vals = {
|
||||
"partner_id": current_user.partner_id.id,
|
||||
"order_line": sale_order_lines,
|
||||
"state": "draft",
|
||||
"group_order_id": order_id,
|
||||
"pickup_day": group_order.pickup_day,
|
||||
"pickup_date": group_order.pickup_date,
|
||||
"home_delivery": group_order.home_delivery,
|
||||
}
|
||||
# Get salesperson for order creation (portal users need this)
|
||||
salesperson = self._get_salesperson_for_order(current_user.partner_id)
|
||||
if salesperson:
|
||||
order_vals["user_id"] = salesperson.id
|
||||
draft.write(
|
||||
{
|
||||
"order_line": [(5, 0, 0)] + sale_order_lines,
|
||||
"group_order_id": order_id,
|
||||
"pickup_day": group_order.pickup_day,
|
||||
"pickup_date": group_order.pickup_date,
|
||||
"home_delivery": group_order.home_delivery,
|
||||
}
|
||||
)
|
||||
return draft
|
||||
|
||||
sale_order = request.env["sale.order"].sudo().create(order_vals)
|
||||
return sale_order, False
|
||||
|
||||
# Default: create new draft
|
||||
order_vals = {
|
||||
"partner_id": current_user.partner_id.id,
|
||||
"order_line": sale_order_lines,
|
||||
|
|
@ -1315,7 +1267,7 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
order_vals["user_id"] = salesperson.id
|
||||
|
||||
sale_order = request.env["sale.order"].sudo().create(order_vals)
|
||||
return sale_order, False
|
||||
return sale_order
|
||||
|
||||
def _decode_json_body(self):
|
||||
"""Safely decode JSON body from request. Returns dict or raises ValueError."""
|
||||
|
|
@ -2045,7 +1997,9 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
|
||||
# Build sale.order lines and create draft using helpers
|
||||
try:
|
||||
sale_order_lines = self._process_cart_items(items, group_order)
|
||||
sale_order_lines = self._process_cart_items(
|
||||
items, group_order, pricelist=self._resolve_pricelist()
|
||||
)
|
||||
except ValueError as e:
|
||||
return request.make_response(
|
||||
json.dumps({"error": str(e)}),
|
||||
|
|
@ -2171,13 +2125,21 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
|
||||
# Extract items from the draft order
|
||||
items = []
|
||||
pricelist = self._resolve_pricelist()
|
||||
partner = current_user.partner_id
|
||||
for line in draft_order.order_line:
|
||||
pricing = self._get_pricing_info(
|
||||
line.product_id,
|
||||
pricelist,
|
||||
quantity=line.product_uom_qty,
|
||||
partner=partner,
|
||||
)
|
||||
items.append(
|
||||
{
|
||||
"product_id": line.product_id.id,
|
||||
"product_name": line.product_id.name,
|
||||
"quantity": line.product_uom_qty,
|
||||
"product_price": line.price_unit,
|
||||
"product_price": pricing.get("price", line.price_unit),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -2306,8 +2268,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
|
||||
# Get cart items
|
||||
items = data.get("items", [])
|
||||
merge_action = data.get("merge_action") # 'merge' or 'replace'
|
||||
existing_draft_id = data.get("existing_draft_id") # ID if replacing
|
||||
|
||||
if not items:
|
||||
_logger.warning(
|
||||
|
|
@ -2334,35 +2294,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
)
|
||||
)
|
||||
|
||||
# If draft exists and no action specified, return the existing draft info
|
||||
if existing_drafts and not merge_action:
|
||||
existing_draft = existing_drafts[0] # Get first draft
|
||||
existing_items = [
|
||||
{
|
||||
"product_id": line.product_id.id,
|
||||
"product_name": line.product_id.name,
|
||||
"quantity": line.product_uom_qty,
|
||||
"product_price": line.price_unit,
|
||||
}
|
||||
for line in existing_draft.order_line
|
||||
]
|
||||
|
||||
return request.make_response(
|
||||
json.dumps(
|
||||
{
|
||||
"success": False,
|
||||
"existing_draft": True,
|
||||
"existing_draft_id": existing_draft.id,
|
||||
"existing_items": existing_items,
|
||||
"current_items": items,
|
||||
"message": request.env._(
|
||||
"A draft already exists for this week."
|
||||
),
|
||||
}
|
||||
),
|
||||
[("Content-Type", "application/json")],
|
||||
)
|
||||
|
||||
_logger.info(
|
||||
"Creating draft sale.order with %d items for partner %d",
|
||||
len(items),
|
||||
|
|
@ -2371,7 +2302,9 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
|
||||
# Create sales.order lines from items using shared helper
|
||||
try:
|
||||
sale_order_lines = self._process_cart_items(items, group_order)
|
||||
sale_order_lines = self._process_cart_items(
|
||||
items, group_order, pricelist=self._resolve_pricelist()
|
||||
)
|
||||
except ValueError as e:
|
||||
return request.make_response(
|
||||
json.dumps({"error": str(e)}),
|
||||
|
|
@ -2380,12 +2313,10 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
)
|
||||
|
||||
# Delegate merge/replace/create logic to helper
|
||||
sale_order, merge_success = self._merge_or_replace_draft(
|
||||
sale_order = self._merge_or_replace_draft(
|
||||
group_order,
|
||||
current_user,
|
||||
sale_order_lines,
|
||||
merge_action,
|
||||
existing_draft_id,
|
||||
existing_drafts,
|
||||
order_id,
|
||||
)
|
||||
|
|
@ -2404,13 +2335,8 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
json.dumps(
|
||||
{
|
||||
"success": True,
|
||||
"message": (
|
||||
request.env._("Merged with existing draft")
|
||||
if merge_success
|
||||
else request.env._("Order saved as draft")
|
||||
),
|
||||
"message": request.env._("Order saved as draft"),
|
||||
"sale_order_id": sale_order.id,
|
||||
"merged": merge_success,
|
||||
}
|
||||
),
|
||||
[("Content-Type", "application/json")],
|
||||
|
|
@ -2481,7 +2407,9 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
|
||||
# Process cart items using helper
|
||||
try:
|
||||
sale_order_lines = self._process_cart_items(items, group_order)
|
||||
sale_order_lines = self._process_cart_items(
|
||||
items, group_order, pricelist=self._resolve_pricelist()
|
||||
)
|
||||
except ValueError as e:
|
||||
_logger.warning("confirm_eskaera: Cart processing error: %s", str(e))
|
||||
return request.make_response(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue