[REM] website_sale_aplicoop: remove dead code and orphaned tests
Duplicate _translate_labels fallback, unreachable /eskaera/add-to-cart and /eskaera/save-cart routes (the frontend cart is localStorage-only and uses save-order), redundant pickup wrappers, unused pagination/count helpers and fields, deprecated JS shims, and the already-empty checkout_summary.js and i18n key/init leftovers. Also drops 11 tests/*.py never wired into tests/__init__.py: three were unimplemented placeholders (setUp with no assertions), and the other eight had real assertions but were bit-rotted against the current schema (e.g. res.partner.is_supplier no longer exists) — wiring them in surfaced 43 failures unrelated to this cleanup. Verified 0 failed/0 errors of 270 tests both before and after. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
6ba554c91b
commit
b3999e2283
24 changed files with 5 additions and 5598 deletions
|
|
@ -323,74 +323,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
)
|
||||
return sale_order
|
||||
|
||||
def _create_draft_sale_order(
|
||||
self,
|
||||
group_order,
|
||||
current_user,
|
||||
sale_order_lines,
|
||||
order_id,
|
||||
pickup_date=None,
|
||||
is_delivery=False,
|
||||
):
|
||||
"""Create a draft sale.order from prepared lines and propagate group fields.
|
||||
|
||||
Returns created sale.order record.
|
||||
"""
|
||||
consumer_group_id = self._validate_user_group_access(group_order, current_user)
|
||||
|
||||
_logger.info(
|
||||
"[CONSUMER_GROUP DEBUG] _create_draft_sale_order: "
|
||||
"group_order=%s, group_order.group_ids=%s, consumer_group_id=%s",
|
||||
group_order.id,
|
||||
group_order.group_ids.ids,
|
||||
consumer_group_id,
|
||||
)
|
||||
|
||||
effective_home_delivery, commitment_date = self._get_effective_delivery_context(
|
||||
group_order, is_delivery
|
||||
)
|
||||
|
||||
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": effective_home_delivery,
|
||||
"consumer_group_id": consumer_group_id,
|
||||
"commitment_date": commitment_date,
|
||||
}
|
||||
|
||||
# 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
|
||||
_logger.info(
|
||||
"Creating draft sale.order with salesperson %s (%d)",
|
||||
salesperson.name,
|
||||
salesperson.id,
|
||||
)
|
||||
|
||||
# Create order with sudo to avoid permission issues with portal users
|
||||
sale_order = request.env["sale.order"].sudo().create(order_vals)
|
||||
|
||||
# Ensure the order has a name (sequence)
|
||||
try:
|
||||
if not sale_order.name or sale_order.name == "New":
|
||||
sale_order._onchange_partner_id()
|
||||
if not sale_order.name or sale_order.name == "New":
|
||||
sale_order.name = "DRAFT-%s" % sale_order.id
|
||||
except Exception as exc:
|
||||
# Do not break creation on name generation issues
|
||||
_logger.warning(
|
||||
"Failed to generate name for draft sale order %s: %s",
|
||||
sale_order.id,
|
||||
exc,
|
||||
)
|
||||
|
||||
return sale_order
|
||||
|
||||
def _build_confirmation_message(self, sale_order, group_order, is_delivery):
|
||||
"""Build localized confirmation message for confirm_eskaera."""
|
||||
# Get pickup day index, localized name and date string using helper
|
||||
|
|
@ -447,28 +379,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
request_obj=request,
|
||||
)
|
||||
|
||||
def _slot_time_label(self, slot):
|
||||
return _pickup._slot_time_label(self, slot)
|
||||
|
||||
def _format_datetime_to_str(self, dt_val):
|
||||
return _pickup._format_datetime_to_str(self, dt_val)
|
||||
|
||||
def _format_slot_pickup_info(self, group_order, slot):
|
||||
return _pickup._format_slot_pickup_info(
|
||||
self,
|
||||
group_order,
|
||||
slot,
|
||||
request_obj=request,
|
||||
)
|
||||
|
||||
def _format_legacy_pickup_info(self, group_order, is_delivery):
|
||||
return _pickup._format_legacy_pickup_info(
|
||||
self,
|
||||
group_order,
|
||||
is_delivery,
|
||||
request_obj=request,
|
||||
)
|
||||
|
||||
def _parse_save_cart_request(self):
|
||||
"""Decode and validate the incoming save-cart request.
|
||||
|
||||
|
|
@ -1250,156 +1160,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
[("Content-Type", "application/json")],
|
||||
)
|
||||
|
||||
@http.route(
|
||||
["/eskaera/add-to-cart"],
|
||||
type="http",
|
||||
auth="user",
|
||||
website=True,
|
||||
methods=["POST"],
|
||||
csrf=False,
|
||||
)
|
||||
def add_to_eskaera_cart(self, **post):
|
||||
"""Validate and confirm product addition to cart.
|
||||
|
||||
The cart is managed in localStorage on the frontend.
|
||||
This endpoint only validates that the product exists in the order.
|
||||
"""
|
||||
import json
|
||||
|
||||
try:
|
||||
# Get JSON data from the request body
|
||||
data = (
|
||||
json.loads(request.httprequest.data) if request.httprequest.data else {}
|
||||
)
|
||||
|
||||
order_id = int(data.get("order_id", 0))
|
||||
product_id = int(data.get("product_id", 0))
|
||||
quantity = float(data.get("quantity", 1))
|
||||
|
||||
group_order = request.env["group.order"].sudo().browse(order_id)
|
||||
product = request.env["product.product"].sudo().browse(product_id)
|
||||
|
||||
# Validate that the order exists and is open
|
||||
if not group_order.exists() or group_order.state != "open":
|
||||
_logger.warning(
|
||||
"add_to_eskaera_cart: Order %d not available (exists=%s, state=%s)",
|
||||
order_id,
|
||||
group_order.exists(),
|
||||
group_order.state if group_order.exists() else "N/A",
|
||||
)
|
||||
return request.make_response(
|
||||
json.dumps({"error": "Order is not available"}),
|
||||
[("Content-Type", "application/json")],
|
||||
)
|
||||
|
||||
if placed_response := self._build_already_placed_response(
|
||||
request.env.user.partner_id.id, group_order
|
||||
):
|
||||
return placed_response
|
||||
|
||||
# Validate that the product is available in this order (use discovery logic)
|
||||
available_products = group_order._get_products_for_group_order(
|
||||
group_order.id
|
||||
)
|
||||
if product not in available_products:
|
||||
_logger.warning(
|
||||
"add_to_eskaera_cart: Product %d not available in order %d",
|
||||
product_id,
|
||||
order_id,
|
||||
)
|
||||
return request.make_response(
|
||||
json.dumps({"error": "Product not available in this order"}),
|
||||
[("Content-Type", "application/json")],
|
||||
)
|
||||
|
||||
# Validate quantity
|
||||
if quantity <= 0:
|
||||
return request.make_response(
|
||||
json.dumps({"error": "Quantity must be greater than 0"}),
|
||||
[("Content-Type", "application/json")],
|
||||
)
|
||||
|
||||
_logger.info(
|
||||
"add_to_eskaera_cart: Added product %d (qty=%f) to order %d",
|
||||
product_id,
|
||||
quantity,
|
||||
order_id,
|
||||
)
|
||||
|
||||
# Get price with taxes using pricelist
|
||||
_logger.info(
|
||||
"add_to_eskaera_cart: Getting price for product %s (id=%s)",
|
||||
product.name,
|
||||
product_id,
|
||||
)
|
||||
pricelist = None
|
||||
|
||||
# Resolve pricelist using centralized helper
|
||||
pricelist = self._resolve_pricelist()
|
||||
|
||||
if not pricelist:
|
||||
_logger.error(
|
||||
"add_to_eskaera_cart: ERROR - No pricelist found! Using list_price for product %s",
|
||||
product.name,
|
||||
)
|
||||
|
||||
product_variant = (
|
||||
product.product_variant_ids[0] if product.product_variant_ids else False
|
||||
)
|
||||
|
||||
if product_variant and pricelist:
|
||||
try:
|
||||
# Use OCA _get_price method - more robust and complete
|
||||
price_info = product_variant._get_price(
|
||||
qty=quantity,
|
||||
pricelist=pricelist,
|
||||
fposition=request.website.fiscal_position_id,
|
||||
)
|
||||
price_with_tax = price_info.get("value", product.list_price)
|
||||
_logger.info(
|
||||
"add_to_eskaera_cart: Product %s - Price: %.2f (original: %.2f, discount: %.1f%%)",
|
||||
product.name,
|
||||
price_with_tax,
|
||||
price_info.get("original_value", 0),
|
||||
price_info.get("discount", 0),
|
||||
)
|
||||
except Exception as e:
|
||||
_logger.warning(
|
||||
"add_to_eskaera_cart: Error getting price for product %s: %s. Using list_price=%.2f",
|
||||
product.name,
|
||||
str(e),
|
||||
product.list_price,
|
||||
)
|
||||
else:
|
||||
reason = "no pricelist" if not pricelist else "no variant"
|
||||
_logger.info(
|
||||
"add_to_eskaera_cart: Product %s - Using list_price fallback (reason: %s). Price=%.2f",
|
||||
product.name,
|
||||
reason,
|
||||
price_with_tax,
|
||||
)
|
||||
|
||||
response_data = {
|
||||
"success": True,
|
||||
"message": request.env._("%s added to cart", product.name),
|
||||
"product_id": product_id,
|
||||
"quantity": quantity,
|
||||
"price": price_with_tax,
|
||||
}
|
||||
return request.make_response(
|
||||
json.dumps(response_data), [("Content-Type", "application/json")]
|
||||
)
|
||||
|
||||
except ValueError as e:
|
||||
_logger.error("add_to_eskaera_cart: ValueError: %s", str(e))
|
||||
return request.make_response(
|
||||
json.dumps({"error": f"Invalid parameters: {str(e)}"}),
|
||||
[("Content-Type", "application/json")],
|
||||
)
|
||||
except Exception as e:
|
||||
_logger.error("add_to_eskaera_cart: Exception: %s", str(e), exc_info=True)
|
||||
return request.make_response(json.dumps({"error": f"Error: {str(e)}"}))
|
||||
|
||||
@http.route(
|
||||
["/eskaera/<int:order_id>/checkout"], type="http", auth="user", website=True
|
||||
)
|
||||
|
|
@ -1797,130 +1557,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
[("Content-Type", "application/json")],
|
||||
)
|
||||
|
||||
@http.route(
|
||||
["/eskaera/save-cart"],
|
||||
type="http",
|
||||
auth="user",
|
||||
website=True,
|
||||
methods=["POST"],
|
||||
csrf=False,
|
||||
)
|
||||
def save_cart_draft(self, **post):
|
||||
"""Save cart items as a draft sale.order with pickup date.
|
||||
|
||||
This controller delegates validation and heavy lifting to helpers
|
||||
so the top-level flow remains easy to follow and McCabe-friendly.
|
||||
"""
|
||||
try:
|
||||
_logger.warning("=== SAVE_CART_DRAFT CALLED ===")
|
||||
|
||||
try:
|
||||
(
|
||||
data,
|
||||
order_id,
|
||||
group_order,
|
||||
current_user,
|
||||
items,
|
||||
pickup_date,
|
||||
is_delivery,
|
||||
) = self._parse_save_cart_request()
|
||||
except BadRequestError as e:
|
||||
return request.make_response(
|
||||
json.dumps({"error": str(e)}),
|
||||
[("Content-Type", "application/json")],
|
||||
status=400,
|
||||
)
|
||||
except ForbiddenError as e:
|
||||
return request.make_response(
|
||||
json.dumps({"error": str(e)}),
|
||||
[("Content-Type", "application/json")],
|
||||
status=403,
|
||||
)
|
||||
except GroupOrderUnavailable:
|
||||
order_id = None
|
||||
try:
|
||||
payload = self._decode_json_body()
|
||||
order_id = (
|
||||
int(payload.get("order_id"))
|
||||
if payload.get("order_id")
|
||||
else None
|
||||
)
|
||||
except Exception:
|
||||
order_id = None
|
||||
group_order = (
|
||||
request.env["group.order"].sudo().browse(order_id)
|
||||
if order_id
|
||||
else False
|
||||
)
|
||||
return self._build_group_order_unavailable_response(group_order)
|
||||
|
||||
# Build sale.order lines and create draft using helpers
|
||||
try:
|
||||
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)}),
|
||||
[("Content-Type", "application/json")],
|
||||
status=400,
|
||||
)
|
||||
|
||||
sale_order = self._create_draft_sale_order(
|
||||
group_order,
|
||||
current_user,
|
||||
sale_order_lines,
|
||||
order_id,
|
||||
pickup_date,
|
||||
is_delivery=is_delivery,
|
||||
)
|
||||
|
||||
_logger.info(
|
||||
"Draft sale.order created: %d (name: %s) for partner %d",
|
||||
sale_order.id,
|
||||
sale_order.name,
|
||||
current_user.partner_id.id,
|
||||
)
|
||||
|
||||
# Compute a readable pickup slot label for the response. Prefer the
|
||||
# order's stored computed label, otherwise derive from the group
|
||||
# order using the same helper the confirmation flow uses.
|
||||
pickup_slot_label = (
|
||||
sale_order.pickup_slot_label
|
||||
if getattr(sale_order, "pickup_slot_label", False)
|
||||
else None
|
||||
)
|
||||
if not pickup_slot_label:
|
||||
try:
|
||||
pickup_slot_label = self._format_pickup_info(
|
||||
group_order, is_delivery
|
||||
)[0]
|
||||
except Exception:
|
||||
pickup_slot_label = None
|
||||
|
||||
return request.make_response(
|
||||
json.dumps(
|
||||
{
|
||||
"success": True,
|
||||
"message": request.env._("Cart saved as draft"),
|
||||
"sale_order_id": sale_order.id,
|
||||
"pickup_slot_label": pickup_slot_label,
|
||||
}
|
||||
),
|
||||
[("Content-Type", "application/json")],
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
|
||||
_logger.error("save_cart_draft: Unexpected error: %s", str(e))
|
||||
_logger.error(traceback.format_exc())
|
||||
return request.make_response(
|
||||
json.dumps({"error": str(e)}),
|
||||
[("Content-Type", "application/json")],
|
||||
status=500,
|
||||
)
|
||||
|
||||
@http.route(
|
||||
["/eskaera/load-draft"],
|
||||
type="http",
|
||||
|
|
@ -2723,107 +2359,6 @@ class AplicoopWebsiteSale(WebsiteSale):
|
|||
_logger.error(traceback.format_exc())
|
||||
return {"success": False, "error": f"Error confirming order: {str(e)}"}
|
||||
|
||||
def _translate_labels(self, labels_dict, lang):
|
||||
"""Manually translate labels based on user language.
|
||||
|
||||
This is a fallback translation method for when Odoo's translation system
|
||||
hasn't loaded translations from .po files properly.
|
||||
"""
|
||||
translations = {
|
||||
"es_ES": {
|
||||
"Draft Already Exists": "El Borrador Ya Existe",
|
||||
"A saved draft already exists for the current order period.": "Un borrador guardado ya existe para el período actual del pedido.",
|
||||
"You have two options:": "Tienes dos opciones:",
|
||||
"Option 1: Merge with Existing Draft": "Opción 1: Fusionar con Borrador Existente",
|
||||
"Combine your current cart with the existing draft.": "Combina tu carrito actual con el borrador existente.",
|
||||
"Existing draft has": "El borrador existente tiene",
|
||||
"Current cart has": "Tu carrito actual tiene",
|
||||
"item(s)": "artículo(s)",
|
||||
"Products will be merged by adding quantities. If a product exists in both, quantities will be combined.": "Los productos se fusionarán sumando cantidades. Si un producto existe en ambos, las cantidades se combinarán.",
|
||||
"Option 2: Replace with Current Cart": "Opción 2: Reemplazar con Carrito Actual",
|
||||
"Delete the old draft and save only the current cart items.": "Elimina el borrador anterior y guarda solo los artículos del carrito actual.",
|
||||
"The existing draft will be permanently deleted.": "El borrador existente se eliminará permanentemente.",
|
||||
"Merge": "Fusionar",
|
||||
"Replace": "Reemplazar",
|
||||
"Cancel": "Cancelar",
|
||||
# Checkout page labels
|
||||
"Home Delivery": "Entrega a Domicilio",
|
||||
"Delivery Information": "Información de Entrega",
|
||||
"Your order will be delivered the day after pickup between 11:00 - 14:00": "Tu pedido será entregado el día después de la recogida entre las 11:00 - 14:00",
|
||||
"Important": "Importante",
|
||||
"Once you confirm this order, you will not be able to modify it. Please review carefully before confirming.": "Una vez confirmes este pedido, no podrás modificarlo. Por favor, revisa cuidadosamente antes de confirmar.",
|
||||
},
|
||||
"eu_ES": {
|
||||
"Draft Already Exists": "Zirriborro Dagoeneko Badago",
|
||||
"A saved draft already exists for the current order period.": "Gordetako zirriborro bat dagoeneko badago uneko eskaera-aldirako.",
|
||||
"You have two options:": "Bi aukera dituzu:",
|
||||
"Option 1: Merge with Existing Draft": "1. Aukera: Existentea Duen Zirriborroarekin Batu",
|
||||
"Combine your current cart with the existing draft.": "Batu zure gaur-oraingo saskia existentea duen zirriborroarekin.",
|
||||
"Existing draft has": "Existentea duen zirriborroak du",
|
||||
"Current cart has": "Zure gaur-oraingo saskiak du",
|
||||
"item(s)": "artikulu(a)",
|
||||
"Products will be merged by adding quantities. If a product exists in both, quantities will be combined.": "Produktuak batuko dira kantitateak gehituz. Produktu bat bian badago, kantitateak konbinatuko dira.",
|
||||
"Option 2: Replace with Current Cart": "2. Aukera: Gaur-oraingo Askiarekin Ordeztu",
|
||||
"Delete the old draft and save only the current cart items.": "Ezabatu zahar-zirriborroa eta gorde soilik gaur-oraingo saskiaren artikulua.",
|
||||
"The existing draft will be permanently deleted.": "Existentea duen zirriborroa behin betiko ezabatuko da.",
|
||||
"Merge": "Batu",
|
||||
"Replace": "Ordeztu",
|
||||
"Cancel": "Ezeztatu",
|
||||
# Checkout page labels
|
||||
"Home Delivery": "Etxera Bidalketa",
|
||||
"Delivery Information": "Bidalketaren Informazioa",
|
||||
"Your order will be delivered the day after pickup between 11:00 - 14:00": "Zure eskaera bidaliko da biltzeko eguaren ondoren 11:00 - 14:00 bitartean",
|
||||
"Important": "Garrantzitsua",
|
||||
"Once you confirm this order, you will not be able to modify it. Please review carefully before confirming.": "Behin eskaera hau berretsi ondoren, ezin izango duzu aldatu. Mesedez, arretaz berrikusi berretsi aurretik.",
|
||||
},
|
||||
# Also support 'eu' as a variant
|
||||
"eu": {
|
||||
"Draft Already Exists": "Zirriborro Dagoeneko Badago",
|
||||
"A saved draft already exists for the current order period.": "Gordetako zirriborro bat dagoeneko badago uneko eskaera-aldirako.",
|
||||
"You have two options:": "Bi aukera dituzu:",
|
||||
"Option 1: Merge with Existing Draft": "1. Aukera: Existentea Duen Zirriborroarekin Batu",
|
||||
"Combine your current cart with the existing draft.": "Batu zure gaur-oraingo saskia existentea duen zirriborroarekin.",
|
||||
"Existing draft has": "Existentea duen zirriborroak du",
|
||||
"Current cart has": "Zure gaur-oraingo saskiak du",
|
||||
"item(s)": "artikulu(a)",
|
||||
"Products will be merged by adding quantities. If a product exists in both, quantities will be combined.": "Produktuak batuko dira kantitateak gehituz. Produktu bat bian badago, kantitateak konbinatuko dira.",
|
||||
"Option 2: Replace with Current Cart": "2. Aukera: Gaur-oraingo Askiarekin Ordeztu",
|
||||
"Delete the old draft and save only the current cart items.": "Ezabatu zahar-zirriborroa eta gorde soilik gaur-oraingo saskiaren artikulua.",
|
||||
"The existing draft will be permanently deleted.": "Existentea duen zirriborroa behin betiko ezabatuko da.",
|
||||
"Merge": "Batu",
|
||||
"Replace": "Ordeztu",
|
||||
"Cancel": "Ezeztatu",
|
||||
# Checkout page labels
|
||||
"Home Delivery": "Etxera Bidalketa",
|
||||
"Delivery Information": "Bidalketaren Informazioa",
|
||||
"Your order will be delivered the day after pickup between 11:00 - 14:00": "Zure eskaera bidaliko da biltzeko eguaren ondoren 11:00 - 14:00 bitartean",
|
||||
"Important": "Garrantzitsua",
|
||||
"Once you confirm this order, you will not be able to modify it. Please review carefully before confirming.": "Behin eskaera hau berretsi ondoren, ezin izango duzu aldatu. Mesedez, arretaz berrikusi berretsi aurretik.",
|
||||
},
|
||||
}
|
||||
|
||||
# Get the translation dictionary for the user's language
|
||||
# Try exact match first, then try without the region code (e.g., 'eu' from 'eu_ES')
|
||||
lang_translations = translations.get(lang)
|
||||
if not lang_translations and "_" in lang:
|
||||
lang_code = lang.split("_")[0] # Get 'eu' from 'eu_ES'
|
||||
lang_translations = translations.get(lang_code, {})
|
||||
if not lang_translations:
|
||||
lang_translations = {}
|
||||
|
||||
# Translate all English labels to the target language
|
||||
translated = {}
|
||||
for key, english_label in labels_dict.items():
|
||||
translated[key] = lang_translations.get(english_label, english_label)
|
||||
|
||||
_logger.info(
|
||||
"[_translate_labels] Language: %s, Translated %d labels",
|
||||
lang,
|
||||
len(translated),
|
||||
)
|
||||
|
||||
return translated
|
||||
|
||||
@http.route(
|
||||
["/eskaera/labels", "/eskaera/i18n"],
|
||||
type="json",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue