[FIX] TestConfirmEskaera_Integration: limpieza de decoradores @patch y corrección de bugs

- Convertir 4 tests de decorador @patch a context manager 'with patch(...)' para evitar RuntimeError en LocalProxy de Werkzeug
- Corregir patrón env(user=..., context=dict(...)) en Odoo 18 (sin .with_context())
- Agregar website real al mock para integración con helpers de pricing (_get_pricing_info)
- Añadir pickup_date en fixture de existing_order para que _find_recent_draft_order localice correctamente
- BUGFIX: Agregar (5,) a order_line para limpiar líneas previas al actualizar pedido existente

Resultado: 0 failed, 0 errors de 4 tests en Docker para TestConfirmEskaera_Integration

BREAKING: _create_or_update_sale_order ahora limpia las líneas anteriores con (5,) antes de asignar las nuevas cuando se actualiza un pedido existente. Comportamiento previo (duplicación de líneas) era un bug.
This commit is contained in:
snt 2026-04-08 17:26:57 +02:00
parent e9809b90e9
commit ce393b6034
13 changed files with 857 additions and 192 deletions

View file

@ -768,6 +768,8 @@ class AplicoopWebsiteSale(WebsiteSale):
if not current_user.partner_id:
raise ValueError("User has no associated partner") from None
self._validate_user_group_access(group_order, current_user)
# Validate items
items = data.get("items", [])
if not items:
@ -820,6 +822,8 @@ class AplicoopWebsiteSale(WebsiteSale):
if not current_user.partner_id:
raise ValueError("User has no associated partner")
self._validate_user_group_access(group_order, current_user)
# Validate items
items = data.get("items", [])
if not items:
@ -887,6 +891,8 @@ class AplicoopWebsiteSale(WebsiteSale):
if not current_user.partner_id:
raise ValueError("User has no associated partner")
self._validate_user_group_access(group_order, current_user)
# Validate items
items = data.get("items", [])
if not items:
@ -921,6 +927,29 @@ class AplicoopWebsiteSale(WebsiteSale):
return False
return bool(value)
def _get_effective_delivery_context(self, group_order, is_delivery):
"""Return effective home delivery flag and commitment date.
Delivery is effective only when requested by the user and enabled
in the group order configuration.
"""
delivery_requested = self._to_bool(is_delivery)
delivery_enabled = bool(group_order and group_order.home_delivery)
effective_home_delivery = delivery_requested and delivery_enabled
if delivery_requested and not delivery_enabled:
_logger.info(
"Delivery requested but disabled in group order %s; using pickup flow",
group_order.id if group_order else "N/A",
)
if effective_home_delivery:
commitment_date = group_order.delivery_date or group_order.pickup_date
else:
commitment_date = group_order.pickup_date if group_order else False
return effective_home_delivery, commitment_date
def _process_cart_items(self, items, group_order, pricelist=None):
"""Process cart items and build sale.order line data.
@ -1009,6 +1038,35 @@ class AplicoopWebsiteSale(WebsiteSale):
# No salesperson found
return False
def _get_consumer_group_for_user(self, group_order, current_user):
"""Return the matching consumer group for the user in this group order."""
partner = current_user.partner_id
if not partner or not group_order:
return False
user_group_ids = set(partner.group_ids.ids)
for consumer_group in group_order.group_ids:
if consumer_group.id in user_group_ids:
return consumer_group.id
_logger.warning(
"_get_consumer_group_for_user: User %s (%s) is not member of any "
"consumer group in order %s. user_groups=%s, order_groups=%s",
current_user.name,
current_user.id,
group_order.id,
sorted(user_group_ids),
group_order.group_ids.ids,
)
return False
def _validate_user_group_access(self, group_order, current_user):
"""Ensure the user belongs to at least one consumer group of the order."""
consumer_group_id = self._get_consumer_group_for_user(group_order, current_user)
if not consumer_group_id:
raise ValueError("User is not a member of any consumer group in this order")
return consumer_group_id
def _create_or_update_sale_order(
self,
group_order,
@ -1022,11 +1080,7 @@ class AplicoopWebsiteSale(WebsiteSale):
Returns the sale.order record.
"""
# consumer_group_id comes directly from group_order (first/only group)
# No calculations - data propagates directly from the order context
consumer_group_id = (
group_order.group_ids[0].id if group_order.group_ids else False
)
consumer_group_id = self._validate_user_group_access(group_order, current_user)
_logger.info(
"[CONSUMER_GROUP DEBUG] _create_or_update_sale_order: "
@ -1036,22 +1090,25 @@ class AplicoopWebsiteSale(WebsiteSale):
consumer_group_id,
)
# commitment_date: use provided or calculate from group_order
effective_home_delivery, calculated_commitment_date = (
self._get_effective_delivery_context(group_order, is_delivery)
)
# Explicit commitment_date wins; otherwise use calculated value
if not commitment_date:
commitment_date = (
group_order.delivery_date if is_delivery else group_order.pickup_date
)
commitment_date = calculated_commitment_date
if existing_order:
# Update existing order with new lines and propagate fields
# Use sudo() to avoid permission issues with portal users
existing_order_sudo = existing_order.sudo()
existing_order_sudo.order_line = sale_order_lines
# (5,) clears all existing lines before adding the new ones
existing_order_sudo.order_line = [(5,)] + sale_order_lines
if not existing_order_sudo.group_order_id:
existing_order_sudo.group_order_id = group_order.id
existing_order_sudo.pickup_day = group_order.pickup_day
existing_order_sudo.pickup_date = group_order.pickup_date
existing_order_sudo.home_delivery = is_delivery
existing_order_sudo.home_delivery = effective_home_delivery
existing_order_sudo.consumer_group_id = consumer_group_id
if commitment_date:
existing_order_sudo.commitment_date = commitment_date
@ -1059,7 +1116,7 @@ class AplicoopWebsiteSale(WebsiteSale):
"Updated existing sale.order %d: commitment_date=%s, home_delivery=%s, consumer_group_id=%s",
existing_order.id,
commitment_date,
is_delivery,
effective_home_delivery,
consumer_group_id,
)
return existing_order
@ -1071,7 +1128,7 @@ class AplicoopWebsiteSale(WebsiteSale):
"group_order_id": group_order.id,
"pickup_day": group_order.pickup_day,
"pickup_date": group_order.pickup_date,
"home_delivery": is_delivery,
"home_delivery": effective_home_delivery,
"consumer_group_id": consumer_group_id,
}
if commitment_date:
@ -1094,23 +1151,25 @@ class AplicoopWebsiteSale(WebsiteSale):
sale_order.id,
group_order.id,
group_order.pickup_day,
group_order.home_delivery,
effective_home_delivery,
consumer_group_id,
)
return sale_order
def _create_draft_sale_order(
self, group_order, current_user, sale_order_lines, order_id, pickup_date=None
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 comes directly from group_order (first/only group)
# No calculations - data propagates directly from the order context
consumer_group_id = (
group_order.group_ids[0].id if group_order.group_ids else False
)
consumer_group_id = self._validate_user_group_access(group_order, current_user)
_logger.info(
"[CONSUMER_GROUP DEBUG] _create_draft_sale_order: "
@ -1120,11 +1179,8 @@ class AplicoopWebsiteSale(WebsiteSale):
consumer_group_id,
)
# commitment_date comes from group_order (delivery_date or pickup_date)
commitment_date = (
group_order.delivery_date
if group_order.home_delivery
else group_order.pickup_date
effective_home_delivery, commitment_date = self._get_effective_delivery_context(
group_order, is_delivery
)
order_vals = {
@ -1134,7 +1190,7 @@ class AplicoopWebsiteSale(WebsiteSale):
"group_order_id": order_id,
"pickup_day": group_order.pickup_day,
"pickup_date": group_order.pickup_date,
"home_delivery": group_order.home_delivery,
"home_delivery": effective_home_delivery,
"consumer_group_id": consumer_group_id,
"commitment_date": commitment_date,
}
@ -1374,11 +1430,7 @@ class AplicoopWebsiteSale(WebsiteSale):
All fields (commitment_date, consumer_group_id, etc.) come from group_order.
"""
# consumer_group_id comes directly from group_order (first/only group)
# No calculations - data propagates directly from the order context
consumer_group_id = (
group_order.group_ids[0].id if group_order.group_ids else False
)
consumer_group_id = self._validate_user_group_access(group_order, current_user)
_logger.info(
"[CONSUMER_GROUP DEBUG] _merge_or_replace_draft: "
@ -1388,9 +1440,8 @@ class AplicoopWebsiteSale(WebsiteSale):
consumer_group_id,
)
# commitment_date comes directly from selected flow
commitment_date = (
group_order.delivery_date if is_delivery else group_order.pickup_date
effective_home_delivery, commitment_date = self._get_effective_delivery_context(
group_order, is_delivery
)
if existing_drafts:
@ -1406,7 +1457,7 @@ class AplicoopWebsiteSale(WebsiteSale):
"group_order_id": order_id,
"pickup_day": group_order.pickup_day,
"pickup_date": group_order.pickup_date,
"home_delivery": is_delivery,
"home_delivery": effective_home_delivery,
"consumer_group_id": consumer_group_id,
"commitment_date": commitment_date,
}
@ -1420,7 +1471,7 @@ class AplicoopWebsiteSale(WebsiteSale):
"group_order_id": order_id,
"pickup_day": group_order.pickup_day,
"pickup_date": group_order.pickup_date,
"home_delivery": is_delivery,
"home_delivery": effective_home_delivery,
"consumer_group_id": consumer_group_id,
"commitment_date": commitment_date,
}
@ -2240,8 +2291,18 @@ class AplicoopWebsiteSale(WebsiteSale):
status=400,
)
try:
self._validate_user_group_access(group_order, current_user)
except ValueError as e:
return request.make_response(
json.dumps({"error": str(e)}),
[("Content-Type", "application/json")],
status=403,
)
items = data.get("items", [])
pickup_date = data.get("pickup_date")
is_delivery = self._to_bool(data.get("is_delivery", False))
if not items:
return request.make_response(
json.dumps({"error": "No items in cart"}),
@ -2262,7 +2323,12 @@ class AplicoopWebsiteSale(WebsiteSale):
)
sale_order = self._create_draft_sale_order(
group_order, current_user, sale_order_lines, order_id, pickup_date
group_order,
current_user,
sale_order_lines,
order_id,
pickup_date,
is_delivery=is_delivery,
)
_logger.info(
@ -2629,6 +2695,15 @@ class AplicoopWebsiteSale(WebsiteSale):
status=400,
)
try:
self._validate_user_group_access(group_order, current_user)
except ValueError as e:
return request.make_response(
json.dumps({"error": str(e)}),
[("Content-Type", "application/json")],
status=403,
)
# Get cart items
items = data.get("items", [])
is_delivery = self._to_bool(data.get("is_delivery", False))
@ -2791,27 +2866,23 @@ class AplicoopWebsiteSale(WebsiteSale):
)
existing_order = None
# Get pickup date and delivery info from group order
# If delivery, use delivery_date; otherwise use pickup_date
commitment_date = None
if is_delivery and group_order.delivery_date:
commitment_date = group_order.delivery_date
elif group_order.pickup_date:
commitment_date = group_order.pickup_date
effective_home_delivery, commitment_date = (
self._get_effective_delivery_context(group_order, is_delivery)
)
# Create or update sale.order using helper
sale_order = self._create_or_update_sale_order(
group_order,
current_user,
sale_order_lines,
is_delivery,
effective_home_delivery,
commitment_date=commitment_date,
existing_order=existing_order,
)
# Build confirmation message using helper
message_data = self._build_confirmation_message(
sale_order, group_order, is_delivery
sale_order, group_order, effective_home_delivery
)
message = message_data["message"]
pickup_day_name = message_data["pickup_day"]